135

在手机的本机浏览器上进行测试时,我正在使用 git 同步到 phonegap。因此,我有以下行:

var isPhoneGap = false;

显然我在构建时更改了它,但是有什么方法可以设置 git 忽略这一行,还是我必须将它放在自己的文件中并以这种方式忽略它?

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

4

9 回答 9

121

如果您的文件属于特定类型,您可以声明一个内容过滤器驱动程序,您可以在文件中声明它(如“ Git 属性.gitattributes”的“关键字扩展”中所示):

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

*.yourType filter=yourFilterName

(如果需要,您甚至可以为特定文件设置该过滤器

实施:

  • 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.


注意:在评论中,ohaalRoald建议将sed调用隔离在单独的helper.sh脚本中:

sed "s/isPhoneGap = .*/isPhoneGap = true/" "$@"
于 2014-03-04T11:56:08.540 回答
54

您可以使用

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

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

当文件有重要的更改时,您必须这样做:

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

此外,请参阅Git 文档更新索引以获取--[no-]assume-unchanged参数。

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

于 2012-07-11T09:58:15.207 回答
7

Gitx 应该允许您提交或忽略个别行(您可能已经知道),但每次提交时都必须这样做。我认为最好为每个部署目标提供一个配置文件(您可以对其进行版本化),以及一些运行时参数,以便您启动服务器(例如./myserver --config=whatever.js)。

于 2011-07-02T14:12:18.997 回答
6

继续https://stackoverflow.com/a/20574486/4935114@Mike建议创建一个pre-commit挂钩,它将grep在暂存文件中为人们可能想要忽略的行创建一个挂钩。钩子检查这些行是否已上演。如果是这样,它echo是一个警告并且它exit带有代码1,因此提交过程将不会继续。

受@Mike回答的启发,我发现自己可能使用了他的钩子的改进版本,它会自动 reset(带有-p标志)我们想要忽略的特定行。

我不确定这个钩子是否适用于你有很多文件需要忽略这一行的情况,但是这个pre-commit钩子会在特定文件的这一行中查找更改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过程中搜索正则表达式的控制序列。从而模拟用户按下/搜索isPhoneGapy当被问及是否要丢弃此补丁时按下,最后按下q退出交互reset

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


注意:上面的脚本假设变量interactive.singleKeyfalse. 如果您将您的配置为,请在警告后立即从命令true中删除任何内容。$'\n'echo

于 2017-09-05T19:30:02.773 回答
3

这就是你可以用git 过滤器做到这一点的方式:

  1. 创建/打开 gitattributes 文件:
    • <project root>/.gitattributes(将提交到 repo)
    • <project root>/.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 中提取文件时什么也不做

注意:
当然,这是针对 ruby​​ 文件,当行以 结尾时#gitignore应用,全局应用在~/.gitconfig. 根据您的目的修改它。

警告!!
这使您的工作文件与 repo 不同(当然)。任何检出或变基将意味着这些行将丢失!这个技巧可能看起来没用,因为这些行在签出、变基或拉取时会反复丢失,但我有一个特定的用例来使用它。

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

我对处理这些问题有一个可能的想法,但我会尝试在其他时间实现它。

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

于 2013-04-26T20:36:38.957 回答
2

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

如果您真的希望这条线脱离版本控制,将其更改为命令行参数或将其放在被忽略的包含或构建文件中可能是唯一实用的方法。

于 2014-05-28T07:54:47.350 回答
1

我猜这可能会出现在您的源代码的不止一行中。

我认为拥有某种类型的 .userbuildconfig 文件并将其包含在内并签入默认值是最干净的。然后您可以使用Carlos 的建议将该文件单独标记为假定未更改。这样就不会错过您需要检查设置的文件的其他更改。

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

于 2014-03-07T19:52:50.737 回答
1

我认为没有人提供这种方法来解决这个问题,所以这是我的技术。我在本地存储库的私有分支中将日志记录/调试/等内容保留在单个修订版(实际上可能是多个修订版)中。所以,当我启动一个特性分支并且我想拥有我所有的好东西(在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

现在我的分支已经从我所有的好东西中清除了,我可以在任何地方推动。

于 2021-06-07T22:57:46.027 回答
0

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

于 2011-07-03T10:23:07.930 回答