我想在我的一个项目中使用子树,并使用描述的方法here。在从子树中删除某些文件的情况下,将子树合并到子项目中时遇到问题。似乎在合并期间文件删除不会从子树集成分支传播到主分支。
我在 Kubuntu 14.04 上运行 Git 1.9.1 ,sub_project
在我的主项目中集成为subtree
。
修改一个文件,然后从我的sub_project
提交修改
浏览我的主项目
签出sub_project集成分支
拉动修改(我看到修改后的文件的修改和删除的删除文件)
查看我的主项目的master
分支
git diff-tree -p sub_project_branch
表示一个文件已被修改,一个文件已被删除
执行我的子树集成分支到主分支的合并(删除的文件仍在那里,而修改已经集成)
以下是相应的命令:
创建将用作子树的项目
$ mkdir sub_project
$ cd sub_project
$ git init
$ touch toto
$ echo "-----------------" >> toto
$ echo "- toto file">> toto
$ echo "-----------------" >> toto
$ touch tata
$ echo "-----------------" >> tata
$ echo "- tata file">> tata
$ echo "-----------------" >> tata
$ git add toto tata
$ git commit -m "Initial commit"
$ echo "echo toto" >> toto
$ echo "echo tata" >> tata
$ git commit -am "Add content to file"
$ cd ..
创建将使用子树的主项目
$ mkdir main_project
$ cd main_project
$ git init
$ touch tutu
$ echo "-----------------" >> tutu
$ echo "- tutu file">> tutu
$ echo "-----------------" >> tutu
$ git add tutu
$ git commit -m "Add tutu file"
创建子树
$ mkdir sources
$ git remote add sub_project_remote ../sub_project
$ git fetch sub_project_remote
$ git checkout -b sub_project_branch sub_project_remote/master
$ git checkout master
$ git read-tree --prefix=sources/sub_project/ -u sub_project_branch
$ git commit -am "Integration of subtree"
检查子树是否已完全集成
$ ls *
tutu
sources:
sub_project
$ ls sources/sub_project
tata
toto
进入子树删除文件tata
$ cd ../sub_project
$ echo "#EOF" >> toto
$ git add toto
$ git rm tata
$ git commit -m "Add EOF and remove tata"
返回主项目以集成子树修改
$ cd ../main_project
$ git checkout sub_project_branch
$ git fetch sub_project_remote
$ git pull
检查是否已在子树中删除了tata
$ ls *
toto
合并主分支
$ git checkout master
$ git diff-tree -p sub_project_branch
diff --git a/tata b/tata
deleted file mode 100644
index a4f4cc4..0000000
--- a/tata
+++ /dev/null
@@ -1,4 +0,0 @@
------------------
-- tata file
------------------
-echo tata
diff --git a/toto b/toto
index 8dfbe14..98ae756 100644
--- a/toto
+++ b/toto
@@ -2,3 +2,4 @@
- toto file
-----------------
echo toto
+#EOF
$ git merge -v --squash --no-commit -X subtree=sources/sub_project -X theirs sub_project_branch
合并后检查tata已被删除
$ ls sources/sub_project
tata
toto
我原本希望在主分支中看到文件的修改和其他文件的删除,但删除的文件仍然存在并被跟踪。文件的修改已经完成,但看起来删除还没有“合并”。
我期望的行为与下面的命令序列中所示的行为相同,除了在分支而不是子树中完成之外,它们执行完全相同的操作。 Toto应该已被修改,tata应该不再存在(或者至少不再被跟踪)。
#!/bin/sh
$ git init
$ touch toto
$ echo "-----------------" >> toto
$ echo "- toto file">> toto
$ echo "-----------------" >> toto
$ touch tata
$ echo "-----------------" >> tata
$ echo "- tata file">> tata
$ echo "-----------------" >> tata
$ git add toto tata
$ git commit -m "Initial commit"
$ echo "echo toto" >> toto
$ echo "echo tata" >> tata
$ git commit -am "Add content to file"
$ git checkout -b headers
$ echo "#EOF" >> toto
$ git add toto
$ git rm tata
$ git commit -m "Add EOF and remove tata"
$ git checkout master
$ touch tutu
$ echo "-----------------" >> tutu
$ echo "- tutu file">> tutu
$ echo "-----------------" >> tutu
$ git add tutu
$ git commit -m "Add tutu file"
$ git merge -m "Merge from headers branch" headers
Merge made by the 'recursive' strategy.
tata | 4 ----
toto | 1 +
2 files changed, 1 insertion(+), 4 deletions(-)
delete mode 100644 tata
[master a9cad6d] Add EOF
1 file changed, 1 insertion(+)
$ echo "#EOF" >> tutu
$ git add tutu
$ git commit -m "Add EOF"
$ ls
toto
tutu
#EOF
根据我的看法,似乎子树合并正在进行一种复制而不是真正的合并,这意味着如果源文件消失,则相应的目标文件不会被触及而不是被删除。
这种行为是正确的,还是我对子树合并应该做什么的理解是错误的?
我也在Git mailing list上提出了问题,但目前我没有答案。