git可以忽略特定的行吗?

时间:2011-07-02 14:00:34

标签: git gitx

我在手机的原生浏览器上测试时使用git同步到phonegap。因此我有以下几行:

var isPhoneGap = false;

显然我在构建时更改了这个,但是有什么办法可以设置git来忽略这一行,或者我必须把它放在自己的文件中并忽略它吗?

我在OSX 10.6上使用Gitx和终端。

9 个答案:

答案 0 :(得分:81)

如果您的文件属于特定类型,则可以声明content filter driver,您可以在.gitattributes文件中声明(如“Git Attributes”的“关键字扩展”中所示“):

http://git-scm.com/figures/18333fig0702-tn.png

*.yourType filter=yourFilterName

(如果你愿意,你甚至可以set that filter for a specific file

实施:

  • yourFilterName.smudge(在git checkout上触发)和

    git config --global filter.yourFilterName.smudge 'sed "s/isPhoneGap = .*/isPhoneGap = true/"'
    
  • yourFilterName.clean(在git add上触发)

    git config --global filter.yourFilterName.clean 'sed "s/isPhoneGap = .*/isPhoneGap = false/"'
    

您的文件在git status上显示不变,但其签出版本的isPhoneGap值正确。

答案 1 :(得分:35)

您可以使用

git update-index --assume-unchanged [file]

忽略您不想跟踪的一个文件的更改。当我需要在存储库中有一个文件时,我使用这个解决方案,但是这个文件有一些部分会改变,我总是不需要跟踪。

当文件包含重要的更改时,您必须执行此操作:

git update-index --no-assume-unchanged [file]

另请参阅--[no-]assume-unchanged {{1}}参数。

  

指定这些标志时,不会更新为路径记录的对象名称。相反,这些选项设置和取消设置"假设不变"路径的位。当"假设不变" bit打开,git停止检查工作树文件是否可能进行修改,因此您需要手动取消设置该位以在更改工作树文件时告诉git。

答案 2 :(得分:6)

Gitx应该让你提交或忽略单独的行(你可能已经知道了),但每次提交时你都必须这样做。我认为最好为每个部署目标配置一个配置文件(您可以对其进行版本设置),然后为启动服务器(例如./myserver --config=whatever.js)创建一些运行时参数。

答案 3 :(得分:4)

继续https://stackoverflow.com/a/20574486/4935114@Mike建议创建一个pre-commit挂钩,它将grep放在可能要忽略的行的暂存文件中。钩子检查这些线是否被分阶段。如果是,则echo发出警告,exit代码为1,因此提交过程将不会继续。

受到@Mike's answer的启发,我发现自己可能使用了一个改进版本的钩子自动 reset s(带-p标志)特定行我们想忽略它。

我不确定这个钩子是否适用于有许多文件要忽略此行的情况,但是这个pre-commit钩子会在特定文件{{1}中查找此行中的更改}。当我在我的机器上测试时,钩子脚本看起来像这样。

buildVars.java

解释

我所做的是回应在交互式#!/bin/sh # this hook looks for lines with the text `var isPhoneGap = false;` in the file `buildVars.java` and it resets these lines to the previous state before staged with `reset -p` if [[ $(git diff --no-ext-diff --cached buildVars.java | grep --count -e "var\ isPhoneGap[\ ]*=[\ ]*") -ne 0 ]]; then cat <<EOW WARNING: You are attempting to commit changes which are not supposed to be commited according to this \`pre-commit\` hook This \`pre-commit\` hook will reset all the files containing this line to it's previous state in the last commit. EOW echo /$'\n'isPhoneGap$'\n'y$'\n'q | git reset -p # BONUS: Check if after reseting, there is no actual changes to be commited and if so, exit 1 so the commit process will abort. if [[ $(git diff --no-ext-diff --cached | wc -l) -eq 0 ]]; then echo there are no actual changes to be commited and besides the change to the variable \'isPhoneGap\' so I won\'t commit. exit 1 fi fi 进程中搜索正则表达式isPhoneGap的控制序列。因此,模拟按reset以搜索/的用户,在被询问是否要丢弃此修补程序时按isPhoneGap,最后按y退出交互式{{1} }}

此处记录了交互式反向修补过程:https://git-scm.com/docs/git-add#git-add-patch

注意:以上脚本假设变量interactive.singleKeyq。如果您将自己配置为reset,请在警告后立即从false命令中删除任何true

答案 4 :(得分:3)

您可以使用git filters

来实现这一目标
  1. 创建/打开gitattributes文件:
    • &lt; project root&gt; / .gitattributes(将被提交到repo)
      OR
    • &lt; project root&gt; / .git / info / attributes(不会被提交到repo中)
  2. 添加一行定义要过滤的文件:
    • *.rb filter=gitignore,即在所有gitignore个文件上运行名为*.rb的过滤器
  3. gitignore中定义gitconfig过滤器:
    • $ git config --global filter.gitignore.clean "sed '/#gitignore$/'d",即删除这些行
    • $ git config --global filter.gitignore.smudge cat,即从repo中提取文件时不执行任何操作
  4. 注意:
    当然,这是针对ruby文件,当行以#gitignore结尾时应用,在~/.gitconfig中全局应用。根据您的需要对此进行修改。

    警告!
    这使您的工作文件与repo(当然)不同。任何退房或重新定位都意味着这些线路将会丢失!这个技巧似乎没用,因为这些行在签出,重新绑定或拉取时反复丢失,但我有一个特定的用例才能使用它。

    过滤器处于非活动状态时只需git stash save "proj1-debug" (只是在gitconfig或其他内容暂时禁用它)。通过这种方式,我的调试代码可以随时git stash apply添加到我的代码中,而不必担心这些行会被意外提交。

    我有可能处理这些问题,但我会尝试在其他时间实施它。

    感谢Rudi和jw013提到git过滤器和gitattributes。

答案 5 :(得分:2)

内容过滤器驱动程序不是一个好的解决方案。您可以隐藏git status / etc中的这一行,但它并没有被忽略。一旦更改了值,即使更改可能不可见,您的工作目录也会被标记为脏。

如果您确实希望此行不受版本控制,将其更改为命令行参数或将其置于忽略的包含或构建文件中可能是唯一可行的方法。

答案 6 :(得分:1)

我猜这可能是你的来源的多行内容。

我认为拥有你刚才包含的某种类型的.userbuildconfig文件并检查默认值是最干净的。然后你可以使用Carlos's suggestion单独标记该文件,假设不变。这样就不会错过对您需要检查设置的文件的其他更改。

这可以允许您在本地调整预处理器宏(或者对于类似于此https://stackoverflow.com/a/1813873/1270965的java)。

答案 7 :(得分:0)

我认为没有人提供过这种方法来解决这个问题,所以,这是我的技巧。我在本地存储库的私有分支中的单个修订版(实际上,它可能是多个)中记录/调试/等内容。所以,当我开始一个功能分支并且我想要拥有我所有的好东西(在 my-goodies 分支中)时,我只是这样做:

git checkout my-feature
git cherry-pick my-feature..my-goodies # assuming both started from the same main branch, say, my-goodies started a few (or many) revisions back

现在我开始研究该功能。完成后,我重写功能分支的历史记录,以便这些修订消失:

git rebase -i @{u} # set all the goodies revisions to skip, save, and go

现在我的分支已经没有我所有的好东西了,我可以推到任何地方。

答案 8 :(得分:-1)

不。您只能忽略单个文件(以及更多),因为.gitignore中的行与文件名匹配,而不与文件内容匹配。您已经提到了解决方案,即忽略包含您要忽略的内容的单个文件。