我可以在Git中删除分支后恢复分支吗?

如果我运行git branch -d XYZ,有没有办法恢复分支?有没有办法回去,就好像我没有运行删除分支命令一样?

561909 次浏览

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


感谢@CasCabel提供了这个浓缩/单行版本,并感谢@Snow崩溃提供了如何获得sha。

如果您刚刚删除了分支,您将在终端Deleted branch <your-branch> (was <sha>)中看到类似的内容。然后只需在此单行程序中使用<sha>

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

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

git-resurrect <name>尝试查找分支尖端的痕迹<name>,并试图复活它。目前,reflg是搜索结帐消息,并且使用-r还合并消息。随着-m-t,扫描所有引用的历史记录以将Merge合并到其他/Merge <other> into <name>(分别)提交主题,其中是相当缓慢,但允许你复活别人的话题分支。

根据我的理解,如果要删除的分支可以被另一个分支到达,您可以使用

git branch -d [branch]

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

如果你删除一个分支无法被另一个分支到达,你甚至不会失去工作。当然,这不会像检查提交哈希那样容易,但你仍然可以做到。这就是为什么Git无法删除使用-d无法到达的分支。相反,你必须使用

git branch -D [branch]

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

GitHub的Scott Chacon介绍Git

如果你没有reflg,例如,因为你在一个没有启用reflg的裸存储库中工作,并且你想要恢复的提交是最近创建的,另一个选择是找到最近创建的提交对象并查看它们。

.git/objects目录中运行:

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

这会查找在过去12小时内创建的所有对象(提交、文件、标签等)并过滤它们以仅显示提交。然后检查这些是一个快速过程。

我会先尝试雅库布的回答中提到的git-ressurect.sh脚本。

当您的提交在reflog

大多数时候,无法访问的提交都在reflg中。所以,要做的第一件事就是看重新发布使用命令git reflog(它显示HEAD的reflg)。

如果提交是特定且仍然存在的分支的一部分,也许更容易使用命令git reflog name-of-my-branch。它也适用于远程,例如,如果您有强制推送(尽管应该使用git push --force-with-lease来防止错误并且更可恢复)。


当他们不在reflog

如果你的提交不在你的reflg中(也许它们被一个没有写入reflg的第三方工具删除了),你可以先尝试这个命令来创建一个包含所有悬空提交的文件

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可以通过菜单Repository=>Git maintenance=>Recover lost objects...轻松恢复代码扩展工具的提交(也是未提交的暂存文件)

相关:轻松恢复以前暂存的已删除文件

首先转到git批处理移动到您的项目,如下所示:

cd android studio projectcd Myprojectthen type :git reflog

你们都有一个更改列表,参考号取参考号,然后从Android工作室或git betcha结帐
。另一个解决方案是参考号,然后去android工作室点击git分支,然后点击签出标签或修订过去的参考号,然后lol你有分支。

我从远程重新定位了一个分支,试图清除一些我不想要的提交,并打算挑选我想要的正确提交。

这是我如何找到它们(主要是一个更容易的界面/交互从答案在这里):

首先,在日志中生成松散提交列表。尽快执行此操作并停止工作,因为这些可能会被垃圾收集器转储。

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

这将向您显示每个选项的差异和提交信息。然后等待您按输入。现在写下所有您想要的选项,然后选择它们。完成后,只需按Ctrl-C键。

投票最多的解决方案实际上比要求的要多:

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>,所以明智地命名你的提交:)

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

gitk --reflog

这将允许您查看分支的提交历史,就好像分支没有被删除一样。现在只需右键单击最近提交到分支并选择菜单选项Create new branch

要恢复已删除的分支,首先查看reflg历史记录,

git reflog -n 60

其中n指的是最后n个提交。然后找到合适的头部并使用该头部创建一个分支。

git branch testbranch HEAD@{30}

除了tfe的回答,你可以用上面提到的这个过程来恢复,除非它的提交没有被垃圾回收。Git分支只是一个指向提交树中特定提交的指针。但是如果你删除了指针,并且该分支上的提交没有合并到其他现有分支中,那么git会将其视为悬空提交,并在垃圾回收机制期间删除它们,它可能会定期自动运行。

如果您的分支没有合并到现有分支,并且如果它是垃圾回收的,那么您将丢失所有提交,直到从现有分支分叉分支的位置。

