如果我运行git branch -d XYZ,是否可以恢复分支?有没有办法像我没有运行delete branch命令一样返回?

评论

关于接受的答案,一个非常令人敬畏的注释是,即使该分支在原始位置被删除,它仍然有效!我只是恢复了几个分支,这些分支原本被不小心删除了。

#1 楼

是的,您应该能够执行git reflog --no-abbrev并在已删除分支的顶端找到提交的SHA1,然后只需git checkout [sha]即可。一旦完成该提交,您就可以通过git checkout -b [branchname]从那里重新创建分支。

此压缩/单线版本的信用额为@Cascabel。
您可以在第一步:
git checkout -b <branch> <sha>


评论


您可以一步完成:git checkout -b <分支>

–卡斯卡贝尔
2010年9月4日下午14:19

快速提示-如果您刚刚删除了分支,您将在终端中看到类似的内容-“已删除分支(was )”。然后,这非常简单-只需使用。例如,如上所述-git checkout -b <分支>

–雪崩
2014年5月29日14:37

是的,只是在您的终端中向上滚动(除非您执行了CMD + K)

–肺炎
15年5月20日在20:50

使用git reflog --no-abbrev查看默认情况下缩写的完整

– jkulak
15年11月11日在11:28

对于像我这样的其他人,他们很难找到已删除分支的影子:我能够git checkout remotes / origin / deleted_branch。

–杰夫·欧文(Jeff Irwin)
17年7月7日在13:04

#2 楼

大多数情况下,无法到达的提交都在reflog中。因此,首先要尝试的是使用命令git reflog(显示HEAD的引用日志)查看引用日志。

如果提交是仍存在的特定分支的一部分,也许更容易一些使用命令git reflog name-of-my-branch。它也可用于远程操作,例如,如果您强行按下(其他建议:请始终选择git push --force-with-lease而不是更好地防止错误并且更可恢复)。


如果您的提交不在您的reflog中(也许是因为被未写入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



一次(或想将其保存在某处),您也可以使用该命令创建别名...

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 rescue

要调查已发现的提交,可以使用一些命令显示每个提交以对其进行查看。

要显示提交元数据(作者,创建日期和提交消息):

git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560


还要查看差异:

git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560


找到提交后,请使用以下命令在此提交上创建分支:

git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560



对于Windows下喜欢GUI的用户,您可以轻松地恢复c通过使用功能Repository => Git maintenance => Recover lost objects...使用GitExtensions省略(以及未提交的暂存文件),类似的命令可轻松恢复已删除的暂存文件:https://stackoverflow.com / a / 58853981/717372

评论


巨大的帮助。我有一个丢失的提交,从未在本地存储区中提交过。您在那里的第一个命令帮助我在服务器上找到了它。 +1

– Sean Adkinson
17年6月30日19:00

那个git抢救别名真是天赐!!!非常感谢您的贡献!

– 72A12F4E
18年1月16日在18:28

你救了我的命。

–杰德·林奇
19年8月5日在19:33

@ Monir-Khan和?我应该得出什么结论?帕特里克(Patrick)的回答只是我命令的复制/粘贴(有一个错误:他忘记对提交进行过滤)...

–菲利普
2月28日18:14

@Philippe谢谢您的详细解释!谢谢,作品像个魅力。

– Alex
5月11日23:48



#3 楼

如果您想使用GUI,则可以使用gitk执行整个操作。

gitk --reflog


这将使您可以查看分支的提交历史记录,就好像分支没有被删除。现在,只需右键单击对分支的最新提交,然后选择菜单选项Create new branch

评论


谢谢,我不知道那一个。几天前删除分支时,已经有两周没有检出它了,不记得它叫什么了,也没有外壳历史记录...这节省了我的钱。

–戈登·箭牌(Gordon Wrigley)
8月28日12:45

#4 楼

票数最高的解决方案实际上超出了要求:

git checkout <sha>
git checkout -b <branch>




git checkout -b <branch> <sha>


将您带到新的分支以及您可能忘记提交的所有最近更改。这可能不是您的意图,特别是在丢失分支后处于“紧急模式”时。

一种更简洁(更简单)的解决方案似乎是一线解决方案(在您找到带有<sha>git reflog之后):

git branch <branch> <sha>


现在,您当前的分支和未提交的更改都不会受到影响。相反,将一直创建一个新分支直到<sha>

如果不是技巧,它仍然可以工作,并且您得到较短的分支,则可以尝试使用新的<sha>和新的分支名称,直到正确为止。

最后,您可以将成功还原的分支重命名为该分支的名称或其他名称:

git branch -m <restored branch> <final branch>


不用说,成功的关键是找到正确的提交<sha>,所以要明智地命名您的提交:)

