Git将如何合并这个文件?

4

约翰和汤姆克隆了同一个远程仓库。 远程仓库的内容如下:

FileA.c

约翰像这样进行了本地提交,即将FileA.c移动到名为John的文件夹中,并在本地提交。
John\FileA.c

Tom也像这样进行了本地提交,即将FileA.c移动到名为Tom的文件夹中,并在本地进行提交。

Tom\FileA.c

如果Tom和John都将他们的本地仓库推送到远程仓库(比如GitHub),Git会如何合并呢?
希望我表述清楚了。谢谢!
6个回答

4
当您使用git commit提交更改但未使用git push时,更改将添加到本地仓库中而未提交到全局仓库。因此,先推送更改的用户不会遇到冲突,因为远程服务器不知道其他尚未push的用户所做的更改。稍后,当下一个用户尝试推送更改时,git将提示全局仓库已更改,必须先拉取更改。由于更改在同一文件中且位置已更改,将出现冲突,git无法自行解决。 下一个用户必须再次进行更改并推送以更新全局仓库。

2
Git/SVN等工具会尽可能地合并代码:如果它们发现John / FileA.c和Karen / FileA.c添加/删除/修改了不相互干扰的代码行,则会简单地组合这些更改。如果合并脚本发现同一行代码已被编辑,则会将其标记为文件冲突。
我认为这一点已经说得很清楚了,但这个过程是在本地进行的;由Karen或John执行,具体取决于谁最后尝试推送。最后推送的人将收到通知,要从远程存储库中拉取并解决任何冲突,然后再推送自己的更改。

1

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

1
第二次推送操作将失败;必须在本地进行合并。在这种情况下,必须手动解决冲突。

1

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很好,会询问哪个重命名是正确的。请注意,并非所有版本控制系统都能检测到这种类型的重命名/重命名冲突。


0
其他答案的关键点是,git不会“猜测”应该发生什么[使用一些预编码的假设],而是会警告用户因为它无法读取各种用户意图而导致的困难。
大多数声称能够执行此类合并的其他系统都未通过透视测试-它们不知道您真正想要什么。让聪明的人(也就是你和我;-)做出决定。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接