4

我编写了这个脚本并在 OSX 10.8 Mountain Lion 上运行它,在默认的不区分大小写的 HFS 文件系统上。

#!/bin/sh -x
# create git repo
rm -rf caps
git init caps
cd caps
# commit empty file called "file"
touch file
git add .
git commit -am "initial commit"
# create branch called "branch"
git branch branch
# rename "file" to "File"
# using --force per http://stackoverflow.com/questions/6899582
git mv --force file File
git commit -am "renamed capital"
# switch to branch, make a non-conflicting commit
git checkout branch
touch newfile
git add .
git commit -am "branch commit"
# merge master into branch, commit merge
git merge --commit --no-edit master
# but where's the renamed File?
more File

脚本完成后,它在最后一行失败了,而它本应成功:

+ git merge --commit --no-edit master
Removing file
Merge made by the 'recursive' strategy.
 file => File | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename file => File (100%)
+ more File
File: No such file or directory

git status 显示了这一点:

$ git status
# On branch branch
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    File
#
no changes added to commit (use "git add" and/or "git commit -a")

我们可以在那个时候用 取回文件git checkout File,但是在那个时候很容易意外地提交删除。

我们最近一直在重命名很多文件,修复它们的大小写,这对我们的团队造成了很大的伤害。有没有我们可以用来解决这个问题的 git 设置或最佳实践?(现在,我们只是告诉大家要格外小心。)

4

2 回答 2

1

该问题(“删除重命名大写的文件”)正是David Turner ( )提交的 ae352c7f37ef2098e03ee86bc7fd75b210b17683解决的问题:dturner-tw

merge-recursive.c: 修复大小写合并错误

在不区分大小写的文件系统上,在合并时,如果传入的提交将文件重命名为仅更改其大小写,则该文件将被错误地从工作树中删除。
合并重命名时,旧名称的文件将被删除——但由于文件系统认为旧名称与新名称相同,因此实际上将删除新文件。

我们通过在第 0 阶段不删除索引中具有案例克隆的文件来避免这种情况。

这意味着,从 git 2.0.1+(2014 年 6 月 25 日)开始,合并现在应该可以工作了。

于 2014-07-27T07:20:25.587 回答
0

仅当重命名检测失败时才会出现此问题。

http://thread.gmane.org/gmane.comp.version-control.git/235889

碰巧 git 在 git 1.8 中禁用了对空文件的重命名检测。https://github.com/git/git/commit/4f7cb99ada26be5d86402a6e060f3ee16a672f16

此脚本在 git 1.7 和 git 1.8 上按预期运行:

#!/bin/sh -x
# create git repo
git --version
rm -rf caps
git init caps
cd caps
git config --get core.ignorecase
# commit empty file called "file"
echo file > file
git add .
git commit -am "initial commit"
# create branch called "branch"
git branch branch
# rename "file" to "File"
# using --force per http://stackoverflow.com/questions/6899582
git mv --force file File
git commit -am "renamed to File"
# switch to branch, make a non-conflicting commit
git checkout branch
echo newfile > newfile
git add .
git commit -am "branch commit"
# merge master into branch, commit merge
GIT_EDITOR=true git merge --verbose --commit master
ls File
git status

但是由于 git 中的一个错误,这个脚本失败了:

#!/bin/sh -x
# create git repo
git --version
rm -rf caps
git init caps
cd caps
git config --get core.ignorecase
# commit empty file called "file"
echo file > file
git add .
git commit -am "initial commit"
# create branch called "branch"
git branch branch
# rename "file" to "File"
# using --force per http://stackoverflow.com/questions/6899582
git mv --force file File
echo "completely different content" > File
git commit -am "renamed to File"
# switch to branch, make a non-conflicting commit
git checkout branch
echo newfile > newfile
git add .
git commit -am "branch commit"
# merge master into branch, commit merge
GIT_EDITOR=true git merge --verbose --commit master
ls File
git status
于 2013-10-10T17:03:03.537 回答