如何使git忽略文件的将来修订?


140

我已经创建了git存储库中包含的文件的默认版本。重要的是,当有人克隆存储库时,他们将获得此文件的副本。但是,我想设置git,以便以后忽略对该文件的更改。 .gitignore仅适用于未跟踪的文件。

我的动机是此文件包含特定于计算机的信息。我想提供默认值,同时允许人们进行不会被推回原始存储库的本地更改,并在我们进行新更改时产生合并冲突。

我们通常很懒惰并且使用git add .很多,所以我很确定如果我不能告诉git忽略这个文件,对其的更改最终将被提交并推送。

总而言之,

  1. 我想创建一个文件,调用它default_values.txt添加到我的git存储库中,并在有人克隆该存储库时将其包含在内。
  2. git add .不应该添加default_values.txt到提交中。
  3. 此行为应传递给存储库的任何克隆。

1
如果修改的文件是default_values.txt(例如),您可以利用git hooks来使用pre-commit钩子来中止提交吗?
sateesh 2010年

1
Git纯粹主义者会说不要偷懒,并正确使用暂存区,这就是它的用途。
Xint0

Git纯粹主义者会说使用污迹/干净的脚本。这是最可维护的解决方案。
亚当·迪米特鲁克

1
Xint0:是的。但是如何防止其他人意外签入?
艾伦

Answers:


115

正如许多其他人所提到的,一个好的现代解决方案是:

git update-index --skip-worktree default_values.txt

这将忽略对该文件的本地和上游更改,直到您决定再次允许它们使用:

git update-index --no-skip-worktree default_values.txt

您可以获取标记为已跳过的文件的列表:

git ls-files -v . | grep ^S

请注意,与不同--skip-worktree--assume-unchanged一旦拉起上游更改,状态将丢失。


2
如果其他人拉出仓库并编辑文件,是否会忽略其目录中的更改?我希望他们必须输入--no-skip-worktree以添加更改。
neaumusic

3
它们的更改由他们控制。换句话说,如果他们不希望推送更改,则必须在其回购中的文件上设置skip-worktree。如果该文件要发送给所有人,然后忽略所有后续更改,则每个人都必须遵循这些相同的说明。
moodboom

3
请注意--skip-worktree,如果在另一个分支中跟踪了同一文件,则可能必须先撤消文件的状态才能切换分支。
moodboom

3
嗯,它可以工作...在文件中做了一些更改后,该文件未显示在中git status,但是当我尝试签出到其他分支时,我知道了error: Your local changes to the following files would be overwritten by checkout: ,即使-f也无济于事error: Entry 'wix-stores-merchant-app/demo/credentials.js' not uptodate. Cannot merge.
ykravv

1
我将这些别名别名为git ignoregit unignore
Michael-Clay Shirky在哪里

48

您正在寻找的是git update-index --assume-unchanged default_values.txt

有关更多详细信息,请参阅文档:http : //www.kernel.org/pub/software/scm/git/docs/git-update-index.html


11
这行不通。虽然它使git add。忽略本地分支上的文件,存档的克隆不具有此行为(如果您更改了克隆的存档中的default_values.txt,它将使用“ git add”添加到提交中。)
Marc 2010年

6
是的,因为您仅将其设置为本地存储库。您不能推送此类信息。
tamasd

8
@Indradhanush-此解决方案不满足条件3-“该行为应传递给存储库的任何克隆”-这就是为什么我不接受它。并不意味着这不是一个好答案。
2014年

我从没注意到第三个标准。因为我不是要找的。:)
Indradhanush Gupta 2014年

3
对于私有应用程序设置本地配置文件,你可能想使用skip-worktree的,而不是assume-unchanged更多的信息stackoverflow.com/questions/13630849/...
亚伦·霍夫曼

22

我通常看到的方法是创建一个具有不同名称的文件,例如:default_values_template.txt并将default_values.txt放入您的.gitignore文件中。指示人们在其本地工作区中将default_values_template.txt复制到default_values.txt,并根据需要进行更改。


嗯...也许我可以写一个钩子,如果default_values不存在,可以自动将default_values_template复制到default_values?
Marc 2010年

2
根据我的经验,这是解决此问题的最常见方法。这几乎是阻力最小的途径,因为它“有效”,并且您可以轻松地使代码检查本地配置文件是否存在,如果不存在则提供有用的错误。
Jani Hartikainen

