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

时间:2015-05-22 08:10:31

标签: git git-merge git-subtree

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

我在 Kubuntu 14.04 上运行 Git 1.9.1 sub_project在我的主项目中集成为subtree

  1. 修改一个文件,然后从我的sub_project

  2. 中删除另一个文件
  3. 提交修改

  4. 浏览我的主项目

  5. 签出sub_project集成分支

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

  7. 查看我的主项目的master分支

  8. git diff-tree -p sub_project_branch表示一个文件已被修改,一个文件已被删除

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

  10. 以下是相应的命令:

    创建将用作子树的项目

    $ 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上提出了问题,但目前我没有答案。

0 个答案:

没有答案