您可以获取C并D返回[编辑:如果您在原始存储库中“丢失”了它们,但我看到您没有]。使用git reflog通过 ID 查找它们:
$ git reflog
或者:
$ git reflog master
(如果您在上master并且只想查看那里发生的更改)等。
找到 commitD后,在其上粘贴分支标签。假设上面的输出清楚地表明这HEAD@{3}是您想要的。然后:
$ git branch recover_my_stuff 'HEAD@{3}'
或者:
$ git branch get_d_back 0123456
按数字(并使用不同的名称等)来完成。您可以在此之前运行gitk HEAD@{3}and或等,以仔细检查这是否是您想要的。一旦你有一个分支标签,它会再次显示给你。gitk 0123456git log HEAD@{3}git branchgitk --all
编辑:因为您仍然在原始仓库中拥有它们,所以让我们在那里工作。首先,您master当前有a - b - C - D序列。让我们将此分支重命名为temp,然后使用git fetch以获取远程 repo 的最新信息,并创建一个新master的 track origin/master:
$ git branch -m master temp
$ git fetch origin
$ git checkout -b master --track origin/master
(这里,temp——因为它只是对原始文件的重命名——也会master“跟踪” origin/master,所以 git 会告诉你它与 不同origin/master,在多次提交之前和之后。但你不需要关心,你可以忽略这些来自 git 的通知。如果你愿意,你可以通过编辑 git 配置让它停止“跟踪”,但无论如何它都是无害的。)
好的,所以,假设您已经完成了上述操作,gitk现在显示(以更漂亮的图形形式)这个。我将为temp恢复的东西使用分支标签,并假设其余的都打开了master(好吧,你说它是 :-)):
a - b - E - f <-- HEAD=master, origin/master
\
C - D <-- temp
一般来说,在其他人身上“倒带”分支标签是不好的(可以对自己做 :-))所以让我们留在那儿E。您可以在任何时候git revert添加一个简单地取消所做的提交的提交E。C您现在需要做的D就是移植f. 这就是这样git rebase做的:它将原始提交中的更改复制到新提交中。然后它移动标签。
$ git checkout temp
$ git rebase master
现在你会有这个:
a - b - E - f <-- master, origin/master
\ \
\ C'-D' <-- HEAD=temp
\
C - D [no branch label]
(由于 C 和 D 没有标签,它们将从gitk --all.
现在您所要做的就是提出master来,您可以使用git merge. 首先你必须git checkout master(有一种方法可以在没有中间步骤的情况下做到这一点,但让我们保持简单):
$ git checkout master
a - b - E - f <-- HEAD=master, origin/master
\
C'-D' <-- temp
这是相同的提交图,我们只是更改了 HEAD 指向(到 master)的位置并删除了不可见的提交。
$ git merge temp
该merge操作将“快进”主控,因为实现合并所需的唯一事情是将标签从提交“向下滑动”f到提交D':
a - b - E - f <-- origin/master
\
C'-D' <-- HEAD=master, temp
现在您可以git branch -d temp删除临时分支并git push origin master推送。
旁注:恭喜您绘制了提交图现在看起来像什么的清晰示例,以及您希望它看起来像什么。这大约是确定要使用哪些 git 命令所需的所有工作的 80%。:-)