混帐合并:删除我想保留的文件!

你怎么能合并两个分支在git,从分支保留必要的文件?

合并两个分支时,如果文件在一个分支中被删除,而在另一个分支中被删除,则该文件最终被删除。

例如:

  • 在创build新分支时,文件存在于主文件中
  • 你从主文件中删除文件,因为我们不需要它(还)
  • 您在分支中进行更改以添加依赖于现有文件的function
  • 你在master中修正错误 (不能被丢弃)
  • 你有一天合并,文件不见了!

如何重现:

  1. 用一个文件创build一个git仓库。

    git init echo "test" > test.txt git add . git commit -m "initial commit" 
  2. 创build一个分支

     git branch branchA 
  3. 删除主文件

     git rm test.txt git commit -m "removed file from master" 
  4. 在branchA中进行任何不会触及已删除文件的更改(必须保持不变以避免冲突)

     git checkout branchA touch something.txt git add . git commit -m "some branch changes" 

从这里,我发现合并这两个分支的任何方式,test.txt文件被删除。 假设我们依赖于 branchA 的文件 ,这是一个大问题。


失败的例子:

合并1

 git checkout branchA git merge master ls test.txt 

合并2

 git checkout master git merge branchA ls test.txt 

Rebase 1

 git checkout branchA git rebase master ls test.txt 

这是一个有趣的问题。 因为您在创buildBranchA之后删除了该文件,然后将master合并到BranchA ,所以我不确定Git如何能够意识到存在冲突。

错误的合并后,你可以撤消,然后重新合并,但是加回文件:

 git checkout HEAD@{1} . git merge --no-commit master git checkout master test.txt git add test.txt git commit 

为了在这种情况下快速修复,“git恢复”删除文件的提交。

当将来出现这种情况时,更好的方法是确保在分支上创build新文件。 然后在你合并的时候把它添加到主文件夹上,但是同时你没有在主文件夹中的文件。

您需要修改分支中的文件,以便与中继中的删除存在合并冲突。

例如,如果删除了trunk中头文件中的某个东西的声明(因为没有东西需要它),并且将该声明的依赖项添加到分支中的某个非头文件中,则会发生完全相同的事情。 当你合并时,由于分支不接触标题的(部分),它只会删除声明,事情就会中断。

每当你在多个相互依赖的地方都需要保持同步的东西时,合并就很容易引起问题。 它只是你必须知道的事情之一,并检查合并。 理想情况下,您使用编译时断言或其他构build时间检查,这将使任何故障立即显现。

凯西的例子没有为我的情况工作 – 我不能从master签出test.txt ,因为它不再在该分支:

 $ git checkout master test.txt error: pathspec 'test.txt' did not match any file(s) known to git. 

很高兴我可以把这个文件从branchA自己的HEAD文件中取出来:

 $ git checkout branchA $ git merge --no-commit master $ git checkout HEAD test.txt $ git add test.txt $ git commit 

我的解决scheme是简单地修改我需要保留的文件(无论如何都需要添加一个注释)并在目标分支上提交这些更改,从而生成一个合并冲突,可以使用git add和normal commit 。

我的历史就是这样的。 分支名称已经改变,以保护无辜者。

  1. 创build并提交新的function文件来掌握
  2. 意识到这个增加将比原计划更加牵涉,从而分支到feature_branch
  3. 从主服务器删除文件,以免中断正常的工作stream和RB等
  4. 时间stream逝,更多的承诺主人,没有在feature_branch
  5. 继续工作的function, git merge master feature_branch导致原始文件被删除(当然), git reset --hard到合并前
  6. 应用上述解决scheme