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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3640764/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 09:02:50  来源:igfitidea点击:

Can I recover a branch after its deletion in Git?

gitbranchgit-branch

提问by prosseek

If I run git branch -d XYZ, is there a way to recover the branch? Is there a way to go back as if I didn't run the delete branch command?

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

回答by tfe

Yes, you should be able to do git reflogand find the SHA1 for the commit at the tip of your deleted branch, then just git checkout [sha]. And once you're at that commit, you can just git checkout -b [branchname]to recreate the branch from there.

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



Credit to @Cascabel for this condensed/one-liner version.

此压缩/单行版本归功于@Cascabel。

You can do it in one step:

您可以一步完成:

git checkout -b <branch> <sha>

回答by Philippe

Most of the time unreachable commits are in the reflog. So, the first thing to try is to look at the reflogusing the command git reflog(which display the reflog for HEAD).

大多数情况下,无法访问的提交都在 reflog 中。因此,要尝试的第一件事是使用命令git reflog(显示 的 reflog HEAD)查看 reflog 。

Perhaps something easier if the commit was part of a specific branch still existing is to use the command git reflog name-of-my-branch. It works also with a remote, for example if you forced push (additional advice: alwaysprefer git push --force-with-leaseinstead that better prevent mistakes and is more recoverable).

如果提交是仍然存在的特定分支的一部分,那么使用命令可能更容易git reflog name-of-my-branch。它也适用于遥控器,例如,如果您强制推送(附加建议:总是更喜欢git push --force-with-lease更好地防止错误并且更容易恢复)。



If your commits are not in your reflog(perhaps because deleted by a 3rd party tool that don't write in the reflog), I successfully recovered a branch by reseting my branch to the sha of the commit found using a command like that (it creates a file with all the dangling commits):

如果您的提交不在您的 reflog 中(可能是因为被未写入 reflog 的第 3 方工具删除),我通过将我的分支重置为使用类似命令找到的提交的 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


If you should use it more than one time (or want to save it somewhere), you could also create an alias with that command...

如果您应该多次使用它(或想将其保存在某处),您还可以使用该命令创建一个别名...

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'

and use it with git rescue

并使用它 git rescue

To investigate found commits, you could display each commit using some commands to look into them.

要调查发现的提交,您可以使用一些命令来显示每个提交以查看它们。

To display the commit metadata (author, creation date and commit message):

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

git cat-file -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

To see also the diffs:

还要查看差异:

git log -p 48540dfa438ad8e442b18e57a5a255c0ecad0560

Once you found your commit, then create a branch on this commit with:

一旦你找到你的提交,然后在这个提交上创建一个分支:

git branch commit_rescued 48540dfa438ad8e442b18e57a5a255c0ecad0560


For the ones that are under Windows and likes GUIs, you could easily recover commits (and also uncommited staged files) with GitExtensionsby using the feature Repository=> Git maintenance=> Recover lost objects...

对于那些在 Windows 下并且喜欢 GUI 的人,您可以通过使用功能=> =>使用GitExtensions轻松恢复提交(以及未提交的暂存文件)RepositoryGit maintenanceRecover lost objects...



A similar command to easily recover staged files deleted: https://stackoverflow.com/a/58853981/717372

一个类似的命令可以轻松恢复已删除的暂存文件:https: //stackoverflow.com/a/58853981/717372

回答by nobar

If you like to use a GUI, you can perform the entire operation with gitk.

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

gitk --reflog

This will allow you to see the branch's commit history as if the branch hadn't been deleted. Now simply right click on the most recent commit to the branch and select the menu option Create new branch.

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

回答by Dmitri Zaitsev

The top voted solution does actually more than requested:

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

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

or

或者

git checkout -b <branch> <sha>

move you to the new branch together with all recent changes you might have forgot to commit. This may not be your intention, especially when in the "panic mode" after losing the branch.

将您移动到新分支以及您可能忘记提交的所有最近更改。这可能不是您的本意,尤其是在失去分支后处于“恐慌模式”时。

A cleaner (and simpler) solutionseems to be the one-liner (after you found the <sha>with git reflog):

一个清洁剂(和简单的)解决方案似乎是一个班轮(你找到后<sha>git reflog):

git branch <branch> <sha>

Now neither your current branch nor uncommited changes are affected. Instead only a new branch will be created all the way up to the <sha>.

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

If it is not the tip, it'll still work and you get a shorter branch, then you can retry with new <sha>and new branch name until you get it right.

如果它不是提示,它仍然可以工作并且您会得到一个较短的分支,然后您可以使用新的<sha>和新的分支名称重试,直到正确为止。

Finally you can rename the successfully restored branch into what it was named or anything else:

最后,您可以将成功恢复的分支重命名为它的名称或其他任何名称:

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

Needless to say, the key to success was to find the right commit <sha>, so name your commits wisely :)

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

回答by Jakub Nar?bski

Adding to tfeanswer: there is also the git-resurrect.shscript in the contrib/area of the Git sources (in git.git repository), which might help you.

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

git-resurrect <name>attempts to find traces of a branch tip called <name>, and tries to resurrect it. Currently, the reflog is searched for checkout messages, and with -ralso merge messages. With -mand -t, the history of all refs is scanned for Merge <name> into other/Merge <other> into <name>(respectively) commit subjects, which is rather slow but allows you to resurrect other people's topic branches.

git-resurrect <name>尝试找到名为 的分支尖端的痕迹<name>,并尝试将其复活。目前,在 reflog 中搜索结帐消息和-r合并消息。使用 -mand -t,扫描所有 refs 的历史以查找Merge <name> into other/ Merge <other> into <name>(分别)提交主题,这相当慢,但允许您复活其他人的主题分支。