#5 楼

添加到tfe答案:Git源(在git.git存储库中)的contrib/区域中还存在git-resurrect.sh脚本,可能会为您提供帮助。


git-resurrect <name>尝试查找痕迹的痕迹
<name>,然后尝试将其复活。当前,在reflog中搜索结帐消息,并使用-r合并消息。使用
-m-t,将扫描所有裁判的历史记录,以分别查找Merge <name> into other / Merge <other> into <name>提交主题,这虽然很慢,但可以让您复活其他人的主题
分支。
/>

评论


尽管我必须将/ usr / lib / git-core /添加到PATH,但它现在对我有用。但是它并没有实现我希望的奇迹:(

– AmanicA
2015年11月27日4:59



#6 楼

我使用以下命令来查找和检索删除的分支。第一步来自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


评论


非常感谢你。花了一些时间搜索名称,但是值得。如果有一种方法也可以搜索提交消息字符串,那就更好了。

– Monir Khan
2月28日14:53



#7 楼

如果您没有reflog,例如。因为您正在一个没有启用reflog的裸仓库中工作,并且您要恢复的提交是最近创建的,所以另一个选择是找到最近创建的提交对象并对其进行浏览。

从在.git/objects目录中运行:

find . -ctime -12h -type f | sed 's/[./]//g' | git cat-file --batch-check | grep commit


这将查找最近12小时内创建的所有对象(提交,文件,标签等),并将其过滤以仅显示提交。检查这些是一个快速的过程。

我会先尝试Jakub的答案中提到的git-ressurect.sh脚本。

评论


不错的选择!您的命令虽然会引发错误。问题出在“ 12h”部分(实际上是“ h”)。一旦删除了“ h”,它就可以正常工作。从人身上发现:“-ctime n-文件状态在n * 24小时前最后一次更改。”因此,我们还应该将12更改为0.5以具有最近12小时的预期行为。

–pagliuca
13年5月15日在12:23



我在这里使用OS X 10.8,因此上面的'find'标志基于它附带的版本。

–罗伯特·奈特(Robert Knight)
13年5月15日在13:13

是的,确定问题出在版本上!这就是为什么我首先赞成您的答案!我刚刚发表评论,使人们意识到参数可能有所不同。

–pagliuca
13年5月15日在17:29

#8 楼

对于未安装Git的GitHub用户:

如果要从GitHub网站还原它,可以使用其API获取与回购相关的事件的列表:

First



找到那些SHA(提交哈希):

curl -i https://api.github.com/repos/PublicUser/PublicRepo/events

...或用于私人仓库:

curl -su YourUserName https://api.github.com/repos/YourUserName/YourProject/events

(系统会提示您输入GitHub密码)


(如果仓库要求二元身份验证,请参见此注释在下面回答。)



下一个


转到GitHub并创建一个新的临时分支,该分支将永远删除(Chrome浏览器最好)。

•转到分支并将其删除。

•在同一页面上,无需重新加载,打开DevTools,“网络”面板。现在准备...

•单击还原。您会注意到一个新的“行”。右键单击它,然后选择“复制为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哈希替换“ BranchSHA”和具有所需名称的BranchName(顺便说一句,从Web重命名分支是一个很好的技巧)。如果您不太慢,则无论如何都需要发出此请求。例如,只需将其复制粘贴到终端即可。

PS

我意识到这可能不是“最简单的解决方案”或“正确的”解决方案,但可以提供万一有人觉得有用。

评论


上面是不依赖git reflog的少数几个方法之一,因此例如在删除远程分支并失去对计算机的访问权限时很有用,因为这样做无法从reflog获得任何有用的帮助。请注意,在Github上使用OAuth或两因素身份验证时,curl命令的形式为:curl -u用户名:令牌https://api.github.com/user或curl -H“授权:令牌令牌” https:// api.github.com/repos/USER_OR_ORG_NAME/REPO_NAME/events

– TT--
19年4月18日在17:25

@ TT--哇,我很高兴它有所帮助!并感谢您对身份验证令牌的贡献:)

