此问题与相关以下问题:https://stackoverflow.com/search?q=[git]+%2Bassume-unchanged但是,这些问题所提供的答案似乎都不符合我的需求。
我有一个由python脚本生成的头文件(key_info.h)。为了聪明,我使用一行代码控制了标题(key_info.h)的占位符版本:
int i = you_need_to_run_the_key_info_gen_python_script_to_generate_this_file();
在运行python脚本之前,编译此代码会产生错误,告诉开发人员确切要做什么;运行脚本。
当然,开发人员将继续运行python脚本来生成最新版本的key_info.h,代码将成功编译。然后,开发人员将继续进行一系列更改,然后“git commit”他们的代码。
我们遇到的问题是key_info.h现在已被修改。因此,git会将其作为修改来接收并允许它被提交。但是,此标头的生成版本永远不应受版本控制。我们需要占位符版本保持不变,以继续向开发人员提供编译错误提示。
我的第一直觉是使用.gitignore来阻止git在提交中获取key_info.h。然后.gitignore可以在开发人员之间轻松共享,因为.gitignore本身是受版本控制的。不幸的是,.gitignore仅适用于不受版本控制的文件。
我的下一个想法是使用'git update-index --assume-unchanged / path / to / file'。这在本地工作得很好,但我无法对其他开发人员强制执行此规则。在dev意外提交生成的标题之前,这只是时间问题。
所以我的问题是:有没有办法对文件进行版本控制,同时默默地强制执行一个规则,即在提交更改时要忽略该文件?我真正想要的是.gitignore版本控制文件。
答案 0 :(得分:3)
但我无法对其他开发者强制执行此规则
你几乎可以:你可以让你的key-info-gen脚本运行git update-index --assume-unchanged /some/path
。
但我认为这不是一个好主意。
我可能会选择不覆盖头文件。让您的Python脚本生成正确的头文件并将其写入不同的目录,并以正确的顺序为这两个目录传递-I
编译器选项。如果尚未运行脚本,则将找到版本控制的标头。如果脚本已运行,则将找到用户生成的标头。然后,您可以将用户生成的标头的路径放在.gitignore
。
答案 1 :(得分:3)
一些替代方案,排名和tl;由一些你从未见过的人做过:
执行此操作的最佳方法是根本不跟踪文件,因为您拥有的是makefile目标。如果您不能或不想要make
......那么,任何IDE都可以配置构建配方,对吗?
@hvd has the best version of this one,我最初错过了它:将生成的标头放在.gitignored generated-headers
目录中,让编译器先搜索,并保留默认为备份。
如果您的构建过程不适合,那么接下来最好的是the filter method @VonC describes,因为它可以防止临时检出没有该文件的分支。过滤器上的tl; dr是“保留那里的东西”:
git config filter.pin-content.clean 'git show HEAD:%f 2>&- || cat'
git config filter.pin-content.smudge 'cat %f 2>&- || cat'
echo anypatternyouwant filter=pin-content >>.gitattributes # tracked, global
echo anypatternyouwant filter=pin-content >>.git/info/attributes # local-only
注意: git will silently ignore filters that aren't configured,所以提供一个文件 跟踪属性将起作用,在他们想要之前对其他人没有影响。
接下来最好的是规范方法,只要在所有分支上跟踪文件,这是最容易实现和处理的方法:
git update-index --assume-unchanged key_info.h
但是当您暂时切换到不跟踪该文件的分支时,它将在返回时失去此保护。
答案 2 :(得分:1)
这在本地很有效,但我无法对其他开发人员强制执行此规则
另一种方法是声明一个内容过滤器驱动程序,该驱动程序将在git add
上自动将您的文件还原到相应的内容。
(来自Pro Git book 7.2 Customizing Git - Git Attributes)
您可以存储和分享:
.gitattributes
file。clean
”脚本但是:每个用户仍然必须在他们的本地配置中注册该过滤器:
git config filter.<filtername>.clean ./<filterscript>
因此没有通用的方法来“忽略”版本化文件,只有本地解决方案才能应用于每个仓库。
同样的过滤器可以帮助您:
key_info.h.tpl
key_info.h
保持私密您并不总是需要存储脚本,因为它可以在过滤器声明中,因为jthill评论below:
为此,自1.8.5以来,过滤器获取路径名,您可以使过滤器设置为自包含。
例如:
git config filter.pin-content.clean 'git show HEAD:%f 2>&- || cat'
git config filter.pin-content.smudge 'cat %f 2>&- || cat'
如果其他任何人使用了所提供的内容,那将保留目的地内容 然后:
echo anypatternyoulike filter=pin-content >>.git/info/attributes
将过滤器设为本地,或...>>.gitattributes
使其全球化。