本文介绍了Git合并删除文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

It's the second time this happens, when I'm doing a merge I later realized some files that were in the branch being merged are no longer in the branch being merged to.

最近的示例是我们有一个功能分支,我一直在合并主dev分支中的更改,合并后丢失了很多文件,现在这些文件不存在于功能分支中.

The latest example is we have a feature branch which I've been merging the changes in from the main dev branch, we lost a lot of files after a merge and they are not present in the feature branch now.

  1. 为什么会这样?
  2. 获取这些文件的最佳方法是什么?我正在考虑手动添加它们.

以下是文件丢失时回购的说明:

here is a description of the repo when the files were lost:

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

964495c is where the files were lost, it is a merge of the remote branch with a local branch.d1c457a is a merge from the main dev branch into the feature branch.

当我对这两个分支进行比较时,我看到丢失的文件被删除了,但是它们从未设置为删除.这不是我的合并,因此我不确定是否是用户错误,但是我需要找出在功能分支中包含这些文件的最佳方法...

When I do a diff of these two branches I see the files I have lost as being removed, but they were never set to remove. This wasn't my merge so I'm not sure if it was user error, but I need to figure out the best way to include these files in my feature branch...

推荐答案

第1部分的答案

我在这里没有足够的信息来告诉您发生了什么 ...但是下面是如何查看应该发生(或已经发生)的信息的方法 git merge ... .从上图可以看到, 964495c 是一个合并,如果其父提交是 d1c457a (黄色的点和线),则是一个合并.我们看不到它的另一个父提交-另一个父在紫色线的另一端.(我想其中一行是分支 dev ,另一行是分支 feature .)

An answer to part 1

I don't have enough information here to tell you what did happen ... but here is how to see what should happen (or have happened), on a git merge .... We can see from the image above that 964495c is a merge and one if its parent commits is d1c457a (the yellow dot and line). We cannot see its other parent commit—the other parent is down the other end of the purple line. (One line is, I imagine, branch dev and the other is branch feature.)

[ [ [每个注释,这是 8967ae7 ...

Now, using the two commit IDs produced above, find the merge-base. Per comment, this is 8967ae7...

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

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

You now have three commit IDs. Let's re-do the above with shell variables, since the symbolic names might help:

$ id_into=$(git rev-parse 964495c^1)
$ id_from=$(git rev-parse 964495c^2)
$ id_base=$(git merge-base $id_into $id_from)

现在的shell变量 $ id_base $ id_from $ id_into 包含合并基础的提交ID,即合并的分支, 1 和提交的ID恰好在 964495c 本身之前(合并时分支 feature 的原始提示)完成).

Now shell variables $id_base, $id_from, and $id_into hold the commit ID of the merge-base, the tip of the branch being merged-from,1 and the ID of the commit just before 964495c itself (the original tip of branch feature when the merge was being done).

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

Using these, we can see what git merge is asked to merge, by doing two git diffs. (The next bit assumes Unix/Linux/Mac shell redirection.)

$ git diff -M50% $id_base $id_into > /tmp/existing_changes
$ git diff -M50% $id_base $id_from > /tmp/new_changes

第一个差异发现由于另一个分支 dev 偏离了该分支,该分支上发生了什么,即 feature ".第二个差异发现自另一个分支 dev 离开该分支以来,发生了什么事情,即 feature ".

The first diff finds out "what has happened on this branch, i.e., feature since the other branch dev diverged from it". The second diff finds out "what has happened on the other branch dev since it diverged from this branch, i.e., feature".

然后, merge 命令尝试将两者合并. dev 发生任何更改的地方:

The merge command then attempts to combine these two. Wherever dev has any change:

  • 如果更改是添加新文件,请添加新文件(除非 feature 也添加了它:否则我们可能有冲突,需要手动解决)
  • 如果更改是要重命名文件,请重命名文件(同样,除非 feature 已经拥有文件)
  • 如果更改是要删除文件,请删除文件
  • 如果更改是要添加或删除文件中的某些行,请在此处执行此操作(除非 feature 已具有该行,在这种情况下,请忽略更改;或者如果我们找不到这些更改确切的行具有相同的内容,那么我们就会发生冲突-这种冲突情况包括在 feature 中删除文件的情况).
  • if the change is to add a new file, add the new file (unless feature has also added it: then we probably have a conflict that requires manual resolution)
  • if the change is to rename a file, rename the file (again unless feature has it already)
  • if the change is to remove a file, remove the file
  • if the change is to add or remove some lines from a file, do that here (unless feature has it already, in which case, ignore the change; or if we can't find those exact lines with the same contents, then we have a conflict—this conflict case includes the case where the file was removed in feature).

我已经加粗了 git merge 应该删除文件的情况.如果merge-from分支( dev )自合并基础以来删除了该文件,则 git merge 将悄悄地从合并结果中删除该文件.

I have bolded the case where git merge should remove a file. If the merge-from branch (dev) removed that file since the merge-base, git merge will quietly remove the file from the merge result.

现在,尽管如此,如果执行合并的任何人都使用-no-commit ,或者如果发生冲突,则合并将在执行所有操作后停止,无论执行者是谁合并有机会进行其他更改.在合并冲突的情况下,这当然是进行合并的人必须解决冲突的地方.但是,即使没有冲突,进行合并的人员也可以使用-no-commit 到达此处.无论如何,此时,执行合并的人员可以删除文件,添加文件和修改文件.当他(或她)(好吧,让我们使用"they" :-))……完成后,他们 git commit 结果,然后提交 964495c ... .

Now, with all that said, if whoever is doing the merge uses --no-commit, or if there is a conflict, the merge stops after doing whatever it can, and whoever is doing the merge has a chance to make additional changes. In the case of merge conflicts, this is of course where the person doing the merge must resolve the conflicts. However, the person doing the merge can use --no-commit to get here even without conflicts. In any case, at this point, the person doing the merge can remove files, add files, and modify files. When he or she (ok, let's use "they" :-) ) ... when they are done, they git commit the result, and that made commit 964495c....

1 至少,这就是当时 dev 的提示: dev 从那时起可能有所增长,就像从那时起,功能实际上已经发展起来.

1At least, it's what was the tip of dev at the time: dev might have grown a bit since then, just as feature has in fact grown since then.

不一定没有最好的方法来找回丢失的文件,但是很容易从特定的提交中检出文件.此处最明显的一个使用方法是 29a7b67 (即上面的 $ id_from ,是进行合并的人进行合并时 feature 的提示):

There is not necessarily a single best way to get the missing files back, but it's easy to check out files from a particular commit. Here the obvious one to use is 29a7b67 (aka $id_from above, the tip of feature when whoever did the merge, did the merge):

$ git checkout 29a7b67 -- path/to/file

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

(List multiple files, or one or more directories, to get more files, or every file in the directory, out of that commit-ID.) This puts the files into the work-tree and the index, as of the state they were in at that commit-ID, so that the next git commit will include them in that state.

(您当然可以对其进行编辑,并在需要时进行 git add 结果进行更改.)

(You can of course edit them and git add the result to make changes if needed.)

这篇关于Git合并删除文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-04 20:13