【发布时间】:2016-08-12 10:33:13
【问题描述】:
假设我们在分支中开发了一个特性,认为它已经完成,将其合并到 master 并删除分支。后来在此特定功能中发现了错误,并且有人去重置全局存储库上的 HEAD(您不应该这样做)。现在,我们本可以修复该错误,但不再拥有分支,并且整个功能都丢失了。有没有办法恢复这些更改,合并后保留功能分支一段时间总体上是个好主意吗?
【问题讨论】:
-
没有人的克隆仍然包含合并提交?
假设我们在分支中开发了一个特性,认为它已经完成,将其合并到 master 并删除分支。后来在此特定功能中发现了错误,并且有人去重置全局存储库上的 HEAD(您不应该这样做)。现在,我们本可以修复该错误,但不再拥有分支,并且整个功能都丢失了。有没有办法恢复这些更改,合并后保留功能分支一段时间总体上是个好主意吗?
【问题讨论】:
正如我们所见,feature 的提交历史仍然存在,尽管 ref feature 已经消失。分支 ref 只是一个变量,它存储从那时到现在它指向的提交的 sha1 哈希值。
M 是在将feature 合并到master 时创建的合并提交(仅当它是真正的合并,非快进合并时)。它有两个父级,D 第一个父级,master 指向,F 第二个父级,feature 指向。如果我们将master 合并到feature 并创建M,那么F 是第一个父级,D 是第二个父级。
M^ 可以引用第一个父级,M^2 可以引用第二个父级。
现在如果你想重新创建分支引用feature,假设M 的值为af2343242,你可以运行git branch feature af2343242^2。它会再次像这样。
合并一段时间后保留特征分支总体上是个好主意
这取决于。有些人认为保留曾经存在的所有更改是件好事,包括所有提交和所有分支、标签等。毕竟,这些都是项目的宝贵遗产。
【讨论】:
使用发布分支。比如说,当你在项目开发中达到一个重要的里程碑(完成并合并一个新功能)到生产等中时。
创建标签
git tag -a v1.0.0 -m "v1.0.0"
现在,假设您继续工作并开始了一项新功能,一段时间后您意识到存在一个错误,该错误已与您之前合并的该功能一起引入。合并删除后如何恢复?
让我们回到我们在合并新功能时创建的标签
git checkout v1.0.0
我们不能直接提交到 tag,但我们可以从中创建一个新分支(release 分支)。
git checkout -b rb1.0.0
现在我们可以应用 hot fix 然后添加并提交我们的更改到分支
git add <file> <file>
git commit -m "<hot fix message>"
此时剩下的就是合并热修复。所以,我们回到master分支,合并release分支
git checkout master
git merge rb1.0.0 -m "Merged <hot fix message>"
为了保持整洁,此时我们还将删除 release 分支。
git branch -d rb1.0.0
【讨论】:
是的,保留特性分支一段时间通常是个好主意,至少在你 100% 确定你永远不会回去之前。
它不会伤害任何东西或占用任何资源。分支只是指向提交的小便签。它在git 内部的唯一作用是防止垃圾收集器不可恢复地删除它指向(及其祖先)的提交。
对于您当前的情况,我将简单地创建一个分支(或标记)指向 master 的错误版本,然后将 master 重置回合并点后面。然后你就准备好了 - git 不会自动删除你否则“丢失”的分支,你可以在准备好后回到它。
当然,如果你想从中创建一个“真正的”分支,你需要在合并之前在分支端找到提交,然后执行git branch mybranch <hash>,这可能是最佳选择。
【讨论】:
您可以使用 reflog 恢复所有提交。请参阅以下链接。
http://gitready.com/advanced/2009/01/17/restoring-lost-commits.html
链接摘录:
例如,考虑以下回购:
$ git show-ref -h HEAD
7c61179cbe51c050c5520b4399f7b14eec943754 HEAD
$ git reset --hard HEAD^
HEAD is now at 39ba87b Fixing about and submit pages so they don't look stupid
$ git show-ref -h HEAD
39ba87bf28b5bb223feffafb59638f6f46908cac HEAD
现在 HEAD 被移回 1 个提交。让我们看看 git 是否知道被删除的提交。
$ git reflog
39ba87b... HEAD@{0}: HEAD~1: updating HEAD
7c61179... HEAD@{1}: pull origin master: Fast forward
[... lots of other refs ...]
所以,我们现在有了 SHA1:7c61179。如果我们想立即将它应用回我们当前的分支,执行 git merge 将恢复提交:
$ git merge 7c61179
Updating 39ba87b..7c61179
Fast forward
css/screen.css | 4 ++++
submit.html | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)
此命令将恢复丢失的更改并确保 HEAD 指向提交。从这里您可以继续正常工作!
【讨论】: