Git合并删除文件

时间:2014-08-28 18:31:36

标签: git github version-control merge

这是第二次发生这种情况,当我进行合并时,我后来意识到合并的分支中的某些文件不再在合并的分支中。

最新的例子是我们有一个功能分支,我已经合并了主dev分支的变化,我们在合并后丢失了很多文件,现在它们不在功能分支中。< / p>

  1. 为什么会这样?
  2. 获取这些文件的最佳方法是什么?我想手动添加它们。
  3. 这里是文件丢失时的回购说明:

    964495c是文件丢失的地方,它是远程分支与本地分支的合并。 d1c457a是从主dev分支到功能分支的合并。

    当我对这两个分支做差异时,我看到我丢失的文件被删除了,但它们从未设置为删除。这不是我的合并,所以我不确定是否是用户错误,但我需要弄清楚将这些文件包含在我的功能分支中的最佳方式......

    enter image description here

1 个答案:

答案 0 :(得分:3)

第1部分的答案

我在这里没有足够的信息告诉你发生了什么 ...但是这里是如何看待应该发生的事情(或者已经发生过) ,在git merge ...上。我们可以从上图中看到964495c是一个合并,如果它的父提交是d1c457a(黄点和线),则为1。我们看不到它的另一个父提交 - 另一个父提出了紫色线的另一端。 (我想,一行是分支dev,另一行是分支feature。)

[修改:每条评论,第一位父级是29a7b67(位于分支feature上),第二位是d1c457a(位于分支{{1}正如预期的那样。)

dev做的第一件事是找到&#34;合并基地&#34;。因此,在shell命令窗口中,找到两个父ID:

git merge

(我在这里部分猜测,基于颜色,$ git rev-parse 964495c^1 29a7b67... $ git rev-parse 964495c^2 d1c457a... 是第二父母,即合并的东西,而不是合并到的东西它太重要了,合并结果应该是相同的两种方式。) [编辑:已确认]

现在,使用上面生成的两个提交ID,找到merge-base。 为简单起见,我假设第一个命令产生d1c457a 每条评论,这是1234567...

8967ae7...

您现在有三个提交ID。让我们使用shell变量重新执行上述操作,只是为了让我不再需要猜测commit-IDs ,因为符号名称可能会有所帮助:

$ git merge-base 29a7b67 d1c457a
8967ae7...

现在,shell变量$ id_into=$(git rev-parse 964495c^1) $ id_from=$(git rev-parse 964495c^2) $ id_base=$(git merge-base $id_into $id_from) $id_base$id_from保存了merge-base的提交ID,分支的提示被合并, 1 $id_into本身之前的提交ID(合并完成时分支964495c的原始提示)。

使用这些,我们可以通过执行两个feature来查看要求合并git merge的内容。 (下一位假定Unix / Linux / Mac shell重定向。)

git diff

第一个差异发现&#34;在这个分支上发生了什么,即$ git diff -M50% $id_base $id_into > /tmp/existing_changes $ git diff -M50% $id_base $id_from > /tmp/new_changes ,因为另一个分支feature与它分开了#34;。第二个差异发现&#34;另一个分支dev发生了什么,因为它偏离了这个分支,即dev&#34;。

feature命令然后尝试将这两者结合起来。 merge有任何变化的地方:

  • 如果要更改是添加新文件,请添加新文件(除非dev也添加了它:那么我们可能存在需要手动解决的冲突)
  • 如果更改是重命名文件,请重命名该文件(除非feature已将其重命名)
  • 如果要删除文件,请删除文件
  • 如果更改是要添加或删除文件中的某些行,请在此处执行此操作(除非feature已经存在,否则请忽略此更改;或者如果我们无法找到这些更改如果内容相同,那么我们就会发生冲突 - 这种冲突案例包括feature中删除文件的情况。

我已经加粗了feature 应该删除文件的情况。如果merge-from分支(git merge)从合并库中删除了该文件,dev将从合并结果中悄悄地删除该文件。


现在,尽管如此,如果正在进行合并的人使用git merge,或者如果存在冲突,则合并会在执行任何操作后停止,并且合并的任何人都有机会进行合并其他更改。在合并冲突的情况下,这当然是进行合并的人必须解决冲突的地方。但是,进行合并的人可以使用--no-commit即使没有冲突也可以到达此处。在任何情况下,此时,执行合并的人可以删除文件,添加文件和修改文件。当他或她(好吧,让他们使用&#34;他们&#34; :-))......完成后,他们--no-commit结果,并且提交了{{1} }。


1 至少,当时git commit的提示是什么:964495c...此后可能会有所增长,就像{dev一样事实上,1}}从那时起已经成长。

第2部分的答案

没有一种最好的方法可以恢复丢失的文件,但是从特定的提交中检出文件很容易。这里使用的显而易见的是dev(上面的feature29a7b67的提示,当合并的任何人进行合并时:{/ p>

$id_from

(列出多个文件,或一个或多个目录,以从该commit-ID中获取更多文件或目录中的每个文件。)这会将文件放入工作树索引,从它们在该commit-ID处的状态开始,以便下一个feature将它们包含在该状态中。

(您当然可以编辑它们并$ git checkout 29a7b67 -- path/to/file 结果以根据需要进行更改。)