Git:恢复已删除的(远程)分支

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1992364/
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 07:36:14  来源:igfitidea点击:

Git: Recover deleted (remote) branch

gitgithub

提问by Craig Walker

I need to recover two Git branches that I somehow deleted during a push.

我需要恢复在推送过程中以某种方式删除的两个 Git 分支。

These two branches were created on a different system and then pushed to my "shared" (github) repository.

这两个分支是在不同的系统上创建的,然后推送到我的“共享”(github)存储库。

On my system, I (apparently) retrieved the branches during a fetch:

在我的系统上,我(显然)在获取期间检索了分支:

~/myfolder> git fetch
remote: Counting objects: 105, done.
remote: Compressing objects: 100% (58/58), done.
remote: Total 62 (delta 29), reused 0 (delta 0)
Unpacking objects: 100% (62/62), done.
From github.com:mygiturl
 * [new branch]      contact_page -> origin/contact_page
   731d1bb..e8b68cc  homepage   -> origin/homepage
 * [new branch]      new_pictures -> origin/new_pictures

Right after that I did a push to send my local changes up to the central repo. For some reason, these branches were deleted from both my local system and the central repo:

在那之后,我推动将我的本地更改发送到中央存储库。出于某种原因,这些分支已从我的本地系统和中央存储库中删除:

~/myfolder> git push
Counting objects: 71, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (43/43), done.
Writing objects: 100% (49/49), 4.99 KiB, done.
Total 49 (delta 33), reused 0 (delta 0)
To [email protected]:mygiturl.git
 - [deleted]         contact_page
 + e8b68cc...731d1bb homepage -> homepage (forced update)
   bb7e9f2..e0d061c  master -> master
 - [deleted]         new_pictures
   e38ac2e..bb7e9f2  origin/HEAD -> origin/HEAD
   731d1bb..e8b68cc  origin/homepage -> origin/homepage
   e38ac2e..bb7e9f2  origin/master -> origin/master
 * [new branch]      origin/contact_page -> origin/contact_page
 * [new branch]      origin/new_pictures -> origin/new_pictures

It's not terribly easy to get the branches off of their birthplace machine, so I'd like to try and recover them from my local if possible.

从他们的出生地机器上取下树枝并不容易,所以如果可能的话,我想尝试从我的本地恢复它们。

All of the git "undo" information I've googled has to with recovering lost commits. I don't think that applies here, since I don't have commit UIDs for these branches.

我在谷歌上搜索过的所有 git“撤消”信息都与恢复丢失的提交有关。我认为这不适用于这里,因为我没有为这些分支提交 UID。

I'd like to know how I can get these back. I'd also like to know how they were deleted in the first place and how I can avoid this in the future.

我想知道我怎样才能把这些拿回来。我还想知道它们最初是如何被删除的,以及我将来如何避免这种情况。

EDIT: by request, here's my repo configuration

编辑:根据要求,这是我的回购配置

