git - 从多个 git rebases 中恢复 'old commits'

标签 git git-rebase

我知道 this问题,但不确定如何将其映射到我目前的情况。 ( rebase 很可怕,撤消 rebase 更可怕!)

我从我主人的几个不同的功能分支开始:

master    x-x-x-x-x-x-x-x-x-x
             \       \    \
FeatureA      1-2-3   \    \
FeatureB               A-B  \
FeatureC                     X-Y-Z

我想将它们全部 merge 在一起,并在 merge 回 master 顶部之前检查它们是否正常工作,所以我做了一个:

git checkout FeatureB
git rebase FeatureA
git mergetool //etc
git rebase --continue

然后

git checkout FeatureC
git rebase FeatureB
git mergetool //hack hack
git rebase --continue

这让我有

master    x-x-x-x-x-x-x-x-x-x
             \
FeatureA      1-2-3 
                   \
FeatureB            A'-B'
                         \ 
FeatureC                  X'-Y'-Z'

然后我纠正了一些没有正确编译的位,并将整个功能设置为可接受的状态:

master    x-x-x-x-x-x-x-x-x-x
             \
FeatureA      1-2-3 
                   \
FeatureB            A'-B'
                         \ 
FeatureC                  X'-Y'-Z'-W

我的问题是我的同事告诉我我们还没有为 FeatureA 做好准备。

有什么方法可以让我保留我所有的工作,同时恢复到我可以将 FeatureC rebase 到 Feature 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

所以正如@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

同样,原始的 Z、Y 和 X 提交仍然存在

因此,我的问题的解决方案是在 master 的 HEAD 之外创建一个新分支 FeaturesBC(例如),然后挑选提交 FeatureB{2 & 1},然后是 FeatureC {4, 3, 2} 和​​(可能)W:

git checkout master
git checkout -b FeaturesBC
git cherry-pick f3f3d43 
git cherry-pick efd3fed 
//etc...

(这似乎奏效了,我不得不重新进行一些相同的 merge ,但还算不错)

编辑,来自 Jefromi:

cherry-pick 可能没有必要。您还可以简单地重新创建分支,其中分支在 rebase 之前:

git branch FeatureB-old efd3fed
git branch FeatureC-old 893eb78

或者,如果你想扔掉 FeatureB 和 FeatureC 的 rebased 位置,回到它们之前的位置:

git branch -f FeatureB efd3fed
git branch -f FeatureC 893eb78

最后,请注意,如果您愿意,可以使用 reflogs 中提供的其他符号 - 例如,FeatureC@{2} 而不是 893eb78。这意味着“FeatureC 的前第二个位置”。不过,请注意仅在查看 reflog 后立即使用它,因为一旦您再次更新分支(移动它、提交它...),FeatureC@{2} 将引用改为 17dafb3。

正如@Jefromi 对我的问题的评论:

You should probably have created a new branch off of master or featureC (called featuresABC, say), and merged each into it, leaving the feature branches intact. It's good to preserve the independent history of various feature branches.

<子> * 准确地说,旧的提交对象只是留在存储库中。它们最终会被修剪,因为你不想要一个充满旧的悬而未决的提交的 repo 协议(protocol);这将在第一次运行 git gc 时发生,并且提交时间至少为两周(由 gc.pruneExpire 配置)。

关于git - 从多个 git rebases 中恢复 'old commits',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2690962/

相关文章:

git - Jenkins 配置和安全问题

eclipse - 如何使用 JGit 将文件重置为特定提交?

git rebase --continue 没有变化

git - 在整个 Git 提交历史中重命名目录

Git 更改 pull 请求的源分支

git - 具有多个分支的 Git 存储库模板的最佳方法?

git - 检查文件选择何时更改

Github squash 在审查评论后根据 pull 请求从 Web 界面提交?

Git 设备上没有剩余空间

git - 如何挑选多个提交