假设我们在分支中开发一个功能,认为它是完整的,将它合并到master并删除分支。稍后在此特定功能中发现了错误,有人会在全局存储库中重置HEAD(您不应该这样做)。现在,我们可以修复该错误,但不再有分支,整个功能都丢失了。有没有办法恢复这些更改,并且在合并一段时间后保留功能分支总体上是个好主意吗?
答案 0 :(得分:1)
使用 发布分支 。比如,当您在项目开发中达到一个重要的里程碑(完成并合并一个新功能)到生产中等。
创建标签
git tag -a v1.0.0 -m "v1.0.0"
现在,假设您继续工作并开始使用新功能,过了一段时间后您才意识到之前已经合并过的功能已经引入了一个错误。合并并删除后如何恢复?
让我们回到我们在合并新功能时创建的代码
git checkout v1.0.0
我们无法直接提交 标记 ,但我们可以从中创建一个新的分支(发布分支)。
git checkout -b rb1.0.0
现在我们可以应用 hotfix ,然后添加并提交我们对分支的更改
git add <file> <file>
git commit -m "<hot fix message>"
此时剩下的就是合并 hotfix 。因此,我们返回master
分支并合并 发布分支
git checkout master
git merge rb1.0.0 -m "Merged <hot fix message>"
为了保持整洁,此时我们还会删除 发布分支 。
git branch -d rb1.0.0
答案 1 :(得分:1)
正如我们所看到的,虽然引用feature
已经消失,但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
。它会再次像这样。
总体好主意是在合并一段时间后保留功能分支
这取决于。有些人认为保留曾经存在的所有变更是件好事,包括所有提交和所有分支,标签等。毕竟,这些都是项目的宝贵遗产。
答案 2 :(得分:0)
您可以使用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指向提交。从这里你可以继续正常工作!
答案 3 :(得分:0)
是的,保留功能分支一段时间通常是一个好主意,至少在您100%确定永远不会回去之前。
它不会伤害任何东西或占用任何资源。分支只是一个指向提交的小粘滞便笺。它在git
中唯一的影响是它可以防止垃圾收集器无法删除它指向的提交(及其祖先)。
对于您当前的场景,我只需创建一个指向master
的错误版本的分支(或标记),然后在合并点后面重置master。然后你就完成了设置 - git
不会自动删除你原本“丢失”的分支,你准备好后就可以回来了。
当然,如果你想从它做一个“真正的”分支,你需要在合并之前在分支端找到提交,然后做git branch mybranch <hash>
,这可能是最佳的。