合并提交不会出现在git rebase --interactive中 [英] Merge commits don't appear in git rebase --interactive

查看:152
本文介绍了合并提交不会出现在git rebase --interactive中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  commit 1abcd [。> git log  ..] 
作者:[...]
日期:[...]

[有用提交]

提交2abcd [..] 。]
作者:[...]
日期:[...]

[等]合并分支[...]等等]

提交3abcd [...]
作者:[...]
日期:[...]

[有用的提交]

合并提交对我无用 - 它并不代表分支的有意义状态并且是从远程拉取生成的,所以我有真正的远程历史提交 - 不需要承诺标记我拉出的事实。我想压缩这个合并提交。我常用的做一个壁球的方法是:
$ b $ g $ rebase --interactive HEAD〜2
我需要去)



然后我将它挤压到一个邻居提交中。如果例如我做了一个提交,意识到我错过了一个很小的重要细节(单个文件,或者没有更改其中一个文件中的一行),并且做了另一个基本上只是一个快速响应的提交,我会多次执行此操作。通过这种方式,当我将变更推回到遥控器时,所有内容都很干净,并且讲述了一个有凝聚力的叙述。 然而,在这种情况下,当我运行 git rebase ... 命令时,提交 2abcd 不会显示!它似乎跳过 2abcd ,而是显示 1abcd 3abcd 。有没有什么特别的合并提交可以防止它出现在 git rebase --interactive 中?

更新 per @ Cupcake的要求:


$ b可以使用其他技术来压缩合并提交吗? $ b

git log --graph --oneline --decorate 的输出如下所示:

  * 1abcd(有用的提交)
* 2abcd(合并)
| \< - 从远程
| * 3abcd(有用的提交)
| |

有帮助吗?

解决方案<如果没有 - preserve-merges

,Rebase通常不会保留合并提交好吧,所以我不确定会发生什么,如果你试图用 - preserve-merges 来压缩一个交互式rebase的合并提交,但这是我的方式删除您的案例中的合并提交,并使您的历史记录成为线性:



  1. 在合并提交之后,Cherry提取或重新绑定了之前重新提交的提交之前的所有内容。



如果在合并提交后只有1次提交



那么就命令而言,这个:
$ b

#在合并之前重置提交
git reset --hard< ;合并> ^

#重新绑定到th e远程分支
git rebase< remote> /< branch>

#樱桃挑选最后一次提交
git cherry-pick 1abcd



如果在合并提交后有超过1次提交



 #将一个临时分支在你当前的提交
git分支temp

#在合并提交之前重置提交
git reset --hard< merge> ^

#Rebase到远程分支上
git rebase< remote> /< branch>

#Cherry使用提交范围选择最后的提交。
#范围的开始是独占的(不包括在内)
git cherry-pick< merge> .. temp

#除了上面的樱桃选择,你可以而是将合并提交中的所有
#重新绑定到临时分支的顶端,然后重新绑定到其他
#新重新提交的提交。

#您也可以使用--preserve-merges来保留在
#之后的合并提交,这是您想要删除的第一个合并提交...但如果有
#这些合并提交中的任何冲突,您需要重新解决它们。
git rebase --preserve-merges --onto< currentBranch> <合并> temp

#这些后续步骤只有在您使用上面的rebase,
#而不是使用樱桃挑选范围时才需要。

#快进您的上一个分支并删除临时
git checkout< previousBranch>
git merge temp
git branch -d temp



Documentation




  • (1)手册页


    / ul>

    git log reveals the following:

    commit 1abcd[...]
    Author: [...]
    Date: [...]
    
        [Useful commit]
    
    commit 2abcd[...]
    Author: [...]
    Date: [...]
    
        Merge branch [...] of [etc. etc.]
    
    commit 3abcd[...]
    Author: [...]
    Date: [...]
    
        [Useful commit]
    

    That merge commit is useless to me - it doesn't represent a meaningful state of the branch and was generated from a remote pull, so I have the real commits of the remote history - no need for a commit to mark the fact that I pulled. I would like to squash this merge commit. My usual technique for doing a squash is:

    git rebase --interactive HEAD~2 (or however far back I need to go)

    And then I would squash it into a neighboring commit. I do this some times if for example I make a commit, realize I missed a tiny important detail (single file, or hadn't changed a line in one of the files), and do another commit that's basically just a quick oops. That way when I push my changes back to the remote, everything is nice and clean and tells a cohesive narrative.

    However, in this case, when I run the git rebase ... command, commit 2abcd doesn't appear! It seems to skip right over 2abcd and instead displays 1abcd and 3abcd. Is there something special about a merge commit that prevents it from being appearing in git rebase --interactive? What other technique could I use to squash that merge commit?

    UPDATE per @Cupcake's request:

    The output of git log --graph --oneline --decorate looks like this:

    * 1abcd (useful commit)
    * 2abcd (merge)
    |  \ <-- from remote
    |   * 3abcd (useful commit)
    |   |
    

    Helpful?

    解决方案

    Rebase doesn't normally preserve merge commits without --preserve-merges

    Ok, so I'm not exactly sure what would happen if you tried to squash a merge commit using an interactive rebase with --preserve-merges...but this is how I would remove the merge commit in your case and make your history linear:

    1. Rebase everything before the merge commit on top of the remote branch.

    2. Cherry-pick or rebase everything after the merge commit on top of the previously rebased commits.

    If you only have 1 commit after the merge commit

    So in terms of commands, that would look something like this:

    # Reset to commit before merge commit
    git reset --hard <merge>^
    
    # Rebase onto the remote branch
    git rebase <remote>/<branch>
    
    # Cherry-pick the last commit
    git cherry-pick 1abcd 
    

    If you have more than 1 commit after the merge commit

    # Leave a temporary branch at your current commit
    git branch temp
    
    # Reset to commit before merge commit
    git reset --hard <merge>^
    
    # Rebase onto the remote branch
    git rebase <remote>/<branch>
    
    # Cherry-pick the last commits using a commit range.
    # The start of the range is exclusive (not included)
    git cherry-pick <merge>..temp
    
    # Alternatively to the cherry-pick above, you can instead rebase everything
    # from the merge commit to the tip of the temp branch onto the other
    # newly rebased commits.
    #
    # You can also use --preserve-merges to preserve merge commits following
    # the first merge commit that you want to get rid of...but if there were
    # any conflicts in those merge commits, you'll need to re-resolve them again.
    git rebase --preserve-merges --onto <currentBranch> <merge> temp
    
    # These next steps are only necessary if you did the rebase above,
    # instead of using the cherry-pick range.
    #
    # Fast-forward your previous branch and delete temp
    git checkout <previousBranch>
    git merge temp
    git branch -d temp
    

    Documentation

    这篇关于合并提交不会出现在git rebase --interactive中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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