git -- 处理冻结内容
git -- 处理冻结内容
我所参与的几乎所有项目都有一些“冻结内容”,在克隆时应始终保留,但很少更改(如下所示)。我尝试过使用git的不同方法,但它们都容易出错:人们经常不小心提交更改。
这确实是一个微妙的情况:文件/文件夹必须进行版本控制,但绝大多数更改不应该被推送。
我找到了几个选择:
git update-index --assume-unchanged
:问题 - 这似乎是一个本地设置,因此只能解决特定机器上的问题。新的克隆容易忘记,并且仍然会不小心提交更改。git update-index --skip-worktree
:问题 - 似乎存在相同的问题,因为我认为索引的更改永远不会传播。git rm --cached
:问题 - 实际上根本不是解决方案,因为这会在推送时破坏每个人的副本!echo
:问题 - 实际上也不是解决方案,因为这只控制是否将对象添加到仓库。>> .gitignore - 使用smudge/clean过滤器从提交中排除文件更改(请参见jthill的答案):问题 - 复杂且容易出错:仍然需要每个开发人员进行本地配置。
对于这个问题,可接受的答案不需要每个新开发人员采取特殊措施。
为什么?因为这正是上述解决方案的问题所在,根据我的经验,这会导致“某人又提交了该文件”的情况。
搜索很容易找到很多问题。我们需要一个最终解答!
示例:
以下是我目前正在处理的情况。我的项目是一个嵌入了维基软件(我没有编写)的网站。维基组件需要一个非平凡的文件夹结构,类似于数据库(应该是一个数据库)。它需要找到已经存在的文件夹和文件才能工作。这些文件会变得很大 - 我们不想追踪这些更改!这个文件夹结构还包含一些配置(我知道)。如果我可以将纯净的副本包含在仓库中,并且以某种方式(几乎)不追踪其更改,那就太完美了。
git -- handling frozen content
在项目中放置以下文件:<proj-root>/.git/hooks/pre-commit
#!/bin/sh numFilesToVerify=0 IFS=$'\n' for l in `git diff --name-only --cached`; do while read m; do [[ $l == $m ]] && verify="$verify"`echo " * $l"`$'\n' && ((numFilesToVerify++)) done < .gitverify done if [ $numFilesToVerify -gt 0 ]; then echo "\nYou're changing $numFilesToVerify frozen files:"; echo "$verify" read -p "Do you know what you're doing? (yes/no): " reply < /dev/tty if [ "$reply" != "yes" ]; then echo 'commit aborted.' exit 1; fi fi unset IFS
然后,在文件<proj-root>/.gitverify
中列出您想要冻结的文件或目录。如果需要,可以使用*通配符:
testdir/test*
如果我尝试提交对tesdir/test
和testdir/test2
这两个文件的更改,会发生以下情况:
$ git commit -m 'test' You're changing 2 frozen files: * testdir/test * testdir/test2 Do you know what you're doing? (yes/no): no commit aborted.
优点:
- 我可以轻松添加/删除冻结列表中的文件
- 如果更新部分tar文件(参见Chris的答案),有可能会覆盖不打算更改的部分。这里不需要tar文件,而且它会告诉您可能愚蠢的事情。
- 不使用服务器端钩子,因此不会出现访问或多个远程的问题。
这是一个有趣的解决方案,但它不违反您的“对于这个问题,一个可接受的答案不需要每个新开发者采取特殊措施”的要求吗?我相当确定每个用户在克隆后都必须手动设置此钩子,因为钩子不是仓库的一部分。
可恶!我以为它们是的。
git -- 处理冻结内容的问题
在处理冻结内容的问题中,我们需要找到出现这个问题的原因,并提出解决方法。根据下面的内容,我们可以得出以下结论:
问题的原因:
- 配置文件的样本和配置文件本身被混在一起,导致处理起来非常困难。
解决方法:
- 提交一个包含合理默认值的配置文件样本,例如config.sample.ini
。
- 忽略非样本文件,例如config.ini
。
- 在新机器的“启动”过程中,将config.sample.ini
文件复制为config.ini
,并进行自定义。在README、wiki或其他地方记录此过程。
- 确保代码在配置文件丢失时能够“正确失败”,例如当软件启动时立即显示“找不到config.ini文件。您是否复制了样本文件?”的错误信息。
这样做可以确保样本文件可以轻松更新。它确保配置文件不被提交。如果操作不正确,它会快速失败。而且实现起来相对简单。
从已提交的config.ini
到被忽略的config.ini
和已提交的config.sample.ini
的最快方法可能是执行以下操作:
git mv config.ini config.sample.ini echo config.ini >> .gitignore git commit -a -m "Replace config file with sample config file"
对于wiki示例的问题,我们可以采用类似的方法解决:
- 创建一个将被提交到仓库中的包含基本wiki内容的归档文件,例如wiki.zip
。
- 忽略将要提取wiki的目录,例如path/to/wiki-root
。
- 在文档中添加“使用unzip -d path/to/wiki-root
解压wiki”的说明。这现在是您的安装/部署过程的一部分。
现在,您可以根据需要更新zip文件并提交这些更改,同时忽略对提取文件的更改。
这种方法可以将样本文件和实际文件分开处理,使问题得到解决。