合并后为什么GIT会说“已经最新”,但分支之间的差异仍然存在? [英] Why after merge does GIT say "Already up-to-date", but differences between branches still exist?

查看:253
本文介绍了合并后为什么GIT会说“已经最新”,但分支之间的差异仍然存在?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最初在'newfeature'分部工作,并且我被要求紧急地修复live分支上的错误。我创建了一个名为'generalmaintenance'的分支,完成了这项工作,然后转而开发并合并了它。现在我想返回到'newfeature'分支并合并早期合并到其中的更改。



当我切换到'newfeature'并在'develop'中合并时,3个文件中出现冲突。



解决冲突并最终决定使用Aptana Studio 3(这是我的IDE)的团队菜单中的恢复命令。我预计这会让我回到合并之前,似乎已经完成了。



无论如何,当我再次合并开发时,它说 Already-to-date ,但是当比较两个分支之间的文件时,它们是非常不同的,我在另一个分支中添加的更改没有被合并。



现在我将如何合并两个分支? 恢复合并与重置合并



我的猜测是您实际上 Already-up-to -date



问题在于 git revert 不会撤消合并,只会解除合并带来的更改。当您创建合并提交时,您将合并这两个分支的提交历史记录。



合并

 开发
|
A --- B --- C
\\
E --- F --- M
|
newfeature

在上面的例子中, develop 合并到 newfeature 中,创建 M 提交。如果你运行 git log newfeature ,你会看到两个分支的所有提交,但是从 newfeature 分支,所有这些更改均由 M 提交执行。



还原



git revert 命令不会删除任何提交,而是会创建一个新的提交以撤销提交的更改遏制。例如,如果你有一个包含这个差异的提交...

   - 这是旧的句子。 
+这是新的句子。

然后恢复它,revert命令将创建一个新的提交,它只是执行相反的diff,它只是翻转标志。

   - 这是新的句子。 
+这是旧的句子。

这对于消除其他开发人员已提交的提交造成的损害非常有用。它向前移动历史而不是改变历史。 b
$ b

还原合并 然而,在非快速合并的情况下它可能会有不良影响。

  develop 
|
A --- B --- C
\\
E --- F --- M --- W
|
newfeature

假设W是一个返回提交,您可以看到 git log newfeature 仍然包含develop分支的所有提交。因此,从开发的额外合并将无法正常工作,因为它没有看到分支中遗漏的任何内容。



改为使用 git reset 未来,您可能需要考虑使用 git reset --hard< ref> c $ c>(其中< ref> 是合并的提交哈希)如果合并未与其他开发人员共享,则撤销合并。在上面的例子中,在创建合并提交 M 之后,运行命令 git reset --hard F 会导致以下。

  develop 
|
A --- B --- C
\\
E --- F --- M
|
newfeature

正如您所看到的,这种技术并不会消除提交,因为有些人倾向于想想,它只是将您的分支移回您选择的提交。现在如果你运行 git log newfeature ,你只会得到提交 F E A 。现在合并实际上已经从你的分支历史中消失了,所以稍后在开发时重新合并的尝试将不会导致任何问题。



这种方法并非没有其复杂性。意识到您现在正在修改历史记录,因此如果 newfeature 分支在 M 合并之后被推送到远程分支那么git会认为你已经过时了,并告诉你需要运行 git pull 。如果只是你在那个远程分支上工作,那么随意 force-push - git push -f< remote> <分支> 。这将会产生与重置相同的效果,但在远程分支上。



如果多个开发人员正在使用此分支,那么这是一个坏主意。这就是 git revert 非常有用的原因,因为它可以在不改变实际历史的情况下撤消更改。



使用reset关于历史是真正的只有在没有共享的提交选项。

解决方案 - 恢复还原。

被共享,那么最好的方法可能是在该合并中使用 git revert 。但是,正如我们之前所说的那样,您不能再简单地将分支合并回来,并期望来自该分支的所有更改重新出现。答案是恢复恢复提交。

假设你在开发分支中完成了一些工作, newfeature 。你的历史看起来像这样。

  develop 
|
A --- B --- C --- D
\\
E --- F --- M --- W
|
newfeature

如果合并 develop 变成 newfeature 现在,您只会得到 D ,因为它是唯一不属于历史记录的提交 newfeature 分支。你还需要做的是恢复 W commit - git revert W 应该执行后面跟着 git merge develop

  develop 
|
A --- B --- C ----------- D
\ \ \
E --- F --- M-- -W --- M --- G
|
newfeature

这会恢复原始合并提交所做的所有更改 - 由 C B 但已在 W 中恢复,它然后通过新的合并提交 G 引入 D >我会建议在之前还原合并最近对 develop 的更改,我怀疑按顺序执行触发冲突的可能性较低。



< TL> DR



