在删除文件时合并Git子树时出现问题

Qui*_*cky 5 git git-merge git-subtree

我想在我的一个项目中使用子树,并使用此处描述的方法.在从子树中删除某些文件的情况下,将子树合并到子项目中时遇到问题.似乎在合并期间文件删除不会从子树集成分支传播到主分支.

我在Kubuntu 14.04上运行Git 1.9.1,并在我的主项目中集成.sub_projectsubtree

  1. 修改一个文件并删除我的另一个文件 sub_project

  2. 提交修改

  3. 浏览我的主项目

  4. 签出sub_project集成分支

  5. 拉修改(我看到修改后的文件的修改和删除的删除文件)

  6. 检查master我的主项目的分支

  7. git diff-tree -p sub_project_branch 表示已修改一个文件,并且已删除一个文件

  8. 执行我的子树集成分支到主分支的合并(删除的文件仍在那里,而修改已集成)

以下是相应的命令:

创建将用作子树的项目

$ 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 ..
Run Code Online (Sandbox Code Playgroud)

创建将使用子树的主项目

$ 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"
Run Code Online (Sandbox Code Playgroud)

创建子树

$ 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"
Run Code Online (Sandbox Code Playgroud)

检查子树是否已很好地集成

$ ls *
tutu

sources:
sub_project
$ ls sources/sub_project
tata
toto
Run Code Online (Sandbox Code Playgroud)

进入子树删除文件tata

$ cd ../sub_project
$ echo "#EOF" >> toto
$ git add toto
$ git rm tata
$ git commit -m "Add EOF and remove tata"
Run Code Online (Sandbox Code Playgroud)

返回主项目以集成子树修改

$ cd ../main_project
$ git checkout sub_project_branch
$ git fetch sub_project_remote
$ git pull
Run Code Online (Sandbox Code Playgroud)

检查子树中是否已删除tata

$ ls *
toto
Run Code Online (Sandbox Code Playgroud)

合并在主分支中

$ 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
Run Code Online (Sandbox Code Playgroud)

合并后检查tata已被删除

$ ls sources/sub_project
tata
toto
Run Code Online (Sandbox Code Playgroud)

我希望在主分支中看到文件的修改和其他文件的删除,但删除的文件仍然存在并被跟踪.文件的修改已经完成,但看起来删除还没有"合并".

我期望的行为与下面的命令序列中所示的行为相同,除了它们在分支而不是子树中完成之外,它执行完全相同的动作.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
Run Code Online (Sandbox Code Playgroud)

根据我的看法,似乎子树合并正在进行一种复制而不是真正的合并,这意味着如果源文件消失,则相应的目标文件不会被触及而不是被删除.

这种行为是正确的,还是我对子树合并应该做什么的理解是错误的?

我还在Git邮件列表上问过这个问题,但目前我没有答案.