合并提交不会出现在git rebase --interactive中

时间:2014-07-16 16:50:36

标签: git git-interactive-rebase

git log显示以下内容:

commit 1abcd[...]
Author: [...]
Date: [...]

    [Useful commit]

commit 2abcd[...]
Author: [...]
Date: [...]

    Merge branch [...] of [etc. etc.]

commit 3abcd[...]
Author: [...]
Date: [...]

    [Useful commit]

合并提交对我来说没用 - 它不代表分支的有意义状态并且是从远程拉动生成的,所以我有远程历史的真实提交 - 不需要提交来标记事实我拉了。我想压缩这个合并提交。我常用的壁球技术是:

git rebase --interactive HEAD~2(或者我需要走得很远)

然后我会把它压成邻居提交。我做了一些这样的事情,例如我做了一个提交,意识到我错过了一个很小的重要细节(单个文件,或者没有更改其中一个文件中的一行),并做了另一个提交,基本上只是一个快速的oops。这样,当我将我的更改推回到遥控器时,一切都很好,干净,并且讲述了一个有凝聚力的叙述。

但是,在这种情况下,当我运行git rebase ...命令时,不会出现提交2abcd!它似乎跳过2abcd,而是显示1abcd3abcd。合并提交有什么特别之处可以防止它出现在git rebase --interactive中吗?我可以用什么其他技术来压缩合并提交?

根据@ Cupcake的要求

更新

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

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

有用吗?

2 个答案:

答案 0 :(得分:32)

Rebase通常不会在没有--preserve-merges

的情况下保留合并提交

好的,所以我不确定如果你试图使用带有--preserve-merges的交互式rebase压缩合并提交会发生什么......但这就是我在你的情况下删除合并提交的方法让你的历史变得线性:

  1. 在远程分支顶部的合并提交之前重新启动所有内容。

  2. 在先前重新提交的提交之上,在合并提交之后挑选或修改所有内容。

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

    所以在命令方面,看起来像这样:

    # 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 
    

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

    # 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
    

    文档

答案 1 :(得分:2)

Git 提供了一种使用 --rebase-merges 的新方法:

在 --rebase-merges 之前,我遇到了 6 个与我的具体情况发生冲突的情况。

git rebase -i --rebase-merges origin/master

你可能会看到类似:

label onto

reset 4127388 # Formatting
pick 87da5b5 feat: add something
pick 8fcdff4 feat: add ..
merge -C 80784fe onto # Merge remote-tracking branch 'origin/master' into a-branch-name
pick 3d9fec7 add unit tests