Git子树工作流-为什么子树合并/拉取总是导致冲突?

Git子树工作流-为什么子树合并/拉取总是导致冲突?,git,merge,git-subtree,Git,Merge,Git Subtree,我在一个真实的项目中遇到了这个问题,并设法用下面的最少步骤重现了它 编辑:这不是重复的问题。我看到了另一个问题,涉及到git子树add,这里不是这样 这个场景是:我有一个大的存储库,我想把项目的一小部分交给其他人来处理,并最终在完成后将他们的工作合并回大型回购 问题是,git子树合并(以及相关的推/拉)总是导致虚假冲突 以下是完整的运行记录: root@devbox:/tmp/git-demo# ll total 164 drwxr-xr-x 2 root root 4096 Dec 5

我在一个真实的项目中遇到了这个问题,并设法用下面的最少步骤重现了它

编辑:这不是重复的问题。我看到了另一个问题,涉及到
git子树add
,这里不是这样

这个场景是:我有一个大的存储库,我想把项目的一小部分交给其他人来处理,并最终在完成后将他们的工作合并回大型回购

问题是,
git子树合并
(以及相关的推/拉)总是导致虚假冲突

以下是完整的运行记录:

root@devbox:/tmp/git-demo# ll
total 164
drwxr-xr-x 2 root root   4096 Dec  5 10:55 ./
drwxrwxrwt 9 root root 159744 Dec  5 10:55 ../

root@devbox:/tmp/git-demo# git init bigrepo
Initialized empty Git repository in /tmp/git-demo/bigrepo/.git/

root@devbox:/tmp/git-demo# cd bigrepo/
root@devbox:/tmp/git-demo/bigrepo# echo 1 > one.txt
root@devbox:/tmp/git-demo/bigrepo# echo 2 > two.txt
root@devbox:/tmp/git-demo/bigrepo# mkdir lib
root@devbox:/tmp/git-demo/bigrepo# echo 3 > lib/three.txt
root@devbox:/tmp/git-demo/bigrepo# echo 4 > lib/four.txt
root@devbox:/tmp/git-demo/bigrepo# git add -A :/
root@devbox:/tmp/git-demo/bigrepo# git commit -minitial
[master (root-commit) 8360303] initial
 4 files changed, 4 insertions(+)
 create mode 100644 lib/four.txt
 create mode 100644 lib/three.txt
 create mode 100644 one.txt
 create mode 100644 two.txt
在这里,我为我的合作者准备了一份小型回购协议:

root@devbox:/tmp/git-demo/bigrepo# git subtree split --prefix=lib
87938ea784d67b83d61e6292a85788f3bdb28fab
root@devbox:/tmp/git-demo/bigrepo# git checkout -b lib_br 87938ea784d67b83d61e6292a85788f3bdb28fab
Switched to a new branch 'lib_br'

root@devbox:/tmp/git-demo/bigrepo# git init ../smallrepo
Initialized empty Git repository in /tmp/git-demo/smallrepo/.git/

root@devbox:/tmp/git-demo/bigrepo# git remote add small ../smallrepo
root@devbox:/tmp/git-demo/bigrepo# git push small lib_br:work
Counting objects: 4, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 238 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To ../smallrepo
 * [new branch]      lib_br -> work
现在假设你是另一台机器上的合作者。忽略我正在使用本地存储库这一事实,使用github时问题也是一样的。准备做一些工作:

root@devbox:/tmp/git-demo/bigrepo# cd ../collaborator/
root@devbox:/tmp/git-demo/collaborator# git clone ../smallrepo
Cloning into 'smallrepo'...
done.
root@devbox:/tmp/git-demo/collaborator# cd smallrepo/
root@devbox:/tmp/git-demo/collaborator/smallrepo# ls
four.txt  three.txt
root@devbox:/tmp/git-demo/collaborator/smallrepo# git status
On branch work
Your branch is up-to-date with 'origin/work'.

nothing to commit, working directory clean
现在,在一个文件中添加一行:

root@devbox:/tmp/git-demo/collaborator/smallrepo# echo 3-too >> three.txt
root@devbox:/tmp/git-demo/collaborator/smallrepo# git commit -a -m"added a line"
[work feb5252] added a line
 1 file changed, 1 insertion(+)
合作者出版了他们的杰作:

root@devbox:/tmp/git-demo/collaborator/smallrepo# git push origin work:work2
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 265 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /tmp/git-demo/collaborator/../smallrepo
 * [new branch]      work -> work2
通常情况下,合作者会在这里推到
work
分支,但我忘了将
smallrepo
作为裸repo,所以他推到
work2
。与github相比,这不会改变行为,对于您最后实际看到的问题应该无关紧要

合作者收拾行李回家。现在我又想起了:

root@devbox:/tmp/git-demo/collaborator/smallrepo# cd ../../bigrepo
root@devbox:/tmp/git-demo/bigrepo# git checkout master
Switched to branch 'master'

root@devbox:/tmp/git-demo/bigrepo# ll
total 24
drwxr-xr-x 4 root root 4096 Dec  5 11:06 ./
drwxr-xr-x 5 root root 4096 Dec  5 10:59 ../
drwxr-xr-x 9 root root 4096 Dec  5 11:06 .git/
drwxr-xr-x 2 root root 4096 Dec  5 11:06 lib/
-rw-r--r-- 1 root root    2 Dec  5 11:06 one.txt
-rw-r--r-- 1 root root    2 Dec  5 11:06 two.txt

root@devbox:/tmp/git-demo/bigrepo# git subtree pull --prefix=lib small work2
From ../smallrepo
 * branch            work2      -> FETCH_HEAD
Auto-merging lib/three.txt
CONFLICT (add/add): Merge conflict in lib/three.txt
Automatic merge failed; fix conflicts and then commit the result.
好了。这一行的变化不应该是冲突。我在更大的文件上也看到过同样的情况,大的改变,小的改变,都没关系。当由
git subtree merge
处理时,任何一方涉及的每个文件都会成为冲突


那么,这是一个bug,还是我做错了什么?

可能的重复,也可能的重复,而不是重复。上述两种方法都使用git子树从中央回购中进行添加和提取。我使用子树拆分和从合作者的回购中提取,这与其他问题正好相反。