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

NWa*_*ard 25 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]
Run Code Online (Sandbox Code Playgroud)

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

git rebase --interactive HEAD~2 (或者我需要去的远方)

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

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

UPDATE每@蛋糕的要求:

输出git log --graph --oneline --decorate看起来像这样:

* 1abcd (useful commit)
* 2abcd (merge)
|  \ <-- from remote
|   * 3abcd (useful commit)
|   |
Run Code Online (Sandbox Code Playgroud)

有用吗?

小智 31

Rebase通常不会保留合并提交 --preserve-merges

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

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

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

如果在合并提交后只有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 
Run Code Online (Sandbox Code Playgroud)

如果在合并提交后有超过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
Run Code Online (Sandbox Code Playgroud)

文档

  • (注:Git 2.22,2019 年第二季度,实际上[弃用](https://github.com/git/git/commit/fa1b86e45743fd5895c33adcd3769782e608bb40) `--preserve-merge` 转而使用 `--rebase-merges`,以及 Git 2.25,2020 年第一季度,[停止对其进行广告](https://github.com/git/git/commit/0c51181ffb178a6581ecb471091cbd2d0c48f165) 在“git rebase --help”输出中) (4认同)

Het*_*mei 23

Git 提供了一种新方法--rebase-merges

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

git rebase -i --rebase-merges origin/master
Run Code Online (Sandbox Code Playgroud)

你可能会看到类似的东西:

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
Run Code Online (Sandbox Code Playgroud)