我无法理解git rebase - 的行为 [英] I can't understand the behaviour of git rebase --onto

查看:941
本文介绍了我无法理解git rebase - 的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我有一个A和B分支,一次提交

  ---分支A ------- COMMIT1 ----- 
\\ \\ - BRANCH B--

我想在最新的A上重新分配B分支(并且拥有B分支上的commit1)

  --- BRANCH A ------- COMMIT1 ----- 
\ - BRANCH B--

如果我这样做,没问题:

 结帐B 
rebase A

但是,如果我这样做:

 结帐B 
rebase --onto BA

完全不起作用,没有任何反应。我不明白为什么这两种行为是不同的。



Phpstorm git客户端使用第二种语法,在我看来完全破坏了,这就是为什么我要求这种语法问题。

解决方案

tl; dr



A 上使用 git rebase --onto B 你的情况是:

  git checkout B 
git rebase --onto AB ^
之上的c $ c>

rebase B B> B 的父项提交开始如果您对 B〜1



git rebase< branch> git rebase --onto< branch> 继续阅读



Quick:git rebase



git rebase< branch> 目前已经检查过从< branch> 可到达的最新提交的顶部,由 HEAD HEAD
这是最常见的重新折合,并且可以说是需要更少的

 之前之后
A --- B --- C --- F --- G(分支)A --- B --- C --- F --- G(分支)
\\\
D --- E(HEAD)D --- E HEAD)

在这个例子中, F G 是可从分支但不是从 HEAD 。说 git rebase branch 会取 D ,这是分支点之后的第一次提交,并且将它转换为分支但不是从 HEAD 可达到的最新提交 / code>,即 G



精确:git rebase - 带2个参数



git rebase --onto 允许您从特定提交开始重新分配 。它授予您对正在重新组装和在哪里进行精确控制。例如,我们假设我们需要重新分配 HEAD 这是用于需要精确的场景。 正好在从 E 开始的 F 之上。我们只关注 F 进入我们的工作分支,同时我们不想保留 D

 前后
A --- B --- C- --F --- G(分支)A --- B --- C --- F --- G(分支)
\\
D --- E --- H --- I(HEAD)E --- H --- I(HEAD)

在这种情况下,我们会说 git rebase --onto FD 。这意味着:


重新实现可从 HEAD 访问的提交,其父<




















$ b $ <换句话说,将 E 的父母
D 更改为˚F。然后, git rebase --onto 的语法是 git rebase --onto< newparent> < oldparent>



另一种方法是,当你想从当前分支中快速移除一些提交而不必做一个交互式重新组织:



 之前之后
A --- B --- C --- E --- F(HEAD)A --- B --- F(HEAD)

在这个例子中,为了从序列中删除 C E ,你会说<$ c $在 B 之上的c> git rebase - 在BE 或rebase HEAD 之处旧的父母是 E



外科医生:git rebase - 带3个参数



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



以下是一个示例:

 前后
A --- B --- C --- F --- G(分支)A --- B --- C --- F --- G(分支)
\\\
D --- E --- H --- I(HEAD)E --- H(HEAD )

在这种情况下,我们想重新确定 E-- -H F 之上,忽略 HEAD 当前指向的位置。我们可以通过说 git rebase --onto FDH ,这意味着:


F 上重新提交父元素 D H / code>。


git rebase --onto 使用范围的提交然后变成 git rebase --onto< newparent> < oldparent> <直到> 。这里的技巧是记住< until> 引用的提交包含,并且将成为新的 HEAD 完成rebase之后。

I have noticed that the two blocks of following git commands have different behaviours and I don't understand why.

I have a A and a B branch that diverge with one commit

---BRANCH A-------COMMIT1-----
\--BRANCH B--

I want to rebase B branch on the lastest A (and have the commit1 on the B branch)

---BRANCH A-------COMMIT1-----
                          \--BRANCH B--

No problem if I do:

checkout B
rebase A

But if I do:

checkout B
rebase --onto B A

It doesn't work at all, nothing happens. I don't understand why the two behaviours are different.

Phpstorm git client use the second syntax, and so seems to me completely broken, that's why I ask for this syntax issue.

解决方案

tl;dr

The correct syntax to rebase B on top of A using git rebase --onto in your case is:

git checkout B
git rebase --onto A B^

or rebase B on top of A starting from the commit that is the parent of B referenced with B^ or B~1.

If you're interested in the difference between git rebase <branch> and git rebase --onto <branch> read on.

The Quick: git rebase

git rebase <branch> is going to rebase the branch you currently have checked out, referenced by HEAD, on top of the latest commit that is reachable from <branch> but not from HEAD.
This is the most common case of rebasing and arguably the one that requires less planning up front.

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

In this example, F and G are commits that are reachable from branch but not from HEAD. Saying git rebase branch will take D, that is the first commit after the branching point, and rebase it (i.e. change its parent) on top of the latest commit reachable from branch but not from HEAD, that is G.

The Precise: git rebase --onto with 2 arguments

git rebase --onto allows you to rebase starting from a specific commit. It grants you exact control over what is being rebased and where. This is for scenarios where you need to be precise.

For example, let's imagine that we need to rebase HEAD precisely on top of F starting from E. We're only interested in bringing F into our working branch while, at the same time, we don't want to keep D because it contains some incompatible changes.

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

In this case, we would say git rebase --onto F D. This means:

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

In other words, change the parent of E from D to F. The syntax of git rebase --onto is then git rebase --onto <newparent> <oldparent>.

Another scenario where this comes in handy is when you want to quickly remove some commits from the current branch without having to do an interactive rebase:

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

In this example, in order to remove C and E from the sequence you would say git rebase --onto B E, or rebase HEAD on top of B where the old parent was E.

The Surgeon: git rebase --onto with 3 arguments

git rebase --onto can go one step further in terms of precision. In fact, it allows you to rebase an arbitrary range of commits on top of another one.

Here's an example:

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

In this case, we want to rebase the exact range E---H on top of F, ignoring where HEAD is currently pointing to. We can do that by saying git rebase --onto F D H, which means:

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

The syntax of git rebase --onto with a range of commits then becomes git rebase --onto <newparent> <oldparent> <until>. The trick here is remembering that the commit referenced by <until> is included in the range and will become the new HEAD after the rebase is complete.

这篇关于我无法理解git rebase - 的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