我们在一个混合的环境中开发--有些人在Mac上工作,有些人在Linux上工作。这有时被证明是个挑战,因为那些在Linux上工作的人习惯于让他们的文件系统区分大小写,所以没有问题提交(不管是偶然还是其他的)多个不同的文件。(例如FileName.ext对filename.ext)
然而,当Mac上的人去查看存储库时,拥有一个不区分大小写的文件系统意味着这两个文件--只有在情况下不同--相互覆盖并造成普遍的破坏。
我知道有不同的git设置可以帮助大小写不敏感的文件系统上的人更好地处理大小写更改(例如core.ignorecase),但是这些设置不能解决存储库中有两个不同文件的问题,只有不同的情况。
我意识到修复它的唯一方法是确保Linux用户不提交两个不同的文件,这首先是为了防止情况不同。--如果一个区分大小写的文件系统上的用户试图在一个不区分大小写的文件系统上提交彼此混淆的文件,那么git中是否会弹出一个警告或错误?
发布于 2016-12-15 00:08:46
没有什么是内置的(尽管应该有,毫无疑问)。您可以做的是提供一个预提交钩子,以验证所有名称是否正常,如果没有,则阻止提交。
这个钩子只需要在Linux盒上运行(虽然让它在Linux和Mac上工作很容易,但是它只是Windows和它的默认贫困工具箱,这是有问题的)。您可能想要将它添加到一个侧分支中,并给Linux人员关于设置它的说明。
您可能也想检查分支名称,就像在git pre-commit or update hook for stopping commit with branch names having Case Insensitive match中一样。(有趣的是:这个问题的答案是我自己的,我已经忘记了。)
首先,让我们编写一个“检查案例冲突”函数。这只是一个用案例折叠排序的问题(这样"helloworld“和"helloWorld”被放置在相邻的位置),然后使用uniq -di打印任何重复的字符串(在案例折叠之后),但是没有不重复的字符串:
sort -f | uniq -di如果这产生任何输出,这些都是“坏名称”。让我们在一个临时文件中捕获输出并检查它的大小,这样我们也可以将它们打印到标准输出:
#! /bin/sh
TF=$(mktemp)
trap "rm -f $TF" 0 1 2 3 15
checkstdin() {
sort -f | uniq -di > $TF
test -s $TF || return 0 # if $TF is empty, we are good
echo "non-unique (after case folding) names found!" 1>&2
cat $TF 1>&2
return 1
}现在,我们只需要在将要提交的文件上使用它,也可以在分支名称上使用它。前者与git ls-files一起列出,因此:
git ls-files | checkstdin || {
echo "ERROR - file name collision, stopping commit" 1>&2
exit 1
}您可以设想使用git diff-index --cached -r --name-only --diff-filter=A HEAD只检查添加的文件,允许现有的大小写冲突继续,并/或尝试检查多个分支和/或提交,但这变得很困难。
将上述两个片段组合到一个脚本中(并进行测试),然后简单地将其复制到一个名为.git/hooks/pre-commit的可执行文件中。
检查分支名称要复杂一些。在创建分支名称时,而不是在提交分支名称时,这种情况确实应该发生,而且不可能在客户机上做得很好--这必须在具有适当全局视图的集中式服务器上完成。
下面是一种在服务器上使用预接收脚本( shell脚本)而不是Python (如链接答案)的方法。不过,我们仍然需要checkstdin函数,您可能希望在更新钩子而不是预接收钩子中这样做,因为您不需要拒绝整个推送,只需要一个分支名称。
NULLSHA=0000000000000000000000000000000000000000 # 40 0s
# Verify that the given branch name $1 is unique,
# even IF we fold all existing branch names' cases.
# To be used on any proposed branch creation (we won't
# look at existing branches).
check_new_branch_name() {
(echo "$1"; git for-each-ref --format='%(refname:short)' refs/heads) |
checkstdin || {
echo "ERROR: new branch name $1 is not unique after case-folding" 1>&2
exit 1 # or set overall failure status
}
}
while read oldsha newsha refname; do
... any other checks ...
case $oldsha,$refname in
$NULLSHA,refs/heads/*) check_new_branch_name ${refname#refs/heads/};;
esac
... continue with any other checks ...
donehttps://stackoverflow.com/questions/41154015
复制相似问题