恢复会创建'恢复提交'。撤销还原时,需要对第一次还原时创建的还原提交运行还原命令。应该很容易找到,git倾向于自动评论回复,以便他们以Reverted一词开始。

git revert < commit>


I was originally working in 'newfeature' branch and I was called to fix a bug on the live branch urgently. I created a branch for that called 'generalmaintenance', did the job and then switched to develop and merged it in. I now want to return to 'newfeature' branch and to merge in the changes that I merged into it earlier.

When I switched to 'newfeature' and merged in 'develop', there were conflicts in 3 files.

I got in a tangle resolving the conflicts and eventually decided to use the "Revert" command in the 'Team' menu of Aptana Studio 3 (which is my IDE). I expected this to roll me back to before the merge, which it appears to have done.

Anyway, when I merge in 'develop' again, it says, Already-up-to-date, but when comparing files between the two branches, they are very different and the changes I added in the other branch are not being merged in.

How will I merge the two branches now please?

解决方案

Reverting Merges vs. Resetting Merges

My guess is that you actually are Already-up-to-date.

The problem is that git revert doesn't undo the merge, it only undoes the changes that the merge brought with it. When you create a merge commit, your combining the commit histories of those two branches.

Merging

     develop
        |
A---B---C
 \       \
  E---F---M
          |
      newfeature

In the case above, develop is merged into newfeature, creating the M commit. If you were to run git log newfeature you would see all the commits from both branches, however from the perspective of the newfeature branch, all those changes were performed by the M commit.

Reverting

The git revert command does not remove any commits, instead it creates a new commit that undoes the changes that the commit contained. For example if you had a commit containing this diff...

-This is the old sentence.
+This is ne new sentence.

Then reverted this, the revert command would create a new commit that just preformed the opposite diff, it simply flips the signs.

-This is ne new sentence.
+This is the old sentence.

This is really useful for undoing damage caused by commits that other developers already have. It moves history forward rather than changing history.

Reverting Merges

However, in the context of a non-fastforward merge it may have an undesired effect.

     develop
        |
A---B---C
 \       \
  E---F---M---W
              |
         newfeature

Assuming W is a reversion commit, you can see how running git log newfeature will still include all the commits from the develop branch. As a result, additional merges from develop will no work, because it doesn't see anything missing from your branch.

Using git reset instead of revert.

In the future, you might want to consider using git reset --hard <ref> (where <ref> is the commit hash of the merge) to undo a merge if that merge has not been shared with other developers. In the example above, after having created merge commit M, running the command git reset --hard F would result in the following.

     develop
        |
A---B---C
 \       \
  E---F---M
      |
  newfeature

As you can see this technique doesn't obliterate the commit as some people tend to think, it simply moves your branch back to the commit you selected. Now if you ran git log newfeature you would only get commit F, E, and A. Now the merge is actually gone from your branches history, so a later attempts to re-merge in develop will cause no problems.

This method is not without its complications. Realize that you are now modifying history, so if the newfeature branch was pushed to a remote branch after the M merge was made, then git is going to think you are simply out of date and tell you that you need to run git pull. If its just you working on that remote branch, then feel free to force-push - git push -f <remote> <branch>. This will have the same effect of the reset but on the remote branch.

If this branch is being used by multiple developers, who would have by now already pulled from it - then this is a bad idea. This is the very reason git revert is useful, because it undoes changes without changing the actual history.

Using reset on history is really only on option for commits that have not been shared.

The solution - reverting the reversion.

If the merge commit has already been shared, then the best approach is probably to use git revert on that merge. However as we said before, you can not then simply merge the branch back in and expect all the changes from that branch to re-appear. The answer is to revert the revert commit.

Lets say you did some work on the develop branch after having revered the merge in newfeature. Your history would look something like this.

         develop
            |
A---B---C---D
 \       \
  E---F---M---W
              |
         newfeature

If you merge develop into newfeature now, you would only get D because its the only commit that is not already part of the history of the newfeature branch. What you also need to do is revert that W commit - git revert W should do the trick followed by git merge develop.

                 develop
                    |
A---B---C-----------D
 \       \           \
  E---F---M---W---M---G
                      |
                 newfeature

This restores all the changes made by the original merge commit - which were actually made by C and B but were reverted in W, it then brings in D via a new merge commit G I would recommend reverting the revert before merging in the recent changes to develop, I suspect doing it in that order will have a lower chance of triggering conflicts.

TL;DR

Reverting creates a 'revert commit'. When undoing a revert, you need to run the revert command on the revert commit that was created when you reverted the first time. It should be easy enough to find, git tends to auto-comment on reverts so that they start with the word "Reverted".

git revert <commit>

这篇关于合并后为什么GIT会说“已经最新”,但分支之间的差异仍然存在?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