我怀疑,我的情况非常典型。我正在与其他一些人一起使用 git 进行版本控制的(年轻)项目。我们的项目是一个网络应用程序,它需要对分布在几个不同配置文件中的某些路径和键进行本地配置。我们认为处理这个问题的一个好方法是制作这些配置文件的模板版本并在存储库中跟踪它,但不跟踪我们的单个配置文件(推荐,例如,here和here)。为了确保没有人意外提交他们的配置文件,我们将其添加到 gitignore 列表中。
但是我们在项目开始时并没有意识到这一点——只有在一个人开始并且其他人加入之后。所以其中一个配置文件在提交历史的早期就被跟踪了。我们的解决方案:当然是从 index 中删除它!
但这会产生一个令人讨厌的问题! 这是一个简化的场景:您有一个跟踪配置文件的分支。
git init # new repository
echo 'file a' > a.txt
git add a.txt
git commit -m 'initial commit'
然后您意识到这是一个问题,因此您创建了一个新分支来修复它:在新分支上,您从存储库索引中删除配置文件(并添加您想要跟踪的模板版本)。然后 gitignore 原始文件。
git checkout -b testbranch
cp a.txt a.template.txt
echo 'a.txt' > .gitignore # ignore a.txt
git add .gitignore
git add a.template.txt
git rm --cached a.txt
git commit -m 'make template file for a'
ls # shows that a.txt and a.template.txt are still in working tree
git status # shows that working directory is clean
当然,对配置文件进行重要更新。
echo 'super-critical config setting' >> a.txt
然后切换分支、合并和BOOM!
配置文件真的消失了,您所做的更改不会在任何分支上跟踪。
git checkout master
ls # shows a.txt, not a.template.txt
git checkout testbranch
ls # a.txt is gone!!
git checkout master
git merge testbranch master # a.txt is gone forever!!
在a.txt
gitignore 文件中隐藏了从索引中删除文件然后切换分支将覆盖或删除它的警告。如果您执行上述步骤,除了 gitignoring 之外a.txt
,您将无法在不移动或删除的情况下从 testbranch 切换a.txt
。如果您将它移动到另一个未跟踪的文件 ( a-copy.txt
),检出 master 然后再次检出 testbranch,您会看到它a.txt
已经消失,就像您要求的那样,但a-copy.txt
仍然存在。
这是我(可能)理解的部分。这是我不明白的:还有什么可能导致这个系统出现问题?由于 git 不跟踪单个文件,而是跟踪内容块,因此即使在存储库中从未跟踪特定文件(名称)(特别是从未从索引中删除),是否有某种方式可能会丢失超关键配置设置)? 有没有办法绝对确定存储库中未跟踪(gitignored)的数据永远不会被静默删除?
而且,为了记录,这里是我遇到的处理本地配置的其他选项。前三个似乎是容易忘记/错误的黑客,接下来的两个需要在本地配置一些其他文件,并且可能会丢失。最后一个似乎有点矫枉过正,但也许不是。如果您确定其中一种是处理配置文件的最佳方式,请解释原因。如果你知道更好的东西,那就太好了!
git stash
git update-index --assume-unchanged
- 本地设置的单独分支,每个单独的开发人员专用
- git 属性过滤器驱动程序(涂抹/清洁脚本)
- “部署”脚本,对于每个开发人员来说也是独立且私有的
- 每个开发人员都维护一个单独的存储库来跟踪他们的配置文件,完全独立于主代码存储库