我可以“ git commit”文件,而忽略其内容更改吗?


355

我们团队中的每个开发人员都有自己的本地配置。该配置信息存储在一个名为devtargets.rbrake的构建任务中使用的文件中。我不希望开发人员破坏彼此的devtargets文件。

我首先想到的是将该文件放入.gitignore列表,以便不将其提交给git。

然后我开始怀疑:是否可以提交文件,但忽略对文件的更改?因此,我将提交文件的默认版本,然后当开发人员在其本地计算机上对其进行更改时,git将忽略所做的更改,并且当您执行git status或git commit时,它不会显示在更改的文件列表中。

那可能吗?这肯定是一个不错的功能...


1
另请参阅关于类似主题的stackoverflow.com/questions/3318043/…
VonC


Answers:


458

当然,我有时会使用

git update-index --assume-unchanged [<file> ...]

要撤消并重新开始跟踪(如果您忘记了未跟踪的文件,请参阅此问题):

git update-index --no-assume-unchanged [<file> ...]

相关文件

-[no-]假定不变
如果指定此标志,则不会更新为路径记录的对象名称。而是,此选项设置/取消设置路径的“假定不变”位。当“假定不变”位打开时,用户承诺不更改文件,并允许Git假定工作树文件与索引中记录的文件匹配。如果要更改工作树文件,则需要取消设置该位以告知Git。当在lstat(2)系统调用非常慢的文件系统(例如cif)上处理大型项目时,这有时会很有帮助。

如果需要修改索引中的该文件(例如合并提交)时,Git将失败(正常)。因此,如果假定未跟踪的文件在上游被更改,则您将需要手动处理这种情况。

在这种情况下,正常失败表示在进行拉取时,如果该文件的上游有任何更改(合法更改等),它将说:

$ git pull
…
From https://github.com/x/y
   72a914a..106a261  master     -> origin/master
Updating 72a914a..106a261
error: Your local changes to the following files would be overwritten by merge:
                filename.ext

并拒绝合并。

到那时,您可以通过还原本地更改来克服此问题,这是一种方法:

 $ git checkout filename.ext

然后再次拉出并重新修改您的本地文件,或者可以进行设置–no-assume-unchanged,此时可以进行常规的隐藏和合并等。


10
这个命令是在.git文件夹中本地执行的吗?我的意思是,如果我为config.php文件运行此命令,此命令是否会传播到其他使用回购协议的用户?
Magus 2015年

16
@Magus:不。这只会为您服务。
罗伯·威尔克森

3
不久之后,您将想知道如何确定文件是否假定不变:stackoverflow.com/questions/2363197/…–
西罗·桑蒂利

10
使用“ git stash”时,以这种方式忽略的文件更改将丢失。有办法解决吗?
亚历克西斯

5
这不是git update-index --assume-unchanged为了什么。 public-inbox.org/git/…–
jsageryd

97

这样做的首选方法是使用git update-index --skip-worktree <file>如此答案中所述

assume-unchanged用于检查一组文件是否已被修改的开销很大的情况;当您设置该位时,git(当然)假定与索引的该部分相对应的文件在工作副本中尚未被修改。因此,它避免了混乱的统计调用。只要索引中的文件条目发生更改(因此,当文件在上游更改时),该位就会丢失。

skip-worktree不仅如此:即使git知道文件已被修改(或需要通过reset --hard等修改),它也会假装还没有,而是使用索引中的版本。这一直持续到索引被丢弃为止。

要撤消此操作,请使用 git update-index --no-skip-worktree <file>

从git 2.25.1版本开始,这也不是推荐的方式,引用:

用户经常尝试使用假设不变和跳过工作树位来告诉Git忽略对跟踪文件的更改。这不能按预期方式工作,因为在执行某些操作时,Git可能仍会根据索引检查工作树文件。通常,Git不提供忽略跟踪文件更改的方法,因此建议使用替代解决方案。

例如,如果要更改的文件是某种配置文件,则存储库可以包含样本配置文件,然后可以将其复制到忽略的名称中并进行修改。该存储库甚至可以包含一个脚本,以将示例文件视为模板,并自动对其进行修改和复制。


这对签出存储库的所有用户都有效吗?除非明确声明,否则他们是否会获取某些文件,但错误地不再能够添加更改?
mmm

2
@momomo该标志存储在索引中,所以不,它仅用于单个用户。请参阅erjiang的答案,以了解适用于所有用户的功能。
1915903年

我试图弄清楚文件的内容应该是什么。我评论了您提到的答案,但没有答案。它应该位于哪里,内容是什么?你知道吗?
毫米

我没有关注。该命令用于忽略您在命令中指定的一个特定文件。该文件的内容不相关。
1915903年

1
Git的文件明确表示,不使用git update-index --skip-worktree用于这一目的。
bk2204

43

常见的做法似乎是创建一个devtargets.default.rb并提交它,然后指示每个用户将该文件复制到devtargets.rb(在.gitignore列表中)。例如,CakePHP对其数据库配置文件执行相同的操作,该配置文件自然会在计算机之间变化。


6
您无法.gitignore跟踪文件。.gitignore仅对不在索引中的文件有效。
CB Bailey 2010年

1
我试图避免这样做,尽管我确实没有充分的理由。我们现在正在这样做,我想记住我需要创建名称中不带“ .default”的自己的版本是很痛苦的。
德里克·贝利

11
@DerickBailey但是,公平地说,记住复制文件比记住--assume-unchanged对克隆存储库的每个人使用该选项要容易。
2013年

1
@DerickBailey,您还可以将rake构建设置为默认(devtargets.default.rb如果devtargets.rb不存在)。
路加福音

@erjang该devtargets.default.rb文件中的内容是什么?一个例子?
mmm

2

对于IntelliJ IDEA用户:如果要忽略一个或多个文件的更改,可以将其移动到别的文件Change Set

  • 前往Local ChangesCmd + 9
  • 选择您要忽略的文件
  • F6 将它们移到另一个 Change Set
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.