您可以获取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 0123456
git log HEAD@{3}
git branch
gitk --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%。:-)