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

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

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

在我的系统中,我(显然)在读取过程中检索到了树枝:

~/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

在那之后,我做了一个推动发送我的本地变化到中央回购。出于某种原因,这些分支机构从我的本地系统和中央回购系统中都被删除了:

~/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 git@github.com: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

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

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

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

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

user.name=Craig Walker
user.email=github@softcraft.ca
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/*
remote.origin.url=git@github.com: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
141794 次浏览

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

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

找到已删除分支的 HEAD 提交并将其返回。

您删除的分支并没有丢失,它们通过您显示的提取被复制到 起源/联系页面起源/新 _ 图片“远程跟踪分支”(它们也通过您显示的推送被推出,但它们被推送到参考/远程/原点/而不是参考/头/)。检查 git log origin/contact_pagegit log origin/new_pictures,看看您的本地副本是否与您认为应该有的任何“最新”。如果有任何新的提交被推到这些分支(从其他回购)之间的取和推你显示,你可能已经“丢失”这些(但也许你可以找到他们在最近推这些分支的其他回购)。

获取/推送冲突

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.fetch and remote.origin.push settings.

请求支援

在尝试任何更改之前,做一个简单的 tar 或 zip 归档文件或整个本地回购。这样,如果你不喜欢发生的事情,你可以尝试从恢复回购。

选项 A: 重新配置为镜像

如果你打算使用你的远程回购作为一个镜像你的本地,这样做:

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

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

选项 B: 重新配置为普通远程

但是,因为它似乎是你使用这个远程回购与多个“工作”回购,你可能不想使用镜像模式。你可以试试这个:

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

然后,您最终将希望删除远程回购中的伪参考文献/远程参考文献/原始参考文献: git push origin :refs/remotes/origin/contact_page :refs/remotes/origin/new_pictures …

Test Push

Try git push --dry-run to see what it git push would 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.

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.

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

数据仍然存在于 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

只有两个命令救了我的命

这将列出所有以前的头

git reflog

2. 这将恢复您删除的 HEAD 提交。

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

它可能看起来过于谨慎,但是我经常在做源代码控制更改之前压缩我所做的工作的副本。在我正在做的一个 Gitlab 项目中,我最近错误地删除了一个在合并请求后想保留的远程分支。事实证明,我所需要做的就是用提交历史再次推送它。合并请求仍然被 Gitlab 跟踪,所以它仍然显示分支右侧的蓝色“合并”标签。我还是拉上了本地文件夹的拉链,以防万一。

如果您的组织使用 JIRA 或其他绑定到 git 的类似系统,您可以找到票据本身上列出的提交,并单击指向代码更改的链接。Github 删除了分支,但是仍然可以提交用于初选的内容。

  1. 找到提交 ID

    git reflog

  2. 恢复错误删除的本地分支

    git branch <NEED-RECOVER-BRANCH-NAME> commitId

  3. 如果您删除远程分支之前再次推动 need-recover-branch-name

    git push origin <NEED-RECOVER-BRANCH-NAME>

如果删除是最近发生的(就像一个糟糕的时刻) ,你仍然应该有一个消息:

Deleted branch <branch name> (was abcdefghi).

你还是可以逃跑:

git checkout abcdefghi

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