我知道这个问题,但不知道如何将其映射到我目前的情况.(Rebase是可怕的,撤消rebase是双重可怕!)
我从我的主人的几个不同的功能分支开始:
master x-x-x-x-x-x-x-x-x-x
\ \ \
FeatureA 1-2-3 \ \
FeatureB A-B \
FeatureC X-Y-Z
Run Code Online (Sandbox Code Playgroud)
我想将它们合并在一起并检查它们是否在合并回到主机顶部之前工作,所以我做了一个:
git checkout FeatureB
git rebase FeatureA
git mergetool //etc
git rebase --continue
Run Code Online (Sandbox Code Playgroud)
然后
git checkout FeatureC
git rebase FeatureB
git mergetool //hack hack
git rebase --continue
Run Code Online (Sandbox Code Playgroud)
这让我失望了
master x-x-x-x-x-x-x-x-x-x
\
FeatureA 1-2-3
\
FeatureB A'-B'
\
FeatureC X'-Y'-Z'
Run Code Online (Sandbox Code Playgroud)
然后我纠正了一些没有正确编译的位,并将整个功能设置为可接受的状态:
master x-x-x-x-x-x-x-x-x-x
\
FeatureA 1-2-3
\
FeatureB A'-B'
\
FeatureC X'-Y'-Z'-W
Run Code Online (Sandbox Code Playgroud)
我的问题是,我的同事告诉我,我们还没有为FeatureA做好准备.
我有什么方法可以保留我的所有工作,但也可以恢复到我可以将FeatureC重新设置为功能B的情况吗?
根据评论,这是我对答案的理解:
当您执行rebase时,当前分支上的提交被"撤消",然后"重新应用",但实际上,它们未被撤消,它们被"记住"*,并重新应用新ID,例如,如果我看起来在git reflog show FeatureB,我得到这样的东西:
7832f89 FeatureB@{0} rebase finished: refs/heads/FeatureB onto f4df3
efd3fed FeatureB@{1} commit: B
f3f3d43 FeatureB@{2} commit: A
2f32fed FeatureB@{3} branch: Created from HEAD
Run Code Online (Sandbox Code Playgroud)
正如@Jefromi所说,原始文件仍然存在(reflog中A和B提交的SHA与git log中的提交不同,它们对应于A'和B').
同样,git reflog show FeatureC看起来像这样
32873ef FeatureC@{0} commit: W
17dafb3 FeatureC@{1} rebase finished: refs/heads/FeatureC onto 89289fe
893eb78 FeatureC@{2} commit: Z
a78b873 FeatureC@{3} commit: Y
e78b873 FeatureC@{4} commit: X
378cbe3 FeatureC@{5} branch: Created from HEAD
Run Code Online (Sandbox Code Playgroud)
同样,原始的Z,Y和X提交仍然存在
所以,我的问题的解决方案是在FeaturesBCmaster的HEAD上创建一个新的分支(例如),然后挑选提交FeatureB {2&1},然后是FeatureC {4,3,2}和(可能) )W:
git checkout master
git checkout -b FeaturesBC
git cherry-pick f3f3d43
git cherry-pick efd3fed
//etc...
Run Code Online (Sandbox Code Playgroud)
(它似乎有效,我不得不重新做一些相同的合并,但它并不太糟糕)
来自Jefromi的编辑:
樱桃采摘可能没有必要.您还可以简单地重新创建分支在rebase之前的分支:
git branch FeatureB-old efd3fed
git branch FeatureC-old 893eb78
Run Code Online (Sandbox Code Playgroud)
或者,如果你想抛弃FeatureB和FeatureC的重新定位,那就回到原来的位置:
git branch -f FeatureB efd3fed
git branch -f FeatureC 893eb78
Run Code Online (Sandbox Code Playgroud)
最后,请注意,如果您愿意,可以使用reflog中提供的其他表示法 - 例如,FeatureC@{2}而不是893eb78.这意味着"FeatureC的第二个先前位置".但是,请注意在查看reflog之后立即使用它,因为只要再次更新分支(移动它,提交它...),FeatureC@{2}就会引用17dafb3.
正如@Jefromi对我的问题发表了评论:
您可能应该从master或featureC创建一个新分支(比如称为featuresABC),并将每个分支合并到其中,使功能分支保持不变.保留各个功能分支的独立历史是很好的.
*确切地说,旧的提交对象只是保留在存储库中.他们最终会被修剪,因为你不想要一个充满旧悬挂的回购; 这将在第一次git gc运行时发生,并且提交至少两周(由配置gc.pruneExpire).