184

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

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

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

总结一下,

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

7 回答 7

185

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

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状态就会丢失。

于 2016-09-29T17:03:05.323 回答
51

您正在搜索的是git update-index --assume-unchanged default_values.txt.

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

于 2010-12-03T19:08:16.447 回答
23

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

于 2010-12-03T18:28:29.870 回答
6

看看涂抹/清洁脚本。通过这种方式,您可以对文件进行版本控制,但是当它被检出时,您将通过用文件中的机器特定数据替换通用/占位符数据来“涂抹”它。

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

涂抹/清洁脚本必须是确定性的,因为以不同的顺序多次应用它们相当于只运行序列中的最后一个。

如果您需要公开存储库但内容可能包含敏感信息,则同样可以使用密码。

于 2010-12-03T18:53:14.790 回答
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

不幸的是,我找不到一种方法可以将其推广到多个文件,因为无法从干净的脚本中判断我们正在处理哪个文件。当然,没有什么可以阻止您为每个文件添加不同的过滤规则,但它有点笨拙。

于 2013-05-20T14:34:59.647 回答
1

我找到了适合我团队的解决方案。我们通过符号链接共享我们的 githooks,在将模板文件添加到 git 后,我​​添加了一个 pre-commit 挂钩,用于检查模板文件是否已被修改,如果是,我git reset -- templatefile.txt. 如果它是唯一更改的文件,我也会中止提交。

于 2018-04-24T12:35:04.607 回答
-2

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

于 2010-12-03T18:46:39.260 回答