Xma*_*oux 136 git git-rebase
我注意到以下git命令的两个块有不同的行为,我不明白为什么.
我有一个A和B分支,一个提交分歧
---COMMIT--- (A)
\
--- (B)
Run Code Online (Sandbox Code Playgroud)
我想在最新的A上重新绑定B分支(并且在B分支上有commit1)
---COMMIT--- (A)
\
--- (B)
Run Code Online (Sandbox Code Playgroud)
如果我这样做没问题:
checkout B
rebase A
Run Code Online (Sandbox Code Playgroud)
但如果我这样做:
checkout B
rebase --onto B A
Run Code Online (Sandbox Code Playgroud)
它根本不起作用,没有任何反应.我不明白为什么这两种行为是不同的.
Phpstorm git客户端使用第二种语法,所以在我看来完全破坏了,这就是我要求这个语法问题的原因.
Enr*_*lio 344
正确的语法变基B之上A使用git rebase --onto你的情况是:
git checkout B
git rebase --onto A B^
Run Code Online (Sandbox Code Playgroud)
或者在作为使用or 引用的父项的提交开始的基础上进行rebaseBAB.B^B~1
如果你对它们之间的区别感兴趣git rebase <branch>并继续git rebase --onto <branch>阅读.
git rebase <branch>是要重订当前已签出的分支,通过引用HEAD,在顶部最新提交可到达的距离<branch>,但不从HEAD.
这是最常见的变基案例,可以说是需要较少预先计划的案例.
Before After
A---B---C---F---G (branch) A---B---C---F---G (branch)
\ \
D---E (HEAD) D---E (HEAD)
Run Code Online (Sandbox Code Playgroud)
在这个例子中,F并且G是提交是从可达branch但不从HEAD.说git rebase branch将采取D,那是分支点后的第一个承诺,和重订它(即改变其母公司)上的最新承诺从最高可达branch但不从HEAD,即G.
git rebase --onto允许您从特定提交开始重新绑定.它可以让您准确控制正在重新定位的内容和位置.这适用于您需要精确的场景.
例如,让我们想象一下,我们需要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)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们会说git rebase --onto F D.这意味着:
重新引用
HEAD其父级位于其D上的可提交的提交F.
换句话说,将E from 的父项更改D为F.git rebase --onto那么语法就是git rebase --onto <newparent> <oldparent>.
另一种方便的方法就是当你想要从当前分支中快速删除一些提交而不必进行交互式rebase时:
Before After
A---B---C---E---F (HEAD) A---B---F (HEAD)
Run Code Online (Sandbox Code Playgroud)
在这个例子中,为了从序列中删除C和删除,或者在旧父母所在的位置上进行变基.Egit rebase --onto B EHEADBE
git rebase --onto在精度方面可以更进一步.实际上,它允许您在另一个提交之上重新提交任意范围的提交.
这是一个例子:
Before After
A---B---C---F---G (branch) A---B---C---F---G (branch)
\ \
D---E---H---I (HEAD) E---H (HEAD)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我们想要E---H在顶部重新确定精确范围F,忽略HEAD当前指向的位置.我们可以这样说git rebase --onto F D H,这意味着:
衍合的提交,其父母为范围
D高达H之上F.
然后,git rebase --onto具有一系列提交的语法变为git rebase --onto <newparent> <oldparent> <until>.这里的技巧是要记住的是,提交通过引用<until>被包含在范围,将成为新的HEAD底垫完成后.
sEv*_*ver 44
这是您需要了解的所有内容--onto:
git rebase --onto <newparent> <oldparent>
Run Code Online (Sandbox Code Playgroud)
您在提交时切换父级,但是您没有提供提交的sha,只提供它的当前(旧)父级的sha.
小智 12
为了更好地理解之间的区别 git rebase和git rebase --onto这是好事,知道什么是两个命令的可能行为。git rebase允许我们将提交移动到所选分支的顶部。像这儿:
git rebase master
Run Code Online (Sandbox Code Playgroud)
结果是:
Before After
A---B---C---F---G (master) A---B---C---F---G (master)
\ \
D---E (HEAD next-feature) D'---E' (HEAD next-feature)
Run Code Online (Sandbox Code Playgroud)
git rebase --onto更精确。它允许我们选择我们想要开始和结束的特定提交。像这儿:
git rebase --onto F D
Run Code Online (Sandbox Code Playgroud)
结果是:
Before After
A---B---C---F---G (branch) A---B---C---F---G (branch)
\ \
D---E---H---I (HEAD my-branch) E'---H'---I' (HEAD my-branch)
Run Code Online (Sandbox Code Playgroud)
要获得更多详细信息,我建议您查看我自己关于git rebase --onto 概述的文章
Wlo*_*oHu 10
简短地说,鉴于:
Before rebase After rebase
A---B---C---F---G (branch) A---B---C---F---G (branch)
\ \ \
D---E---H---I (HEAD) \ E'---H' (HEAD)
\
D---E---H---I
git rebase --onto F D H
Run Code Online (Sandbox Code Playgroud)
这与(因为--onto有一个参数)相同:
git rebase D H --onto F
Run Code Online (Sandbox Code Playgroud)
手段范围变基提交(d,H] F上的通知顶部的范围是左手排斥。这是独特的,因为它更容易指定1日通过键入如承诺branch让git找到1分歧从提交branch即D导致H。
o---o (A)
\
o (B)(HEAD)
git checkout B
git rebase --onto B A
Run Code Online (Sandbox Code Playgroud)
可以更改为单个命令:
git rebase --onto B A B
Run Code Online (Sandbox Code Playgroud)
这里看起来像错误的地方是它的位置B,意思是“移动一些提交,从而导致分支B在顶部B”。问题是什么是“某些提交”。如果添加-i标志,您将看到它是指向的单次提交HEAD。提交被跳过,因为它已经被应用到--onto目标B,因此什么也没有发生。
在这样重复分支名称的情况下,该命令都是无意义的。这是因为提交范围将是该分支中已经存在的某些提交,并且在重新设置基准期间将全部跳过这些提交。
git rebase <upstream> <branch> --onto <newbase>。git rebase 默认值。git rebase master
Run Code Online (Sandbox Code Playgroud)
扩展为:
git rebase --onto master master HEAD
git rebase --onto master master current_branch
Run Code Online (Sandbox Code Playgroud)
以标准方式使用时,例如:
git checkout branch
git rebase master
Run Code Online (Sandbox Code Playgroud)
您不会注意到在git将branch基准迁移到最近的基于基准的提交之后,确实会这样做git checkout branch(请参阅git reflog历史记录)。当第二个参数是commit hash而不是分支名称rebase时,仍然很有趣,但是没有分支可移动,因此您最终以“ detached HEAD”结尾,而不是检出到移动的分支。
将master在--onto从第一个拍摄git rebase参数。
git rebase master
/ \
git rebase --onto master master
Run Code Online (Sandbox Code Playgroud)
因此实用上可以是任何其他提交或分支。这样,您可以通过获取最新提交并保留主要的不同提交来限制重新提交的数量。
git rebase --onto master HEAD~
git rebase --onto master HEAD~ HEAD # Expanded.
Run Code Online (Sandbox Code Playgroud)
将HEAD重新master建立指向的单个提交,并最终以“分离的HEAD”结尾。
默认值HEAD或current_branch参数是从上下文中从您所处的位置获取的。这就是为什么大多数人结帐到他们想作为基准的分支的原因。但是,当显式给出第二个rebase参数时,您不必在重新设置基数之前以隐式方式传递它。
(branch) $ git rebase master
(branch) $ git rebase master branch # Expanded.
(branch) $ git rebase master $(git rev-parse --abbrev-ref HEAD) # Kind of what git does.
Run Code Online (Sandbox Code Playgroud)
这意味着您可以在任何地方重新建立提交和分支。因此,与重新设置基准点后的自动结帐一起使用。在重新设置基准之前或之后,您不必分别检出已重新定义的分支。
(master) $ git rebase master branch
(branch) $ # Rebased. Notice checkout.
Run Code Online (Sandbox Code Playgroud)
因为onto您需要两个额外的分支。使用该命令,您可以将branchB基于该分支的提交应用branchA到另一个分支,例如master。branchB在下面的示例中,您希望应用onbranchA的更改而不应用 的更改。branchBmasterbranchA
o---o (master)
\
o---o---o---o (branchA)
\
o---o (branchB)
Run Code Online (Sandbox Code Playgroud)
通过使用以下命令:
checkout branchB
rebase --onto master branchA
Run Code Online (Sandbox Code Playgroud)
您将得到以下提交层次结构。
o'---o' (branchB)
/
o---o (master)
\
o---o---o---o (branchA)
Run Code Online (Sandbox Code Playgroud)
简单地说,git rebase --onto选择一系列提交并在作为参数给出的提交中重新定义它们.
阅读手册页git rebase,搜索"上".这些例子非常好:
example of --onto option is to rebase part of a branch. If we have the following situation:
H---I---J topicB
/
E---F---G topicA
/
A---B---C---D master
then the command
git rebase --onto master topicA topicB
would result in:
H'--I'--J' topicB
/
| E---F---G topicA
|/
A---B---C---D master
Run Code Online (Sandbox Code Playgroud)
在这种情况下,你告诉git将提交从最重要的topicA转移到.topicBmaster
Git 的措辞在这里有点混乱。如果您假装命令如下所示,这可能会有所帮助:
git rebase --onto=<new_base> <old_base> [<branch>]
如果我们现在打开branch,它可以省略:
git rebase --onto=<new_base> <old_base>
如果new_base与 相同old_base,我们可以省略--onto参数:
git rebase <new_old_base>
这听起来可能很奇怪:如果旧基地与新基地相同,你如何重新定位?但是这样想,如果你有一个功能分支foo,它已经(可能)基于你的main分支中的一些提交。通过“re-base”,我们只是基于更新的提交提交。
(事实上,<old_base>是我们比较的东西branch。如果它是一个分支,那么 git 寻找一个共同的祖先(另见--fork-point);如果它是当前分支上的提交,则使用之后的提交;如果它是一个没有与当前分支的共同祖先,使用当前分支的所有提交。<new_base>也可以是提交。因此,例如,git rebase --onto HEAD~ HEAD将在旧基HEAD和当前之间进行提交HEAD并将它们放在 之上HEAD~,从而有效地删除最后一次提交。)
| 归档时间: |
|
| 查看次数: |
51410 次 |
| 最近记录: |