我认为解决方案的确是这样做,最好是在您拉出或克隆时执行一个脚本。一种想法是,将具有特定扩展名的任何内容(例如.basefile)复制到删除了扩展名的文件中,然后将该文件名添加到该目录中的.gitignore。因此,我将创建一个文件default_values.txt.basefile并将其提交。我没有git或perl排骨来做到这一点,但是我会问一个做的朋友,让您知道它是如何工作的。
Marc 2010年

1
@AdamDymitruk:是的,在这种情况下可以使用清洁/涂抹功能,但尚不清楚这是最佳选择。例如,如果人们真的更改文件,这将变得非常困难,因为清除/污迹会妨碍您的工作。我实际上更喜欢这里描述的方法。
sleske

1
我从git本身(特别是git钩子)中获取提示,并使用.sample后缀。所以在您的情况下default_values.txt.sample
tir38

5

看一下污迹/干净的脚本。这样,您可以对文件进行版本控制,但是当签出文件时,可以通过用文件中的计算机专用数据替换通用/占位符数据来“涂抹”它。

提交时,可以通过用通用或占位符信息替换机器特定的信息来“清理”它。

污迹/清除脚本必须具有确定性,因为可以多次应用它们,以不同的顺序等效于只运行序列中的最后一个脚本。

如果您需要公开存储库,则可以对密码进行同样的设置,但是内容可能包含敏感信息。


清理脚本和污迹脚本是本地的还是回购协议的一部分?
艾伦

是。:) ...也就是说,您可以通过回购共享干净的污垢,但是当它们包含生产密码等敏感数据时,这不是一个好主意。如果这无关紧要,则git要求您显式启用脚本。否则,人们可以通过github和其他共享存储库对其他用户执行恶意操作。
亚当·迪米特鲁克

我需要阅读更多有关此的内容。基本上,我想设置一个默认项目,user.json每个开发人员的信用都需要覆盖该项目,但是我不想让开发人员意外检查其信用。
艾伦(Alan)

我会四处搜寻干净的污迹示例脚本。看看会发生什么。另外,跳到freenode上的git irc房间。您会立即获得帮助。
亚当·迪米特鲁克

3

我已经通过定义“干净”过滤器来解决这个问题,该过滤器仅将索引中文件的内容包含在内。

git show :path/to/myfile 应该只打印指定文件的索引内容,因此我们可以在脚本中使用该内容将工作副本替换为索引中的原始副本:

#! /bin/sh

git show :$1

将其设置为有关文件的“干净”过滤器(假设您已将其放在“ discard_changes”中):

$ git config filter.ignore_myfile.clean "discard_changes path/to/myfile"
$ echo "path/to/myfile filter=ignore_myfile" >> .gitattributes

不幸的是,我找不到将其通用化到多个文件的方法,因为无法从干净脚本中分辨出我们正在处理哪个文件。当然,没有什么可以阻止您为每个文件添加不同的过滤器规则,但这有点笨拙。


1

我找到了适合我的团队的解决方案。我们通过符号链接共享githooks,在将模板文件添加到git之后,我添加了一个预提交钩子,该钩子检查模板文件是否已修改,如果是,则进行修改git reset -- templatefile.txt。如果这是唯一更改的文件,我也将中止提交。


-1

我建议研究子模块。如果将机器特定的文件放在子模块中,则git add应该忽略它。


这是一个好主意,但随后我还必须将单个文件存储库也放到git服务器上,这并不是最佳选择,只是因为我们使用的是github并且存储库数量有限。
Marc 2010年

@Marc看看Visual Studio Team Services,无限的免费私人项目和git存储库。看板,工作项和错误跟踪,将签入与工作项关联,管理冲刺(如果您进入Scrum或其他项目类型)。它具有出色的构建工具,可以针对多个平台进行构建,还有很多东西都是免费的。有人因为它的Microsoft而对它不屑一顾,但是它不仅仅在存储库托管方面击败了github在工具方面所提供的功能。您可以免费做的事情有一些限制,但我很少超过这些限制。
阿兰·穆赫兰

@Marc我真的很方便的一件事是,我可以设置任意数量的帐户,因此,如果我为想要拥有源代码管理的客户编写项目,则可以创建一个帐户,使用它计划,设计和执行项目,完成后我可以将帐户所有权转让给客户。
亚兰·穆赫兰
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.