git - 如何使用 onto 命令对分支进行 git rebase?

标签 git git-rebase

我注意到以下两个 git 命令 block 有不同的行为,但我不明白为什么。

我有一个 A 和一个 B 分支,它们与一个 commit

fork
---COMMIT--- (A)
\
 --- (B)

我想在最新的 A 上 rebase B 分支(并在 B 分支上提交)

---COMMIT--- (A)
         \
          --- (B)

如果我这样做没问题:

checkout B
rebase A

但如果我这样做:

checkout B
rebase --onto B A

它根本不起作用,什么也没有发生。我不明白为什么这两种行为不同。

PhpStorm GIT 客户端使用第二种语法,因此似乎完全被破坏了,这就是为什么我要求这个语法问题。

最佳答案

tl;dr

rebase 的正确语法 BA 之上使用 git rebase --onto在你的情况下是:

git checkout B
git rebase --onto A B^

rebase BA 之上从 B 的父级提交开始B^ 引用或 B~1 .

如果您对 git rebase <branch> 之间的区别感兴趣和 git rebase --onto <branch>继续阅读。

快速:git rebase

git rebase <branch>将重新设置您当前 checkout 的分支,由 HEAD 引用, 在来自 <branch>可访问的最新提交之上但不是来自HEAD .
这是最常见的 rebase 案例,可以说是需要较少预先规划的案例。

          Before                           After
    A---B---C---F---G (branch)        A---B---C---F---G (branch)
             \                                         \
              D---E (HEAD)                              D---E (HEAD)

在这个例子中,FG是可以从 branch 访问的提交但不是来自 HEAD .说git rebase branch将采取D ,这是分支点之后的第一个提交,并且在可从 branch 到达的最新提交之上对其进行 rebase (即更改其父级)但不是来自 HEAD , 即 G .

精确:带有 2 个参数的 git rebase --onto

git rebase --onto允许您从特定提交开始 rebase 。它使您可以精确控制要重新定位的内容和位置。这适用于需要精确的场景。

例如,假设我们需要 rebase HEAD正好在 F 之上从 E 开始.我们只对带来 F 感兴趣进入我们的工作分支,同时,我们不想保留 D因为它包含一些不兼容的更改。

          Before                           After
    A---B---C---F---G (branch)        A---B---C---F---G (branch)
             \                                     \
              D---E---H---I (HEAD)                  E---H---I (HEAD)

在这种情况下,我们会说 git rebase --onto F D .这意味着:

Rebase the commit reachable from HEAD whose parent is D on top of F.

换句话说,更改 E 的父节点来自 DF . git rebase --onto 的语法然后是git rebase --onto <newparent> <oldparent> .

另一个派上用场的场景是当你想从当前分支中快速删除一些提交而不必执行 interactive rebase 时:

          Before                       After
    A---B---C---E---F (HEAD)        A---B---F (HEAD)

在这个例子中,为了删除CE从序列中你会说 git rebase --onto B E , 或 rebase HEADB 之上老 parent 在哪里E .

The Surgeon: git rebase --onto with 3 arguments

git rebase --onto在精度上可以更进一步。事实上,它允许您将一个任意范围的提交 rebase 到另一个提交之上。

这是一个例子:

          Before                                     After
    A---B---C---F---G (branch)                A---B---C---F---G (branch)
             \                                             \
              D---E---H---I (HEAD)                          E---H (HEAD)

在这种情况下,我们要重新定位确切范围 E---HF 之上, 忽略哪里 HEAD当前指向。我们可以说 git rebase --onto F D H 来做到这一点,这意味着:

Rebase the range of commits whose parent is D up to H on top of F.

git rebase --onto的语法具有提交范围然后变为git rebase --onto <newparent> <oldparent> <until> .这里的技巧是记住 <until> 引用的提交包含 在范围内,将成为新的 HEAD rebase 完成后。

关于git - 如何使用 onto 命令对分支进行 git rebase?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29914052/

相关文章:

git - 如何使用过滤器分支更改多个提交的提交作者?

c# - 有没有办法将数据流式传输到 GIT 而不是传递文件名?

git - 递归 Git 推/pull ?

github 操作 : how to check if current push has new tag (is new release)?

git rebase origin/develop 与 git rebase develop

git - 在预提交 Hook 中,查找正在创建的提交的父级的哈希值

performance - git 与 mercurial 性能对比

git - 将分支向后重新设置为 master 分支?

git - git rebase通过提交提交

git - 除了生成的 git 树结构之外,git pull 与 git fetch + git rebase 之间还有什么重要区别吗?