约翰和汤姆克隆了同一个远程仓库。 远程仓库的内容如下:
FileA.c
约翰像这样进行了本地提交,即将FileA.c移动到名为John的文件夹中,并在本地提交。
John\FileA.c
Tom也像这样进行了本地提交,即将FileA.c移动到名为Tom的文件夹中,并在本地进行提交。
Tom\FileA.c
如果Tom和John都将他们的本地仓库推送到远程仓库(比如GitHub),Git会如何合并呢?
希望我表述清楚了。谢谢!
约翰和汤姆克隆了同一个远程仓库。 远程仓库的内容如下:
FileA.c
John\FileA.c
Tom也像这样进行了本地提交,即将FileA.c移动到名为Tom的文件夹中,并在本地进行提交。
Tom\FileA.c
git commit
提交更改但未使用git push
时,更改将添加到本地仓库中而未提交到全局仓库。因此,先推送更改的用户不会遇到冲突,因为远程服务器不知道其他尚未push
的用户所做的更改。稍后,当下一个用户尝试推送更改时,git将提示全局仓库已更改,必须先拉取更改。由于更改在同一文件中且位置已更改,将出现冲突,git无法自行解决。
下一个用户必须再次进行更改并推送以更新全局仓库。Git在push
期间永远不会合并。两个开发人员中的一个(试图最后推送的可怜人)必须在本地解决冲突,并告诉git文件应该移动到哪里。Git无法在没有人类干预的情况下确定文件应该结束的位置。
# dev1
git clone …
mkdir John && git mv FileA.c John/FileA.c
git commit -m 'move file to john subdir'
git push origin master
# dev2
git clone …
mkdir Tom && git mv FileA.c Tom/FileA.c
git commit -m 'move file to tom subdir'
git push origin master
# git errors out: non-fast-forward, pull first to resolve potential conflicts
git pull origin master
# merge conflict in FileA.c
# tell git which file to delete and which file to keep:
git rm Tom/FileA.c && git add John.FileA.c
git commit # creates a merge commit
git push origin master
Git 的好处在于,你可以轻松地尝试这些操作而不影响任何服务器。对最后一个推送的人来说,结果是:
02:32:54 ~/desktop/tom
$ git push
To /cygdrive/h/desktop/test
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to '/cygdrive/h/desktop/test'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again. See the
'Note about fast-forwards' section of 'git push --help' for details.
02:32:54 ~/desktop/tom
$ git pull
remote: Counting objects: 3, done.
remote: Total 2 (delta 0), reused 0 (delta 0)
Unpacking objects: 50% (1/2) Unpacking objects: 100% (2/2) Unpacking objects: 100% (2/2), done.
From /cygdrive/h/desktop/test
307f68a..2539f44 master -> origin/master
error: refusing to lose untracked file at 'John/FileA.c'
error: refusing to lose untracked file at 'John/FileA.c'
CONFLICT (rename/rename): Rename "FileA.c"->"Tom/FileA.c" in branch "HEAD" rename "FileA.c"->"John/FileA.c" in "2539f448bb15d10f14bef74688dc3470975c2dbf"
CONFLICT (rename/rename): Rename "FileA.c"->"Tom/FileA.c" in branch "HEAD" rename "FileA.c"->"John/FileA.c" in "2539f448bb15d10f14bef74688dc3470975c2dbf"
Automatic merge failed; fix conflicts and then commit the result
Git很好,会询问哪个重命名是正确的。请注意,并非所有版本控制系统都能检测到这种类型的重命名/重命名冲突。