回答by Patrick Koorevaar

I used the following commands to find and retrieve my deleted branch. The first steps are from gcb's description.

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

Now look for the git commit id (GIT-SHA) based on the commit comments and use it in the command below. Checkout a new branch called NEW-BRANCH with the previously found GIT-SHA:

现在根据提交注释查找 git commit id (GIT-SHA) 并在下面的命令中使用它。使用之前找到的 GIT-SHA 签出一个名为 NEW-BRANCH 的新分支:

$ git checkout -b NEW-BRANCH GIT-SHA

回答by Robert Knight

If you don't have a reflog, eg. because you're working in a bare repository which does not have the reflog enabled and the commit you want to recover was created recently, another option is to find recently created commit objects and look through them.

如果您没有 reflog,例如。因为您正在一个未启用引用日志的裸存储库中工作,并且您要恢复的提交是最近创建的,所以另一种选择是查找最近创建的提交对象并查看它们。

From inside the .git/objectsdirectory run:

.git/objects目录内部运行:

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

This finds all objects (commits, files, tags etc.) created in the last 12 hours and filters them to show only commits. Checking these is then a quick process.

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

I'd try the git-ressurect.sh script mentioned in Jakub's answerfirst though.

不过,我会先尝试Jakub 的回答中提到的 git-ressuret.sh 脚本。

回答by Maxim Mazurok

For GitHubusers without Git installed:

对于未安装 Git 的GitHub用户:

If you want to restore it from GitHubwebsite, you can use their APIto get a list of repo-related events:

如果你想从GitHub网站恢复它,你可以使用他们的 API来获取与 repo 相关的事件列表:

First

第一的

  • find those SHAs (commit hashes):

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

    ... or for private repos:

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

    (will be prompted for GitHub password)

    • (If the repo rquires two-factor auth, see the comments on this answer below.)
  • 找到那些 SHA(提交哈希):

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

    ...或私人回购:

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

    (会提示输入 GitHub 密码)

    • (如果 repo rquires 双重身份验证,请参阅下面对此答案的评论。)

Next

下一个

  • go to GitHuband create a new temporary branch which will be deleted for ever (Chromeis preferable).
  • 转到GitHub并创建一个新的临时分支,该分支将被永久删除(最好使用Chrome)。

   ?  Go to branches and delete that one.

   ? 转到分支并删除该分支。

   ?  On the same page, without reloading, open DevTools, Network panel. Now prepare...

   ?  在同一页面上,无需重新加载,打开 DevTools,Network 面板。现在准备...

   ?  Click restore. You will notice a new "line". Right-click on it and select "Copy as cURL" and save this text in some editor.

   ? 点击恢复。你会注意到一个新的“线”。右键单击它并选择“复制为 cURL”并将此文本保存在某个编辑器中。

   ?  Append to the end of the copied line of code, this one: -H "Cookie=".

   ? 附加到复制的代码行的末尾,这一行:-H "Cookie=".

You should now get something like:

你现在应该得到类似的东西:

    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

Final step

最后一步

  • replace "BranchSHA" with your SHA-hash and BranchName with desired name (BTW, it is great hack to rename branch from web). If you were not too slow, you need to make this request anyhow. For example, just copy-paste to a terminal.
  • 将“BranchSHA”替换为您的 SHA-hash 和带有所需名称的 BranchName(顺便说一句,从网络重命名分支是一个很好的技巧)。如果你不是太慢,无论如何你都需要提出这个请求。例如,只需复制粘贴到终端。

P.S.

聚苯乙烯

I realize this may not be the "simplest solution" or the "right" solution, but it is offered in case someone finds it useful.

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

回答by fabiopagoti

From my understanding if the branch to be deleted can be reached by another branch, you can delete it safely using

根据我的理解,如果要删除的分支可以被另一个分支访问,您可以使用安全删除它

git branch -d [branch]

and your work is not lost. Remember that a branch is not a snapshot, but a pointer to one. So when you delete a branch you delete a pointer.

你的工作不会丢失。请记住,分支不是快照,而是指向一个的指针。所以当你删除一个分支时,你删除了一个指针。

You won't even lose work if you delete a branch which cannot be reached by another one. Of course it won't be as easy as checking out the commit hash, but you can still do it. That's why Git is unable to delete a branch which cannot be reached by using -d. Instead you have to use

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

git branch -D [branch]

This is part of a must watch video from Scott Chacon about Git. Check minute 58:00 when he talks about branches and how delete them.

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

Introduction to Git with Scott Chacon of GitHub

与 GitHub 的 Scott Chacon 一起介绍 Git

回答by uyghurbeg

Make sure to perform all of this locally, and confirm your repo is in the state you desire before pushing to Bitbucket Cloud. It may also be a good idea to clone your current repo, and test these solutions out first.

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

  1. If you just deleted the branch, you'll see something like this in your terminal:
  1. 如果您刚刚删除了分支,您将在终端中看到如下内容:
    Deleted branch <your-branch> (was <sha>)

2.To restore the branch, use:

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

    git checkout -b <branch> <sha>

If you don't know the 'sha' off the top of your head, you can:

如果您不知道头顶上的“sha”,您可以:

  1. Find the 'sha' for the commit at the tip of your deleted branch using:
  1. 使用以下命令在已删除分支的尖端找到提交的“sha”:
    git reflog
  1. To restore the branch, use:
  1. 要恢复分支,请使用:
    git checkout -b <branch> <sha>

If your commits are not in your reflog:

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

  1. You can try recovering a branch by reseting your branch to the sha of the commit found using a command like:
  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.You can then display each commit using one of these:

2. 然后,您可以使用以下方法之一显示每个提交:

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