假设我有一个由三个提交组成的分支,其中一个是空的:
# On branch test
3208910 empty
85c949c bar
0c1a615 foo
Run Code Online (Sandbox Code Playgroud)
我想在根页面上重新定义它,从man页面看来,这--root --keep-empty正是我需要的.
然而,无论git rebase -i --root和git rebase -i --root --keep-empty省略空承诺,让我看看这个计划,而不是:
pick 0c1a615 foo
pick 85c949c bar
Run Code Online (Sandbox Code Playgroud)
如何重新绑定整个分支并同时保留空提交?
PS我需要这个去除分支上的一些第一次提交,我设法通过这个SO答案中filter-branch描述的实现,但我仍然有兴趣知道是否能够做到这一点.我发现它是Git中的一个错误吗?很难相信这种行为是故意的,但我不确定.rebase
PPS我发现我可以手动编辑计划并添加pick 3208910.
根据我的理解git pull --rebase origin master,它应该相当于运行以下命令:
(from branch master): $ git fetch origin
(from branch master): $ git rebase origin/master
Run Code Online (Sandbox Code Playgroud)
我似乎找到了一些不按预期工作的情况.在我的工作区中,我有以下设置:
origin/master引用分支masteroriginmaster设置为跟踪origin/master,并由几个提交落后于主.feature设置为跟踪当地的分支机构master,以及领先的master通过多次提交.有时,我会通过运行以下一系列步骤来丢失提交
(from branch master): $ git pull --rebase
(from branch master): $ git checkout feature
(from branch feature): $ git pull --rebase
Run Code Online (Sandbox Code Playgroud)
在这一点上,我所feature面临的一些提交现在已经丢失了.现在,如果我重置我的位置,而是执行以下操作:
(from branch feature): $ git reset --hard HEAD@{2} # rewind to before …Run Code Online (Sandbox Code Playgroud) 我正在努力更好地理解git-rebase背后的魔力.今天我对以下行为感到非常惊喜,我没想到.
TLDR:我重新设置了一个共享分支,导致所有提交sha1都发生了变化.尽管如此,派生分支能够准确地识别出其原始提交被"别名"为具有不同sha1的新提交.rebase并没有造成任何混乱.
拿一个主分支: M1
将它分支到branch-X,添加一些额外的提交:M1-A1-B1-C1.记下git-log输出.
将branch-X分支到branch-Y,添加了一个额外的提交:M1-A1-B1-C1-D1.记下git-log输出.
将新提交添加到主分支的提示: M1-M2
将branch-X重新引导到更新后的master : M1-M2-A2-B2-C2. 请注意,A2-B2-C2都具有与A1-B1-C1相同的消息,内容和作者日期.但是,它们具有完全不同的sha1值以及提交日期.根据这篇文章,SHA1不同的原因是因为提交的父级已经改变.
将branch-Y重新引导到更新的分支-X上.结果:M1-M2-A2-B2-C2-D2.
值得注意的是,仅应用D1提交(并且变为D2).分支-Y中的A1-B1-C1提交被git-rebase完全忽略.您可以在输出日志中看到这一点.
这很棒,但git-rebase如何知道忽略A1-B1-C1?git-rebase如何知道A2-B2-C2与A1-B1-C1相同,因此可以安全地忽略?我一直认为git使用sha1标识符跟踪提交,但是尽管上面的提交有不同的sha1s,git仍然知道它们是链接在一起的.它是如何做到的?鉴于上述行为,何时修改共享分支真的很危险?