如何在分支的第一个(根)提交上使用交互式rebase?

时间:2015-05-16 14:57:34

标签: git rebase squash

如果我遇到以下情况,

$ git log --oneline
* abcdef commit #b
* 123456 commit #a

我知道我总能跑

$ git reset HEAD~ 
$ git commit --amend

但是,我试图运行

$ git rebase -i HEAD~2

但我得到了

fatal: Needed a single revision
invalid upstream HEAD~2

因此我的问题是:有没有办法使用git rebase来压缩这两个提交?

3 个答案:

答案 0 :(得分:27)

您想要重新绑定到master分支的根提交。更具体地说,要压缩两个提交,您需要运行

git rebase -i --root

然后将squash替换为弹出的编辑器缓冲区中第二行的pick

pick 123456 a                                                        
squash abcdef b

我将您推荐到git-rebase man page以获取有关该标志的更多详细信息:

  

--root

     

重新启动所有可从<branch>到达的提交   限制他们<upstream>。这允许你变基   分支上的根提交。 [...]

的交互式rebase示例
# Set things up
$ mkdir testgit
$ cd testgit
$ git init

# Make two commits
$ touch README
$ git add README
$ git commit -m "add README"
$ printf "foo\n" > README
$ git commit -am "write 'foo' in README"

# Inspect the log
$ git log --oneline --decorate --graph
* 815b6ca (HEAD -> master) write 'foo' in README
* 630ede6 add README

# Rebase (interactively) the root of the current branch: 
# - Substitute 'squash' for 'pick' on the second line; save and quit the editor.
# - Then write the commit message of the resulting commit; save and quit the editor.
$ git rebase -i --root
[detached HEAD c9003cd] add README; write 'foo' in README
 Date: Sat May 16 17:38:43 2015 +0100
 1 file changed, 1 insertion(+)
 create mode 100644 README
Successfully rebased and updated refs/heads/master.

# Inspect the log again
$ git log --oneline --decorate --graph
* c9003cd (HEAD -> master) add README; write 'foo' in README

答案 1 :(得分:8)

看来这个参数可能会有所帮助:

volatile
     

重新启动从&lt; branch&gt;到达的所有提交,而不是用&lt; upstream&gt;限制它们。这允许您重新定义根   在一个分支上提交。

这应该让你压扁(我猜你真的想要修复)你的第二次提交到第一次:

--root 

请注意了解--root选项的用途,因为在您的情况下它会满足您的需求,但在分支中使用时可能会很棘手,因为它会重新定位到历史中可以到达的最远的祖先(即。树的根);因此git rebase --root -i 会在rebase --rootz上重新a

A-B-D-E-X-Y-Z

答案 2 :(得分:1)

我来到这个问题,寻找标题的答案。在一个很大的仓库上,被接受的答案会为主分支(又称:master)中的每个提交产生一个交互式的基础,而不是给定分支的 just 。对于来这里的其他人,替代方法是使用父分支名称(或提交):

git rebase -i <base_branch_name>

在git文档中找到并找到(https://git-scm.com/docs/git-rebase#_interactive_mode)后,我意识到了这一点:

从您要原样保留的最后一次提交开始:

git rebase -i <after-this-commit>

将使用所有提交触发一个编辑器 您当前的分支(忽略合并提交),该分支位于 给定的提交。

假设您的branch_a从master分支出来,并且您希望以交互方式将所有提交基于branch_a。为此,您可以这样做:

git rebase -i master

或者,如果您想从中间(或任何提交)开始,则可以执行以下操作:

git rebase -i <some-commit-hash-in-the-middle>

另一种常见形式是,如果您知道“我想根据现在的位置重新调整5个提交”

git rebase -i HEAD~5

希望这有助于其他人在git rebase打开具有数千行提交的编辑器时避免心脏病发作。 ─=≡Σ((((つ> <)つ