如果我运行git branch -d XYZ
,有没有办法恢复分支?有没有办法像我没有运行删除分支命令一样返回?
21 回答
是的,您应该能够git reflog --no-abbrev
在已删除分支的尖端找到提交的 SHA1,然后只需git checkout [sha]
. 一旦你完成了那个提交,你就可以git checkout -b [branchname]
从那里重新创建分支。
感谢@Cascabel 获得这个浓缩/单线版本和@Snowcrash 如何获得 sha。
如果您刚刚删除了分支,您将在终端中看到类似的内容Deleted branch <your-branch> (was <sha>)
。然后<sha>
在这个单行中使用它:
git checkout -b <your-branch> <sha>
当您的提交在reflog
大多数情况下,无法访问的提交都在 reflog 中。因此,首先要尝试的是使用命令git reflog
(显示 reflog HEAD
)查看 reflog。
git reflog name-of-my-branch
如果提交是特定且仍然存在的分支的一部分,也许更容易使用该命令。它也适用于遥控器,例如,如果你强制推动(尽管应该使用git push --force-with-lease
它来防止错误并且更容易恢复)。
当他们不在reflog
如果您的提交不在您的 reflog 中(可能它们已被不写入 reflog 的 3rd 方工具删除),您可以先尝试此命令以创建一个包含所有悬空提交的文件
git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\ -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt
然后读取丢失提交的 SHA 并将您的分支重置为它。
git rescue
频繁的用户可以使用创建别名
git config --global alias.rescue '!git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\ -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt'
以下是一些示例,展示了如何分析找到的提交
显示提交元数据(作者、创建日期和提交消息):
git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560
另见差异:
git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560
在找到的提交上创建一个分支:
git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560
Windows GUI 可以通过菜单使用GitExtensions轻松恢复提交(也包括未提交的暂存文件)Repository
=> Git maintenance
=>Recover lost objects...
相关:轻松恢复已删除的暂存文件
如果您喜欢使用 GUI,您可以使用 gitk 执行整个操作。
gitk --reflog
这将允许您查看分支的提交历史记录,就好像该分支没有被删除一样。现在只需右键单击分支的最新提交并选择菜单选项Create new branch
。
投票最多的解决方案实际上比要求的要多:
git checkout <sha>
git checkout -b <branch>
或者
git checkout -b <branch> <sha>
将您连同您可能忘记提交的所有最近更改一起移至新分支。这可能不是您的意图,尤其是在失去分支后处于“恐慌模式”时。
一个更清洁(更简单)的解决方案似乎是单线(在你找到<sha>
with之后git reflog
):
git branch <branch> <sha>
现在,您当前的分支和未提交的更改都不会受到影响。相反,只会创建一个新分支,直到<sha>
.
如果它不是提示,它仍然可以工作并且你得到一个更短的分支,然后你可以用新的<sha>
和新的分支名称重试,直到你得到它。
最后,您可以将成功恢复的分支重命名为它的名称或其他名称:
git branch -m <restored branch> <final branch>
不用说,成功的关键是找到正确的提交<sha>
,所以明智地命名你的提交:)
添加到tfe答案: Git 源(在 git.git 存储库中)区域中还有git-resurrect.sh脚本,这可能会对您有所帮助。contrib/
git-resurrect <name>
试图找到名为 的分支尖端的痕迹<name>
,并尝试将其复活。目前,在 reflog 中搜索结帐消息,并-r
合并消息。使用-m
and-t
,扫描所有 refs 的历史以查找Merge <name> into other
/Merge <other> into <name>
(分别)提交主题,这相当慢,但允许您复活其他人的主题分支。
我使用以下命令来查找和检索已删除的分支。第一步来自 gcb 的描述。
$ git fsck --full --no-reflogs --unreachable --lost-found > lost
$ cat lost | cut -d\ -f3 > commits
$ cat commits | xargs -n 1 git log -n 1 --pretty=oneline
现在根据提交注释查找 git commit id (GIT-SHA) 并在下面的命令中使用它。使用之前找到的 GIT-SHA 签出一个名为 NEW-BRANCH 的新分支:
$ git checkout -b NEW-BRANCH GIT-SHA
据我了解,如果要删除的分支可以被另一个分支访问,您可以使用它安全地删除它
git branch -d [branch]
你的工作不会丢失。请记住,分支不是快照,而是指向快照的指针。所以当你删除一个分支时,你会删除一个指针。
如果您删除了另一个无法访问的分支,您甚至不会失去工作。当然它不会像检查提交哈希那样简单,但你仍然可以做到。这就是为什么 Git 无法删除使用-d
. 相反,您必须使用
git branch -D [branch]
这是 Scott Chacon 关于 Git 的必看视频的一部分。当他谈到分支以及如何删除它们时,请查看 58:00 分钟。
如果您没有 reflog,例如。因为您在一个未启用 reflog 的裸存储库中工作,并且您要恢复的提交是最近创建的,所以另一种选择是查找最近创建的提交对象并查看它们。
从.git/objects
目录内部运行:
find . -ctime -12h -type f | sed 's/[./]//g' | git cat-file --batch-check | grep commit
这会查找在过去 12 小时内创建的所有对象(提交、文件、标签等)并过滤它们以仅显示提交。检查这些是一个快速的过程。
不过,我会先尝试Jakub 的回答中提到的 git-ressurect.sh 脚本。
对于未安装 Git的GitHub用户:
如果你想从GitHub网站恢复它,你可以使用他们的 API来获取与 repo 相关的事件列表:
第一的
找到那些 SHA(提交哈希):
curl -i https://api.github.com/repos/PublicUser/PublicRepo/events
...或私人回购:
curl -su YourUserName https://api.github.com/repos/YourUserName/YourProject/events
(将提示输入 GitHub 密码)
- (如果 repo 需要双因素身份验证,请参阅下面对此答案的评论。)
下一个
• 转到分支并删除那个。
• 在同一页面上,无需重新加载,打开 DevTools、Network 面板。现在准备...
• 单击恢复。你会注意到一个新的“线”。右键单击它并选择“复制为 cURL”并将此文本保存在某个编辑器中。
• 附加到复制的代码行的末尾,这一行:-H "Cookie="
。
你现在应该得到类似的东西:
curl 'https://github.com/UserName/ProjectName/branches?branch=BranchSHA&name=BranchName' -H 'Cookie:' -H 'Origin: https://github.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US' -H 'User-Agent: User-Agent' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'Accept: */*' -H 'Referer: https://github.com/UserName/ProjectName/branches' -H 'X-Requested-With: XMLHttpRequest' -H 'Connection: keep-alive' --data 'utf8=%E2%9C%93&authenticity_token=token' --compressed
最后一步
- 用你的 SHA-hash 和 BranchName 替换“BranchSHA”,用所需的名称(顺便说一句,从 web 重命名分支是一个很好的技巧)。如果你不是太慢,无论如何你都需要提出这个请求。例如,只需复制粘贴到终端。
附言
我意识到这可能不是“最简单的解决方案”或“正确的”解决方案,但如果有人发现它有用,就会提供它。
如果您删除了分支并忘记了它的提交 ID,您可以执行以下命令:
git log --graph --decorate $(git rev-list -g --all)
在此之后,您将能够看到所有提交。然后你可以git checkout
对这个 id 做,并在这个提交下创建一个新的分支。
确保在本地执行所有这些操作,并确认您的存储库处于您想要的状态,然后再推送到 Bitbucket Cloud。克隆您当前的存储库并首先测试这些解决方案可能也是一个好主意。
- 如果您刚刚删除了分支,您将在终端中看到类似这样的内容:
Deleted branch <your-branch> (was <sha>)
2.要恢复分支,请使用:
git checkout -b <branch> <sha>
如果您不知道头顶上的“sha”,您可以:
- 使用以下命令在已删除分支的尖端找到提交的“sha”:
git reflog
- 要恢复分支,请使用:
git checkout -b <branch> <sha>
如果您的提交不在您的 reflog 中:
- 您可以尝试通过将分支重置为使用以下命令找到的提交的 sha 来恢复分支:
git fsck --full --no-reflogs --unreachable --lost-found | grep commit | cut -d\ -f3 | xargs -n 1 git log -n 1 --pretty=oneline > .git/lost-found.txt
2.然后您可以使用以下之一显示每个提交:
git log -p <commit>
git cat-file -p <commit>
要恢复已删除的分支,首先要查看 reflog 历史记录,
git reflog -n 60
其中 n 是指最后 n 次提交。然后找到合适的头并用那个头创建一个分支。
git branch testbranch HEAD@{30}
我从远程重新设置了一个分支,以尝试清除一些我不想要的提交,并准备挑选我想要的正确的提交。当然我写错了SHA...
这是我找到它们的方法(主要是从这里的答案中获得的更简单的界面/交互):
首先,在日志中生成松散提交列表。尽快执行此操作并停止工作,因为这些可能会被垃圾收集器转储。
git fsck --full --no-reflogs --unreachable --lost-found > lost
这将创建一个lost
包含您必须查看的所有提交的文件。为了简化我们的生活,让我们只删除其中的 SHA:
cat lost | cut -d\ -f3 > commits
现在您有了一个commits
包含所有必须查看的提交的文件。
假设您使用的是 Bash,最后一步:
for c in `cat commits`; do git show $c; read; done
这将向您显示他们每个人的差异和提交信息。等你按Enter。现在写下所有你想要的,然后挑选它们。完成后,只需 Ctrl-C 即可。
是的
如果您使用 GIT,请 按照以下简单步骤 操作https://confluence.atlassian.com/bbkb/how-to-restore-a-deleted-branch-765757540.html
如果您正在使用 smartgit 并且已经将该分支推 送到原点,请找到该分支并右键单击然后结帐
我在删除分支的计算机上执行了此操作:
git reflog
回复:
74b2383 (develope) HEAD@{1}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{2}: checkout: moving from develope to master
74b2383 (develope) HEAD@{3}: checkout: moving from master to develope
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{4}: reset: moving to HEAD
40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{5}: clone: from http://LOCALGITSERVER/myBigProject/Android.git
我用这个命令检索分支:
git checkout -b newBranchName 74b2383
恢复已删除分支的一般问题的一个非常常见的子问题是在合并后恢复功能分支然后删除它 - 这是常见的做法。
正如这篇SO 帖子所涵盖的,如果已成功合并,您始终可以恢复已删除的分支。这是因为分支只是一个指向提交的精美指针,并且因为您已经合并,所以提交仍然存在。合并提交将列出合并的两个(或更多)分支的头部提交的哈希值。例如:
git show master
commit 849675951d41497e7b07d34096ebf36dc713221 (HEAD -> master)
Merge: fc1c9ce 97f8a60
Author: Me
Date: Sun Jan 9 16:14:24 2022 +0100
Merge branch 'feature'
因此,您可以通过执行恢复删除“功能”分支git checkout -b feature 97f8a60
- 不需要任何 reflog 内容。
如果你使用 Git 扩展
虽然很旧,但当你用谷歌恢复已删除的分支时,这个线程是列表的顶部。我使用 git 扩展而不是命令行,因此对命令不熟悉,但reflog命令给了我一个线索,所以我在此处发布我的 git 扩展解决方案,供使用 git 扩展的其他人阅读。
- 转到工具栏上的视图下拉菜单
- 选择显示 reflog 引用
您删除的分支现在应该可以查看和选择,只需单击它并检查它。
首先去 git batch 移动到你的项目,比如:
cd android studio project
cd Myproject
then type :
git reflog
你们都有一个更改列表,参考编号取参考编号,然后
从 android studio 或 git betcha 结帐。另一个解决方案获取参考号并转到 android studio 单击 git 分支向下然后单击结帐标签或超过参考号的修订然后大声笑你有分支。
添加到 tfe 的答案中,您可以使用提到的这个过程进行恢复,除非它的提交不是垃圾收集的。Git 分支只是指向提交树中特定提交的指针。但是如果你删除了指针,并且该分支上的提交没有合并到其他现有分支中,那么 git 会将其视为悬空提交并在垃圾收集期间将其删除,它可能会定期自动运行。
如果您的分支没有合并到现有分支,并且如果它被垃圾收集,那么您将丢失所有提交,直到分支从现有分支分叉的点。
只是使用git reflog
并没有sha
为我返回。只有commit id
(8个字符长,sha更长)
所以我用
git reflog --no-abbrev
然后执行与上面相同的操作:
git checkout -b <branch> <sha>
如果您使用的是 VSCode ...并且您在删除之前将分支与服务器同步...
请注意, git branch delete 只删除本地副本,而不是服务器上的副本。首先,在 Git 面板(左侧工具栏上的 git 图标)中,查看分支,看看您的分支是否仍在“origin/your_branch_name”下。如果是这样,只需选择它,您就应该取回您的代码(建议您立即在其他地方复制/粘贴/保存它)。
如果您没有看到“origin/your_branch_name”,请安装 GitLens 扩展。这使您可以直观地浏览服务器存储库并找到您同步到服务器的副本。如果您有多个存储库,请注意,可能需要从所需存储库中打开至少一个文件才能使存储库出现在 GitLens 中。然后:
打开 GitLens 面板
展开存储库
您应该会看到一个类别列表:Branches / Contributors / Remotes / Stashes / etc
您应该在“Branches”下或可能在“Remotes -> Origins”下找到 YourLostTreasure。希望您会看到一个具有所需名称的分支 - 如果您展开它,您应该会看到您在该分支中更改的文件。双击文件名将其打开,然后立即备份该代码。
如果您没有立即看到丢失的分支,请四处寻找,如果您发现有希望的东西,请立即打开它并获取代码。在找到 TheGoldenBranch 之前,我不得不四处寻找,即便如此,代码仍然缺少最后一两次保存(可能是因为我在尝试分支之前未能同步到服务器 - 分支 - 合并 - 但意外点击 -分支删除)。我的搜索被不必要地延长了,因为当我第一次找到分支时,我并不完全确定名称是否正确,所以一直在寻找,并且花了一些时间重新找到第一个分支。(因此,Carpe Carpum 然后 继续寻找。)