重做之后,Git提交在同一分支中被复制 [英] Git commits are duplicated in the same branch after doing a rebase

查看:87
本文介绍了重做之后,Git提交在同一分支中被复制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解Pro Git中提供的有关 git rebase 。作者基本上告诉你如何避免重复提交:


不要重新提交已推送到公共存储库的提交。


我会告诉你我的具体情况,因为我认为它不完全适合Pro Git场景,而且我仍然会重复提交。 / p>

假设我有两个远程分支机构和他们的本地分支机构:

 原产地/主产地/开发商
| |
master dev

所有四个分支都包含相同的提交,我将开始开发 dev

  origin / master:C1 C2 C3 C4 
主人:C1 C2 C3 C4

原产地/ dev:C1 C2 C3 C4
dev:C1 C2 C3 C4

经过几次提交后,我将更改推送到 origin / dev

 原点/主点:C1 C2 C3 C4 
主点:C1 C2 C3 C4

原点/ dev:C1 C2 C3 C4 C5 C6# (2)git push
dev:C1 C2 C3 C4 C5 C6#(1)git checkout dev,git commit

我必须回到 master 才能快速解决问题:

  origin / master:C1 C2 C3 C4 C7#(2)git push 
master:C1 C2 C3 C4 C7#(1)git checkout master,git commit

原产地/ dev:C1 C2 C3 C4 C5 C6
dev:C1 C2 C3 C4 C5 C6

返回到 dev 我将这些更改重新包含在我的实际开发中的快速修复中:

  origin / master:C1 C2 C3 C4 C7 
master:C1 C2 C3 C4 C7

origin / dev:C1 C2 C3 C4 C5 C6
dev:C1 C2 C3 C4 C7 C5'C6'#git checkout dev,git rebase master

如果我显示提交GitX / gitk的历史记录,我注意到 origin / dev 现在包含两个相同的提交 C5' C6',它们与Git不同。现在,如果我将更改推送到 origin / dev ,结果如下:

  origin / master:C1 C2 C3 C4 C7 
master:C1 C2 C3 C4 C7

origin / dev:C1 C2 C3 C4 C5 C6 C7 C5'C6'#git push
dev:C1 C2 C3 C4 C7 C5'C6'

也许我不完全理解在Pro Git中的解释,所以我想知道两件事:


  1. 为什么Git在重新绑定时重复这些提交?是否有特殊原因这样做,而不是在 C7 之后应用 C5 C6 / code>?

  2. 我该如何避免这种情况?这是明智的做法吗?
  3. 简单的合并就足够了。你链接的Pro Git书基本上解释了这种确切的情况。内部工作原理可能略有不同,但以下是我想象它的方式:


    • C5 C6 暂时从开发

    • C7 应用于 dev

    • C5 C7 之上播放c>和 C6 ,创建新的差异并因此创建新的提交


    • $ b因此,在你的 dev 分支中, C5 C6 实际上不再存在:它们现在是 C5' C6'。当你推到 origin / dev 时,git会看到 C5' C6'作为新提交并将它们粘贴到历史记录的末尾。事实上,如果你看看 origin / dev 中的 C5 C5' / code>,你会注意到尽管内容是相同的,行号可能不同 - 这使得提交的哈希值不同。



      我会重申Pro Git规则:永远不要重新提交曾经存在于本地存储库以外的提交。改用合并。


      I understand the scenario presented in Pro Git about the risks of git rebase. The author basically tells you how to avoid duplicated commits:

      Do not rebase commits that you have pushed to a public repository.

      I am going to tell you my particular situation because I think it does not exactly fit the Pro Git scenario and I still end up with duplicated commits.

      Let's say I have two remote branches with their local counterparts:

      origin/master    origin/dev
      |                |
      master           dev
      

      All four branches contains the same commits and I am going to start development in dev:

      origin/master : C1 C2 C3 C4
      master        : C1 C2 C3 C4
      
      origin/dev    : C1 C2 C3 C4
      dev           : C1 C2 C3 C4
      

      After a couple of commits I push the changes to origin/dev:

      origin/master : C1 C2 C3 C4
      master        : C1 C2 C3 C4
      
      origin/dev    : C1 C2 C3 C4 C5 C6  # (2) git push
      dev           : C1 C2 C3 C4 C5 C6  # (1) git checkout dev, git commit
      

      I have to go back to master to make a quick fix:

      origin/master : C1 C2 C3 C4 C7  # (2) git push
      master        : C1 C2 C3 C4 C7  # (1) git checkout master, git commit
      
      origin/dev    : C1 C2 C3 C4 C5 C6
      dev           : C1 C2 C3 C4 C5 C6
      

      And back to dev I rebase the changes to include the quick fix in my actual development:

      origin/master : C1 C2 C3 C4 C7
      master        : C1 C2 C3 C4 C7
      
      origin/dev    : C1 C2 C3 C4 C5 C6
      dev           : C1 C2 C3 C4 C7 C5' C6'  # git checkout dev, git rebase master
      

      If I display the history of commits with GitX/gitk I notice that origin/dev now contains two identical commits C5' and C6' which are different to Git. Now if I push the changes to origin/dev this is the result:

      origin/master : C1 C2 C3 C4 C7
      master        : C1 C2 C3 C4 C7
      
      origin/dev    : C1 C2 C3 C4 C5 C6 C7 C5' C6'  # git push
      dev           : C1 C2 C3 C4 C7 C5' C6'
      

      Maybe I don't fully understand the explanation in Pro Git, so I would like to know two things:

      1. Why does Git duplicate these commits while rebasing? Is there a particular reason to do that instead of just applying C5 and C6 after C7?
      2. How can I avoid that? Would it be wise to do it?

      解决方案

      You should not be using rebase here, a simple merge will suffice. The Pro Git book that you linked basically explains this exact situation. The inner workings might be slightly different, but here's how I visualize it:

      • C5 and C6 are temporarily pulled out of dev
      • C7 is applied to dev
      • C5 and C6 are played back on top of C7, creating new diffs and therefore new commits

      So, in your dev branch, C5 and C6 effectively no longer exist: they are now C5' and C6'. When you push to origin/dev, git sees C5' and C6' as new commits and tacks them on to the end of the history. Indeed, if you look at the differences between C5 and C5' in origin/dev, you'll notice that though the content is the same, the line numbers are probably different -- which makes the hash of the commit different.

      I'll restate the Pro Git rule: never rebase commits that have ever existed anywhere but your local repository. Use merge instead.

      这篇关于重做之后,Git提交在同一分支中被复制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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