– Maxim Mazurok
19年4月19日在12:06

#9 楼

据我了解,如果要删除的分支可以被另一个分支访问,则可以使用

git branch -d [branch]


安全地删除它,而您的工作也不会丢失。请记住,分支不是快照,而是指向它的指针。因此,当删除分支时,会删除一个指针。

如果删除另一个分支无法访问的分支,您甚至不会丢失工作。当然,它不像检出提交哈希那样简单,但是您仍然可以做到。这就是为什么Git无法删除使用-d无法到达的分支。相反,您必须使用

git branch -D [branch]


,这是Scott Chacon关于Git的必看视频的一部分。检查58:00分钟,当他谈论分支以及如何删除它们时。

GitHub的Scott Chacon介绍Git

评论


这如何帮助回答问题?

–德米特里·扎伊采夫(Dmitri Zaitsev)
15年4月28日在13:36



告诉质问者分支不保存内容,但实际上是指针。您不必担心删除分支..您可以创建指向与已删除分支相同的提交的新分支。我仍然记得我问这个问题的时候。美好的时光回到2012年!

–fabiopagoti
15年4月28日在19:04

不得不将三个屏幕滚动到“最后”,找到解决该问题的答案:删除分支就是删除一个纯指针。这里没有数据丢失的情况,唯一要恢复的是它指向的位置。直接进入reflog的答案实在是太过分了。

– RomainValeri
19年1月18日在19:38

#10 楼

确保在本地执行所有这些操作,并在推送到Bitbucket Cloud之前确认您的存储库处于所需状态。克隆当前回购并首先测试这些解决方案也是一个好主意。


如果您刚刚删除了分支,您将在终端中看到类似以下内容:

    Deleted branch <your-branch> (was <sha>)


2.要还原分支,请使用:

    git checkout -b <branch> <sha>


如果您不知道'sha'离开您的头顶,您可以:


使用以下方法在已删除分支的顶端找到提交的“ sha”:

    git reflog



要恢复分支,请使用:

    git checkout -b <branch> <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.You然后可以使用以下选项之一显示每个提交:

    git log -p <commit>
    git cat-file -p <commit>


#11 楼

要恢复已删除的分支,请首先遍历reflog历史记录,其中n表示最后n次提交。然后找到合适的头并使用该头创建分支。

git reflog -n 60


#12 楼

我从远程重新建立了一个分支,以尝试清除一些我不想要的提交,并将挑选出我想要的正确提交。当然,我把SHAs写错了...

这是我找到它们的方式(主要是从这里的答案得到的界面/交互更容易):

首先,生成一个日志中的松散提交列表。尽快执行此操作并停止工作,因为垃圾收集器可能会将其丢弃。

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即可。

#13 楼

大是

如果您使用的是GIT
,请遵循以下简单步骤
https://confluence.atlassian.com/bbkb/how-to-restore-a-deleted-branch -765757540.html

如果您使用的是smartgit并已将该分支推送到源
,请找到该分支,然后右键单击然后结帐

