简体   繁体   English

如何让 git 忽略文件的未来修订?

[英]How can I make git ignore future revisions to a file?

I have created a default version of a file included in a git repository.我创建了一个包含在 git 存储库中的文件的默认版本。 It's important that when someone clones the repository, they get a copy of this file.重要的是,当有人克隆存储库时,他们会获得此文件的副本。 However, I would like to set git so that it ignores changes to this file later.但是,我想设置 git,以便它稍后忽略对此文件的更改。 .gitignore works only on untracked files. .gitignore仅适用于未跟踪的文件。

My motivation is that this file contains machine-specific information.我的动机是该文件包含特定于机器的信息。 I would like to provide default values, while allowing people to make local changes that won't get pushed back to the origin repository, creating merge conflicts when we pull new changes.我想提供默认值,同时允许人们进行不会被推回原始存储库的本地更改,当我们拉新更改时会产生合并冲突。

We are generally pretty lazy and use git add .我们通常很懒惰并使用git add . a lot, so I'm pretty sure if I can't tell git to ignore this file, changes to it will end up getting committed and pushed.很多,所以我很确定如果我不能告诉 git 忽略这个文件,对它的更改最终会被提交和推送。

To summarize,总结一下,

  1. I would like to create a file, call it default_values.txt that is added to my git repository and is included when someone clones that repository.我想创建一个文件,将其命名为default_values.txt ,该文件将添加到我的 git 存储库中,并在有人克隆该存储库时包含在内。
  2. git add . should not add default_values.txt to the commit.不应将default_values.txt添加到提交中。
  3. This behavior should be passed on to any clones of the repository.此行为应传递给存储库的任何克隆。

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.请注意,与--skip-worktree不同,一旦上游更改被拉动, --assume-unchanged状态将丢失。

What you are searching for is git update-index --assume-unchanged default_values.txt .您正在搜索的是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有关更多详细信息,请参阅文档: http : //www.kernel.org/pub/software/scm/git/docs/git-update-index.html

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.我通常看到的方法是创建一个具有不同名称的文件,例如:default_values_template.txt 并将 default_values.txt 放在您的 .gitignore 中。 Instruct people to copy default_values_template.txt to default_values.txt in their local workspaces and make changes as needed.指导人们将 default_values_template.txt 复制到他们本地工作区中的 default_values.txt 并根据需要进行更改。

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.如果您需要公开您的存储库,但内容可能包含敏感信息,同样可以应用密码。

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: git show :path/to/myfile应该只打印指定文件的索引内容,因此我们可以在脚本中使用它来用索引中未修改的副本替换工作副本:

#! /bin/sh

git show :$1

Set that as the "clean" filter for the file concerned (assuming you've put that in "discard_changes"):将其设置为相关文件的“干净”过滤器(假设您已将其放在“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.当然,没有什么可以阻止您为每个文件添加不同的过滤规则,但这有点笨拙。

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 .我们通过符号链接共享我们的 githooks,在向 git 添加模板文件后,我添加了一个预提交钩子,检查模板文件是否已被修改,如果是,我git reset -- templatefile.txt If it's the only changed file I also abort the commit.如果它是唯一更改的文件,我也会中止提交。

I suggest looking into submodules.我建议查看子模块。 If you place the machine specific files in a submodule, git add should ignore it.如果您将机器特定的文件放在子模块中, git add 应该忽略它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM