git -- 处理冻结内容

9 浏览
0 Comments

git -- 处理冻结内容

我所参与的几乎所有项目都有一些“冻结内容”,在克隆时应始终保留,但很少更改(如下所示)。我尝试过使用git的不同方法,但它们都容易出错:人们经常不小心提交更改。

这确实是一个微妙的情况:文件/文件夹必须进行版本控制,但绝大多数更改不应该被推送。

我找到了几个选择:

  • git update-index --assume-unchanged 问题 - 这似乎是一个本地设置,因此只能解决特定机器上的问题。新的克隆容易忘记,并且仍然会不小心提交更改。
  • git update-index --skip-worktree 问题 - 似乎存在相同的问题,因为我认为索引的更改永远不会传播。
  • git rm --cached 问题 - 实际上根本不是解决方案,因为这会在推送时破坏每个人的副本!
  • echo >> .gitignore问题 - 实际上也不是解决方案,因为这只控制是否将对象添加到仓库。
  • 使用smudge/clean过滤器从提交中排除文件更改(请参见jthill的答案):问题 - 复杂且容易出错:仍然需要每个开发人员进行本地配置。

对于这个问题,可接受的答案不需要每个新开发人员采取特殊措施

为什么?因为这正是上述解决方案的问题所在,根据我的经验,这会导致“某人又提交了该文件”的情况。

搜索很容易找到很多问题。我们需要一个最终解答!

示例:

以下是我目前正在处理的情况。我的项目是一个嵌入了维基软件(我没有编写)的网站。维基组件需要一个非平凡的文件夹结构,类似于数据库(应该是一个数据库)。它需要找到已经存在的文件夹和文件才能工作。这些文件会变得很大 - 我们不想追踪这些更改!这个文件夹结构还包含一些配置(我知道)。如果我可以将纯净的副本包含在仓库中,并且以某种方式(几乎)不追踪其更改,那就太完美了。

0
0 Comments

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/testtestdir/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文件,而且它会告诉您可能愚蠢的事情。
  • 不使用服务器端钩子,因此不会出现访问或多个远程的问题。

这是一个有趣的解决方案,但它不违反您的“对于这个问题,一个可接受的答案不需要每个新开发者采取特殊措施”的要求吗?我相当确定每个用户在克隆后都必须手动设置此钩子,因为钩子不是仓库的一部分。

可恶!我以为它们是的。

0
0 Comments

git -- handling frozen content的问题出现的原因是在没有克隆仓库的每个副本中强制实施“不要更改此内容”的策略的唯一方法是为其安装服务器端钩子。一个pre-receive钩子可以检查传入的提交是否更改了冻结文件,并拒绝它们(除非提交消息匹配某个魔术模式使其通过)。

解决方法是安装服务器端钩子。服务器端钩子只在你控制的中央仓库上工作,即不能在GitHub或其他类似的服务上使用。

这是一个近乎完美的解决方案。很可惜我们不能在GitHub上使用它。尽管如此,这仍然会帮助很多人。

0
0 Comments

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文件并提交这些更改,同时忽略对提取文件的更改。

这种方法可以将样本文件和实际文件分开处理,使问题得到解决。

0