使用git 2.11,git rebase文档说:
如果提供了--onto选项,则当前分支将重置为<upstream>或<newbase>.这与git reset --hard(或)具有完全相同的效果.ORIG_HEAD设置为在重置之前指向分支的尖端.
我理解它upstream并且newbase指向相同的"基本引用",这意味着下面的两个rebase语法是等价的:
git rebase ABC
git rebase --onto ABC
Run Code Online (Sandbox Code Playgroud)
这是我设置的演示.让我们假设当前分支是FeatureABC与远程分支完全同步.
#---create two identical branches, behind current branch by 5 commits
(FeatureABC) git branch Demo1-Rebase-ABC HEAD~4
(FeatureABC) git branch Demo2-Rebase-onto-ABC HEAD~4
#---Make a new commit in branch Demo1
git checkout Demo1-Rebase-ABC
echo "Demo of: git rebase FeatureABC Demo1-Rebase-ABC" > ./Demo1_BogusFile.txt
git add ./Demo1_BogusFile.txt
git commit -m "Create file Demo1_BogusFile.txt"
git rebase FeatureABC
Run Code Online (Sandbox Code Playgroud)
首先,倒带头重播你的工作
...应用:创建文件Demo1_BogusFile.txt
git log --oneline -3表明该分支Demo1-Rebase-ABC与FeatureABC的HEAD同步.提交"创建文件Demo1_BogusFile.txt"已正确应用于它之上.
#---Make a new commit in branch Demo2
git checkout Demo2-Rebase-onto-ABC
echo "Demo of: git rebase --onto FeatureABC Demo2-Rebase-onto-ABC" > ./Demo2_Onto_BogusFile.txt
git add ./Demo2_Onto_BogusFile.txt
git commit -m "Create file Demo2_Onto_BogusFile.txt"
git rebase --onto FeatureABC
Run Code Online (Sandbox Code Playgroud)
当前分支没有跟踪信息.请指定您要反对的分支.有关详细信息,请参阅git-rebase(1).
Run Code Online (Sandbox Code Playgroud)git rebase <branch>如果您希望为此分支设置跟踪信息,可以使用以下命令:
Run Code Online (Sandbox Code Playgroud)git branch --set-upstream-to=origin/<branch> Demo2-Rebase-onto-ABC
我误解了警告信息.当使用--onto时,认为git在默认值中混淆了.所以我只想通过告诉git当前的分支我想要"帮助"
git rebase --onto FeatureABC Demo2-Rebase-onto-ABC
Run Code Online (Sandbox Code Playgroud)
首先,倒带头重播你的工作......
git log --oneline -3示出了分支Demo2-Rebase-onto-ABC变得相同比FeatureABC.最后一次提交"创建文件Demo2_Onto_BogusFile.txt"已经消失,文件./Demo2_Onto_BogusFile.txt被删除.
问题:git rebase --onto FeatureABC Demo2-Rebase-onto-ABC没有应用Demo2-Rebase-onto-ABC分支机构的新提交的原因是什么?
它们不一样,这也可能因--fork-point选项而变得复杂.我认为这可能有点像你,虽然不可能确定,只是从你所描述的内容,因为你概述的步骤之一只会产生错误.
要查看实际发生的情况,绘制(部分)提交图非常有用,特别注意标记,因为您使用的多个名称都指向单个提交.
让我们假设当前分支是
FeatureABC与远程分支完全同步.
因此我们有这样的东西 - 但是这样的东西不够好; 你有存储库,所以你应该绘制图形; 我猜:
...--o--A--B--C--D--E <-- FeatureABC (HEAD), origin/FeatureABC
Run Code Online (Sandbox Code Playgroud)
现在你运行:
Run Code Online (Sandbox Code Playgroud)#---create two identical branches, behind current branch by 5 commits (FeatureABC) git branch Demo1-Rebase-ABC HEAD~4 (FeatureABC) git branch Demo2-Rebase-onto-ABC HEAD~4
由于HEAD~4名称提交A(HEAD~1是D,HEAD~2是C等等),我们需要做一些事情来标记这两个新名称指向提交的事实A.我要缩短名字只是Demo1和Demo2虽然.(我创建了一个信息库,只有承诺o通过E在这一点上,与实际运行git branch Demo1 HEAD~4; git branch Demo2 HEAD~4在这里.)
...--o--A <-- Demo1, Demo2
\
B--C--D--E <-- FeatureABC (HEAD), origin/FeatureABC
Run Code Online (Sandbox Code Playgroud)
顺便说一下,git log --all --decorate --oneline --graph("有人把它从A DOG那里获得帮助")以这种方式显示了这个测试库(origin/在我的例子中没有分支):
* c4a0671 (HEAD -> master) E
* a7b8ae4 D
* 3deea72 C
* b11828d B
* ffc29b5 (Demo2, Demo1) A
* 3309a8d initial
Run Code Online (Sandbox Code Playgroud)
接下来,你看看Demo1,移动HEAD:
Run Code Online (Sandbox Code Playgroud)git checkout Demo1-Rebase-ABC
...--o--A <-- Demo1 (HEAD), Demo2
\
B--C--D--E <-- FeatureABC, origin/FeatureABC
Run Code Online (Sandbox Code Playgroud)
并修改工作树,将修改后的文件添加到索引,并提交,以进行我将调用的新提交F,更新HEAD分支,从而分离Demo1和Demo2.我现在将使用我自己的命令及其输出:
$ git checkout Demo1
Switched to branch 'Demo1'
$ echo demo1 > demo1.txt && git add demo1.txt && git commit -m F
[Demo1 89773b6] F
1 file changed, 1 insertion(+)
create mode 100644 demo1.txt
Run Code Online (Sandbox Code Playgroud)
绘制图形会变得有点困难; 我会用一行:
F <-- Demo1 (HEAD)
/
...--o--A <-- Demo2
\
B--C--D--E <-- FeatureABC, origin/FeatureABC
Run Code Online (Sandbox Code Playgroud)
现在我们开始你的第一个git rebase命令.我必须使用master,当然:
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: F
Run Code Online (Sandbox Code Playgroud)
这适用于当前分支(HEAD或Demo1).它发现HEAD没有打开的提交FeatureABC(FeatureABC..在gitrevisions语法中).这是承诺F.这些提交被放入一个可能复制的提交列表中 - git rebase将检查具有相同的提交git patch-id并跳过它们,尽管显然这里没有发生.所以现在将commit F复制到新的commit F',具有不同的hash ID和不同的base:
F [abandoned]
/
...--o--A <-- Demo2
\
B--C--D--E <-- FeatureABC, origin/FeatureABC
\
F' <-- Demo1 (HEAD)
Run Code Online (Sandbox Code Playgroud)
(这是实际的git log输出,显示了副本的新提交哈希.F除非我添加Demo1@{1}到命令,否则不会显示原来的,现在被放弃的.我在这里做了.原来是第二个 F显示,即先前的提交:
$ git log --all --decorate --oneline --graph Demo1@{1}
* c1d0896 (HEAD -> Demo1) F
* c4a0671 (master) E
* a7b8ae4 D
* 3deea72 C
* b11828d B
| * 89773b6 F
|/
* ffc29b5 (Demo2) A
* 3309a8d initial
Run Code Online (Sandbox Code Playgroud)
我更喜欢水平图,但是这个有更多的信息,特别是缩写的哈希ID.)
现在我们尝试重复这个Demo2,但它失败了.这是我的实际命令,剪切和粘贴.第一步工作正常:
$ git checkout Demo2
Switched to branch 'Demo2'
$ echo demo2 > demo2.txt && git add demo2.txt && git commit -m G
[Demo2 ae30665] G
1 file changed, 1 insertion(+)
create mode 100644 demo2.txt
Run Code Online (Sandbox Code Playgroud)
不再绘制原始图F,这是新图.我把它放在原G处F,虽然我可以把它画成...--o--A--G:
G <-- Demo2 (HEAD)
/
...--o--A
\
B--C--D--E <-- FeatureABC, origin/FeatureABC
\
F <-- Demo1
Run Code Online (Sandbox Code Playgroud)
然而,rebase不起作用.我必须再次使用master而不是FeatureABC,但是在您的示例中,由于该git branch命令未设置上游("跟踪")名称,因此行为方式相同:
$ git rebase --onto master
There is no tracking information for the current branch.
Please specify which branch you want to rebase against.
See git-rebase(1) for details.
git rebase <branch>
If you wish to set tracking information for this branch you can do so with:
git branch --set-upstream-to=<remote>/<branch> Demo2
Run Code Online (Sandbox Code Playgroud)
git rebase失败的原因是这个错误消息--onto已经吸收了这个论点<newtarget>,让我们没有<upstream>:
如果
<upstream>未指定,将使用上游配置的branch.<name>.remote和branch.<name>.merge选项(有关详细信息,请参阅git-config(1))并--fork-point假定该选项.如果您当前不在任何分支上,或者当前分支没有配置上游,则rebase将中止.
这里的粗体字是我的,但我认为它也是关键.我想你跑git rebase --onto <somename>那没有失败.因为它没有失败,你的分支必须有一个上游集.上游可能是 origin/FeatureABC或类似的,这意味着就Git而言,你正在运行:
git rebase --onto FeatureABC --fork-point origin/FeatureABC
Run Code Online (Sandbox Code Playgroud)
而不是:
git rebase --onto FeatureABC --no-fork-point origin/FeatureABC
Run Code Online (Sandbox Code Playgroud)
一些的(过于神秘,在我看来)在进一步阅读的git rebase文档会变成了这样一句话:
如果在命令行中给出了
<upstream>或者--root是,则默认为--no-fork-point,否则默认为--fork-point.
换一种说法:
git rebase FeatureABC
Run Code Online (Sandbox Code Playgroud)
关闭该--fork-point选项,一样:
git rebase --onto FeatureABC FeatureABC
Run Code Online (Sandbox Code Playgroud)
但:
git rebase
Run Code Online (Sandbox Code Playgroud)
要么:
git rebase --onto FeatureABC
Run Code Online (Sandbox Code Playgroud)
离开--fork-point选项上.
--fork-point是关于该目标的--fork-point是专门下降曾经是提交,在同一时间,在你的上游,但不再在你的上游.有关示例,请参阅Git rebase - 以fork-point模式提交select. 具体机制很复杂,依赖于上游分支的reflog. 由于我没有您的存储库或您的reflog,我无法测试您的具体情况 - 但这是一个原因,并且可能是在您的问题中给出提示的最可能的原因,一个会影响rebase 树结果的提交会放弃了.这是由于具有相同扔下提交补丁ID作为上游犯是那些[ 编辑:]通常1将不会影响到最终的树最后复制的承诺:他们只会导致合并冲突和/或强迫你用于git rebase --skip跳过它们,如果它们被包括在内.
1写完之后我发现有一个重要的例外(这可能与原始问题无关,但我应该提到).将功能或主题分支重新分配到更多主线分支上,当首次从功能中挑选出提交到主线中,然后在主线中恢复时,将导致问题.考虑一下,例如:
...--o--*--P--Q--C'-R--S--X--T <-- mainline
\
A--B--C--D--E <-- topic
Run Code Online (Sandbox Code Playgroud)
其中C'是commit的副本C,并且X是C尚未放入的commit的恢复mainline.这样做:
git checkout topic
git rebase mainline
Run Code Online (Sandbox Code Playgroud)
将指示的Git把承诺A通过E进入"考生复制"列表中,还看P通过T,看看是否有已经通过.承诺C 被采纳为C'.如果C并且C'具有相同的补丁ID - 通常,它们将 -Git将从C列表中删除为"已经复制".但是,在提交C中显式还原X.
C如果需要并且适当,那么谁需要注意,并仔细恢复.
这种特殊行为不是问题git merge(因为合并忽略了中间提交),只有git rebase.
| 归档时间: |
|
| 查看次数: |
688 次 |
| 最近记录: |