#14 楼

我在删除分支的计算机上执行了此操作:

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

#15 楼

首先转到git batch移动到您的项目,例如:

cd android studio project
cd Myproject
then type :
git reflog


你们都有变更列表,参考号带有参考号,然后从android studio签出或从git betcha中获取。
另一种解决方案采用参考编号,然后转到android studio,向下单击git分支,然后单击参考编号后的checkout标签或修订,然后大声笑,您拥有分支。

#16 楼

添加到tfe的答案中,您可以使用上述过程进行恢复,除非未对这些提交进行垃圾收集。 Git分支只是指向提交树中特定提交的指针。但是,如果删除了指针,并且该分支上的提交未合并到其他现有分支中,则git将其视为悬空提交并在垃圾回收期间将其删除,它可能会定期自动运行。

如果您的分支未合并到现有分支,并且已被垃圾回收,那么您将松散所有提交,直到分支从现有分支派生到分支为止。

#17 楼

一个相关的问题:
我在搜索“如何知道被删除的分支是什么”之后来到了此页面。

删除许多旧分支时,我却错误地删除了其中一个较新的分支,但是不知道要恢复的名称。

要了解最近删除了哪些分支,请执行以下操作:

如果转到Git URL,它将看起来像像这样的内容:

https://your-website-name/orgs/your-org-name/dashboard


然后您可以看到最近的提要,删除的内容,被谁删除的内容。

评论


当然。上面的答案是针对GitHub的。我们在本地安装了GitHub。感谢您提出问题。

–Manohar Reddy Poreddy
17年5月14日在13:47



#18 楼

仅使用git reflog不会为我返回sha
只有commit id(长8个字符,sha更长)

所以我用了
git reflog --no-abbrev

,然后执行与上面提到的:
git checkout -b <branch> <sha>

评论


您可以始终使用缩写的8字符阴影,而不必使用完整的阴影

– Michael Dreher
19年9月7日在12:59

#19 楼

如果您使用的是VSCode ...,并且在删除分支之前已将分支与服务器同步...
请注意git branch delete仅删除本地副本,而不删除服务器上的副本。首先,在Git面板(左侧工具栏上的git图标)中,浏览分支并查看分支在“ origin / your_branch_name”下是否仍然存在。如果是这样,请选择该代码,然后应该找回代码(建议您立即将其复制/粘贴/保存在其他地方)。
如果没有看到“ origin / your_branch_name”,请安装GitLens扩展程序。这使您可以直观地在服务器存储库中四处浏览,并找到同步到服务器的副本。如果您有多个存储库,请注意,可能需要从所需的存储库中至少打开一个文件,以使该存储库出现在GitLens中。然后:


打开GitLens面板


扩展存储库


您应该看到一个列表类别:分支机构/贡献者/远程控制器/哈希值/ etc


您应该在“分支”下或可能在“ Remotes-> Origins”下找到YourLostTreasure。希望您会看到一个具有所需名称的分支-如果展开它,您应该会看到在该分支中更改的文件。双击文件名将其打开,然后立即备份该代码。
如果您没有立即看到丢失的分支,请四处寻找,如果发现有希望的东西,请立即打开它并获取代码。我不得不四处摸索,直到找到TheGoldenBranch,即使这样,代码也丢失了最后的一两次保存(可能是因为在尝试进行“分支合并”之前,我未能同步到服务器,但偶然地单击了“删除分支)。我的搜索被不必要地延长了,因为当我第一次找到该分支时,我并不完全确定名称是否正确,因此一直在寻找,并且花了一些时间来重新找到第一个分支。 (因此,Carpe Carpum,然后继续查看。)

#20 楼

如果您删除了分支并忘记了它的提交ID,则可以执行以下命令:
git log --graph --decorate $(git rev-list -g --all)

之后,您将可以看到所有提交。
然后您可以对这个ID执行git checkout并在此提交下创建一个新分支。