对于没有安装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密码)

    • (如果回购请求双因素身份验证,请参阅下面对此答案的评论。

下一个

  • 转到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哈希替换“布兰奇SHA”,并用所需的名称替换“布兰奇名称”(顺便说一句,从Web重命名分支是很好的黑客)。如果你不是太慢,你无论如何都需要发出这个请求。例如,只是复制粘贴到终端。

P. S.

我知道这可能不是“最简单的解决方案”或“正确的”解决方案,但它是在有人发现它有用的情况下提供的。

我使用以下命令查找和检索已删除的分支。第一步来自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提交ID(GIT-SHA)并在下面的命令中使用它。使用之前找到的GIT-SHA签出一个名为NEW-BRANCH的新分支:

$ git checkout -b NEW-BRANCH GIT-SHA

确保在本地执行所有这些,并确认你的存储库处于你想要的状态,然后再推送到比特桶云。克隆你当前的存储库,并首先测试这些解决方案可能也是一个好主意。

  1. 如果您刚刚删除了分支,您将在终端中看到类似这样的内容:
    Deleted branch <your-branch> (was <sha>)

2.要恢复分支,请使用:

    git checkout -b <branch> <sha>

如果你不知道你头顶上的“沙”,你可以:

  1. 使用以下命令在已删除分支的尖端找到提交的'sha':
    git reflog
  1. 要恢复分支,请使用:
    git checkout -b <branch> <sha>

如果您的提交不在您的reflg中:

  1. 您可以尝试通过使用以下命令将您的分支重置到找到的提交的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>

仅仅使用git reflog并没有为我返回sha。只有commit id(8个字符长,一个sha更长)

我用git reflog --no-abbrev

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

大是

如果您正在使用GIT遵循这些简单的步骤https://confluence.atlassian.com/bbkb/how-to-restore-a-deleted-branch-765757540.html

如果你正在使用智能git并且已经推送了该分支转到原点,找到该分支并右键单击然后签出

我在删除分支的计算机上这样做:

git reflog

答复:

74b2383 (develope) HEAD@{1}: checkout: moving from master to develope40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{2}: checkout: moving from develope to master74b2383 (develope) HEAD@{3}: checkout: moving from master to develope40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{4}: reset: moving to HEAD40ef328 (HEAD -> master, origin/master, origin/HEAD) HEAD@{5}: clone: from http://LOCALGITSERVER/myBigProject/Android.git

我用这个命令检索分支:

git checkout -b newBranchName 74b2383

如果您正在使用VSCode…,您在删除分支之前的某个时间点与服务器同步…

请注意,git分支删除只会删除本地副本,而不是删除服务器上的副本。首先,在Git面板(左侧工具栏上的git图标)中,查看分支,看看你的分支是否还在“源/your_branch_name”下。如果是,只需选择它,你应该会取回你的代码(建议你立即将其复制/粘贴/保存到本地其他地方)。

如果您没有看到“源/your_branch_name”,请安装GitLens扩展。这允许您直观地在服务器存储库中四处寻找并找到您同步到服务器的副本。如果您有多个存储库,请注意,可能需要从所需的存储库中打开至少一个文件才能使存储库出现在GitLens中。然后:

  1. 打开GitLens面板

  2. 扩展存储库

  3. 您应该会看到一个类别列表:分支/贡献者/远程调用/隐藏/等

您应该会在“分支”下或可能在“重新定位->起源”下找到YourLost宝藏。希望您会看到具有所需名称的分支-如果您展开它,您应该会看到您在该分支中更改的文件。双击文件名以打开它们,并立即备份该代码。

如果你没有立即看到你丢失的分支,四处看看,如果你发现有希望的东西,立即打开它并获取代码。我不得不四处寻找了很长时间,直到找到TheGolden布兰奇,即使这样,代码也缺少最后一次或两次保存(可能是因为我在尝试-分支-合并-但-意外-点击-分支-删除之前未能同步到服务器)。我的搜索被不必要地延长了,因为当我第一次找到分支时,我不完全确定名称是否正确,所以一直在寻找,并且花了一些时间重新找到第一个分支。(因此,Carpe Carpa和<强>然后继续看)。

如果您删除了分支并忘记了其提交ID,您可以执行以下命令:

git log --graph --decorate $(git rev-list -g --all)

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

如果您正在使用Git扩展

虽然很旧,但当你谷歌恢复已删除的分支时,这个线程是列表的顶部。我使用git扩展而不是命令行,所以不熟悉命令,但重排命令给了我一个线索,所以我在这里发布了我的git扩展解决方案,供其他使用git扩展的人阅读。

  1. 转到工具栏上的查看下拉列表
  2. 选择显示reflg引用

您删除的分支现在应该是可见和可选择的,只需单击它并检查它。

恢复已删除分支的一般问题的一个非常常见的子问题是在合并后恢复功能分支,然后将其删除-这是常见的做法。

正如这个so帖子所涵盖的,如果已成功合并,您始终可以恢复已删除的分支。这是因为分支只是指向提交的花哨指针,并且因为您已合并,提交仍在那里。合并提交将列出合并的两个(或多个)分支的头提交的哈希值。例如:

        git show mastercommit 849675951d41497e7b07d34096ebf36dc713221 (HEAD -> master)Merge: fc1c9ce 97f8a60Author: MeDate:   Sun Jan 9 16:14:24 2022 +0100
Merge branch 'feature'

因此,您可以通过执行git checkout -b feature 97f8a60来恢复删除“功能”分支-不需要任何reflg内容。

谢谢你们所有人。

我的问题是我在GitLab(远程)和GIT(本地)上删除了我的分支。

但不知何故,我像这样拿回了我的提交:

  1. 首先我得到了最后一次提交(SHA)
git log --graph --decorate $(git rev-list -g --all)
  1. 我结帐最后SHA简单
git checkout <SHA>
  1. 然后我通过键入创建了一个全新的分支(如你所愿命名)
git switch -c <branch-name>

然后我得到了我的承诺,我再次推了分支

谢天谢地。

ps:不知何故(SHA)是一个提交代码

如果您已经将分支推送到远程服务器,那么请尝试使用git checkout <branch>,git将尝试从您本地机器中的最后一个源镜像中克隆。

第一类

git reflog

在终端。

之后,获取HEAD@{**number**}(例如HEAD@{12})。

现在输入:

git checkout -b 'branch_name' 'HEAD@{22}'