user.name=Craig Walker
[email protected]
alias.unadd=reset HEAD
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
[email protected]:MyGitURL.git
remote.origin.mirror=true
branch.master.remote=origin
branch.master.merge=refs/heads/master
alias.undo=reset --hard
alias.test=push -f ci HEAD:master
alias.st=status
alias.ci=commit
alias.br=branch
alias.co=checkout
alias.ch=checkout
alias.df=diff
alias.lg=log -p
alias.who=shortlog -s --
remote.ci.url=ContinuousIntegrationGitURL
remote.ci.fetch=+refs/heads/*:refs/remotes/ci/*
branch.photo.remote=origin
branch.photo.merge=refs/heads/photos
remote.foo.url=FooGitURL
remote.foo.fetch=+refs/heads/*:refs/remotes/cynthia/*
branch.homepage.remote=origin
branch.homepage.merge=refs/heads/homepage

回答by iamamac

I'm not an expert. But you can try

我不是专家。但是你可以试试

git fsck --full --no-reflogs | grep commit

to find the HEAD commit of deleted branch and get them back.

找到已删除分支的 HEAD 提交并将它们取回。

回答by chinnawatp

just two commands save my life

只需两个命令就能救我一命

1. This will list down all previous HEADs

1. 这将列出所有以前的 HEAD

git reflog

2. This will revert the HEAD to commit that you deleted.

2. 这会将 HEAD 还原为您删除的提交。

git reset --hard <your deleted commit>
ex. git reset --hard b4b2c02

回答by Chris Johnsen

Your deleted branches are not lost, they were copied into origin/contact_pageand origin/new_pictures“remote tracking branches” by the fetch you showed (they were also pushed back out by the push you showed, but they were pushed into refs/remotes/origin/ instead of refs/heads/). Check git log origin/contact_pageand git log origin/new_picturesto see if your local copies are “up to date” with whatever you think should be there. If any new commits were pushed onto those branches (from some other repo) between the fetch and push that you showed, you may have “lost” those (but probably you could probably find them in the other repo that most recently pushed those branches).

您删除的分支没有丢失,它们被您显示的提取复制到origin/contact_pageorigin/new_pictures“远程跟踪分支”(它们也被您显示的推送推回,但它们被推入 refs/remotes/ origin/ 而不是 refs/heads/)。检查git log origin/contact_pagegit log origin/new_pictures查看您的本地副本是否与您认为应该存在的内容“保持同步”。如果在您显示的 fetch 和 push 之间有任何新提交被推送到这些分支(来自其他某个 repo),您可能已经“丢失”了那些(但可能您可能会在最近推送这些分支的另一个 repo 中找到它们) .

Fetch/Push Conflict

获取/推送冲突

It looks like you are fetching in a normal, ‘remote mode' (remote refs/heads/ are stored locally in refs/remotes/origin/), but pushing in ‘mirror mode' (local refs/ are pushed onto remote refs/). Check your .git/config and reconcile the remote.origin.fetchand remote.origin.pushsettings.

看起来您正在以正常的“远程模式”获取(远程 refs/heads/ 本地存储在 refs/remotes/origin/ 中),但以“镜像模式”推送(本地 refs/ 被推送到远程 refs/) . 检查您的 .git/config 并协调remote.origin.fetchremote.origin.push设置。

Make a Backup

进行备份

Before trying any changes, make a simple tar or zip archive or your whole local repo. That way, if you do not like what happens, you can try again from a restored repo.

在尝试任何更改之前,制作一个简单的 tar 或 zip 存档或整个本地存储库。这样,如果您不喜欢发生的事情,您可以从恢复的回购中重试。

Option A: Reconfigure as a Mirror

选项 A:重新配置为镜像

If you intend to use your remote repo as a mirror of your local one, do this:

如果您打算将远程仓库用作本地仓库的镜像,请执行以下操作:

git branch contact_page origin/contact_page &&
git branch new_pictures origin/new_pictures &&
git config remote.origin.fetch '+refs/*:refs/*' &&
git config --unset remote.origin.push &&
git config remote.origin.mirror true

You might also eventually want to do delete all your refs/remotes/origin/ refs, since they are not useful if you are operating in mirror mode (your normal branches take the place of the usual remote tracking branches).

您可能最终还想删除所有的 refs/remotes/origin/refs,因为如果您在镜像模式下操作它们就没有用了(您的正常分支取代了通常的远程跟踪分支)。

Option B: Reconfigure as a Normal Remote

选项 B:重新配置为普通遥控器

But since it seems that you are using this remote repo with multiple “work” repos, you probably do not want to use mirror mode. You might try this:

但是,由于您似乎正在将此远程存储库与多个“工作”存储库一起使用,因此您可能不想使用镜像模式。你可以试试这个:

git config push.default tracking &&
git config --unset remote.origin.push
git config --unset remote.origin.mirror

Then, you will eventually want to delete the bogus refs/remotes/origin refs in your remote repo: git push origin :refs/remotes/origin/contact_page :refs/remotes/origin/new_pictures ….

然后,你最终将要删除的假裁判/遥控器/产地裁判在远程回购:git push origin :refs/remotes/origin/contact_page :refs/remotes/origin/new_pictures …

Test Push

测试推送

Try git push --dry-runto see what it git pushwould do without having it make any changes on the remote repo. If you do not like what it says it is going to do, recover from your backup (tar/zip) and try the other option.

尝试git push --dry-run看看它git push会做什么,而无需对远程存储库进行任何更改。如果您不喜欢它所说的内容,请从您的备份 (tar/zip) 中恢复并尝试其他选项。

回答by Timmy

If the delete is recent enough (Like an Oh-NO! moment) you should still have a message:

如果删除是最近的(就像一个 Oh-NO!时刻),您仍然应该有一条消息:

Deleted branch <branch name> (was abcdefghi).

Deleted branch <branch name> (was abcdefghi).

you can still run:

你仍然可以运行:

git checkout abcdefghi

git checkout abcdefghi

git checkout -b <some new branch name or the old one>

git checkout -b <some new branch name or the old one>

回答by Hymanzhoumine

  1. find out coimmit id

    git reflog

  2. recover local branch you deleted by mistake

    git branch need-recover-branch-name commitId

  3. push need-recover-branch-name again if you deleted remote branch too before

    git push origin need-recover-branch-name

  1. 找出 coimmit id

    git reflog

  2. 恢复你误删的本地分支

    git 分支需要恢复分支名称 commitId

  3. 如果您之前也删除了远程分支,请再次推送需要恢复分支名称

    git push origin 需要恢复分支名称

回答by jhilden

The data still exists out in github, you can create a new branch from the old data:

数据仍然存在于github中,您可以从旧数据创建一个新分支:

git checkout origin/BranchName #get a readonly pointer to the old branch
git checkout –b BranchName #create a new branch from the old
git push origin BranchName #publish the new branch

回答by CB Bailey

I think that you have a mismatched config for 'fetch' and 'push' so this has caused default fetch/push to not round trip properly. Fortunately you have fetched the branches that you subsequently deleted so you should be able to recreate them with an explicit push.

我认为您的 'fetch' 和 'push' 配置不匹配,因此这导致默认的 fetch/push 无法正常往返。幸运的是,您已经获取了随后删除的分支,因此您应该能够通过显式推送重新创建它们。

git push origin origin/contact_page:contact_page origin/new_pictures:new_pictures

回答by Roralee

If your organization uses JIRA or another similar system that is tied into git, you can find the commits listed on the ticket itself and click the links to the code changes. Github deletes the branch but still has the commits available for cherry-picking.

如果您的组织使用 JIRA 或其他与 git 相关联的类似系统,您可以找到工单本身上列出的提交,然后单击代码更改的链接。Github 删除了该分支,但仍有可供挑选的提交。

回答by Artorias2718

It may seem as being too cautious, but I frequently zip a copy of whatever I've been working on before I make source control changes. In a Gitlab project I'm working on, I recently deleted a remote branch by mistake that I wanted to keep after merging a merge request. It turns out all I had to do to get it back with the commit history was push again. The merge request was still tracked by Gitlab, so it still shows the blue 'merged' label to the right of the branch. I still zipped my local folder in case something bad happened.

这可能看起来过于谨慎,但我经常在进行源代码控制更改之前压缩我一直在处理的任何内容的副本。在我正在处理的 Gitlab 项目中,我最近错误地删除了一个远程分支,我想在合并合并请求后保留该分支。事实证明,我所要做的就是再次推送提交历史记录。Gitlab 仍会跟踪合并请求,因此它仍会在分支右侧显示蓝色的“已合并”标签。我仍然压缩了我的本地文件夹,以防万一发生了不好的事情。