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

34

如果我处于以下情况:

$ 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个回答

52

你想将分支master的基础移动至根提交。更具体地说,若要合并这两个提交,需要运行以下命令:

git rebase -i --root

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

pick 123456 a                                                        
squash abcdef b

更多有关该标志的详细信息,请参阅git-rebase手册页

--root

将所有从<branch>可达的提交进行 rebase,而不是将它们限制在一个<upstream>中。这使您可以在分支上 rebase 根提交(或者所有初始提交)。[...]

对根提交进行交互式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

13

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

--root 

重新定位所有可达自 <branch> 的提交,而不是将它们限制在 <upstream> 上。这允许您在分支上重定位根提交。

这应该可以让您将第二个提交压缩(我猜您实际上想要修复)到第一个提交中:

git rebase --root -i

请注意理解--root选项的作用,因为在你的情况下它是符合你需求的,但在分支中使用时可能会比较棘手,因为它会将衍合变基到历史记录中可达的最远祖先(即树的根); 因此rebase --root将通过A-B-D-E-X-Y-Zz变基到a上:

master      A-B-C
               \
upstream        D-E  
                   \     
current branch      X-Y-Z

5
在查找答案的过程中,我来到了这个问题。对于一个非常大的 repo,所接受的答案针对主分支(即:master)的每个提交生成交互式 rebase,而不仅仅是给定的分支。对于在此处寻求帮助的其他人,替代方法是使用父分支名称(或提交): git rebase -i <base_branch_name> 我在挖掘 git 文档并找到以下内容后意识到了这一点 (https://git-scm.com/docs/git-rebase#_interactive_mode):
开始时用你想要保留为原状的最后一个提交开始: git rebase -i <after-this-commit> 一个编辑器将启动,其中包含您当前分支中的所有提交(忽略合并提交),这些提交在给定提交之后。
假设您从 master 分支分支出 branch_a,并且想要交互式地重组 branch_a 上的所有提交。那么,您应该这样做: git rebase -i master 或者,如果您想要从中间(或任何提交)开始,可以这样做: git rebase -i <some-commit-hash-in-the-middle> 另一种常见的形式是,如果您知道"我想要从现在开始重新排序 5 个提交",那么可以这样做: git rebase -i HEAD~5 希望这可以帮助其他人避免当他们的 git rebase 打开了数千行提交时产生心脏病。 ─=≡Σ((( つ><)つ

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接