如何让Git忽略将来对文件的修订?

我创建了一个包含在Git存储库中的文件的默认版本。重要的是,当有人克隆存储库时,他们会获得此文件的副本。但是,我想设置Git,以便它以后忽略对此文件的更改。__,ABC0只对未跟踪的文件起作用。

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

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

概括地说,

  1. 我想创建一个文件,将其命名为__abc0,并将其添加到我的Git存储库中,当有人克隆该存储库时,将包含该文件。
  2. git add .不应将default_values.txt添加到COMMIT.
  3. 此行为应传递给存储库的任何克隆。
32021 次浏览

The approach I've generally seen is to create a file with a different name, eg: default_values_template.txt and put default_values.txt in your .gitignore. Instruct people to copy default_values_template.txt to default_values.txt in their local workspaces and make changes as needed.

I suggest looking into submodules. If you place the machine specific files in a submodule, git add should ignore it.

Take a look at smudge/clean scripting. This way you can version control the file but when it is checked out, you will "smudge" it by replacing the generic/place-holder data with machine specific data in the file.

When you commit it, you will "clean" it by replacing the machine specific information with generic or place-holder information.

Smudge/clean scripts must be deterministic in that applying them multiple times, in different orders will be the equivalent of just running the last one in the sequence.

The same can be applied with passwords if you need to expose your repository but the contents may contain sensitive information.

What you are searching for is git update-index --assume-unchanged default_values.txt.

See the docs for more details: http://www.kernel.org/pub/software/scm/git/docs/git-update-index.html

I've solved this by defining the "clean" filter to simply cat the contents of the file in the index.

git show :path/to/myfile should just print the contents of the index for the specified file, so we can use that in a script to replace the working copy with the untouched copy in the index:

#! /bin/sh


git show :$1

Set that as the "clean" filter for the file concerned (assuming you've put that in "discard_changes"):

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

Unfortunately I can't find a way to make this generalisable to multiple files, as there's no way to tell which file we're processing from inside the clean script. Of course, there's nothing to stop you from adding a different filter rule for each file, but it's a bit cludgy.

As many others have mentioned, a good modern solution is:

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

That will ignore changes to that file, both local and upstream, until you decide to allow them again with:

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

You can get a list of files that are marked skipped with:

git ls-files -v . | grep ^S

Note that unlike --skip-worktree, the --assume-unchanged status will get lost once an upstream change is pulled.

I found a solution that works for my team. We share our githooks via symlinks and after adding a template file to git I added a pre-commit hook that checks whether the template file has been modified and if so I git reset -- templatefile.txt. If it's the only changed file I also abort the commit.