如何从Git远程仓库删除中恢复数据

5
我们在服务器上的虚拟机上运行了一个Gitlab CE。
有3个人在这个Gitlab服务器上共同工作于一个代码库。
这个Gitlab CE虚拟机被意外删除了!
这三个人仍然有他们的本地代码库,里面有很多分支。
我们的分支策略是这样的:
我们有一个主分支和每个用户的一些功能分支。
用户通常会:

  • 从远程拉取主分支,
  • 从主分支创建一个新的分支,
  • 进行修改,
  • 再次将其推送到主分支(通过合并请求)

现在,我有一些问题:

  1. 是否有任何方法或策略可以从本地代码库重新创建远程代码库?
  2. 如果没有,我应该怎么做才能创建另一个远程代码库并将所有提交合并到其中?
4个回答

7
  • Create an empty repo in GitLab/BitBucket/GitHub.

  • Add a new remote (say, another) in your current repo with the URL of the new repo. Then push your master branch commits/changes to another repo's master branch.

    $ git remote add another <new-repo-url>
    $ git remote -v                 # see if the remote is added correctly 
    $ git checkout master
    
    $ git push another master       # push the changes to another/master
    
  • If you need features of another branch (say, feature) then simply checkout to the feature branch and push the changes to another repo's feature branch.

    $ git checkout feature
    $ git push another feature      # push changes to 'another' repo's 'feature' branch
    
  • Push all the branches and tags to another repo.

    $ git push --all --tags another
    

注意:这里的another代表您新仓库的URL。


谢谢回答。我们的用户在主分支的不同状态(提交)中。应该推送哪一个到主分支?其他功能分支呢? - MeeDNite
如果你需要推送其他分支的功能,那么只需checkout到该分支并简单地执行git push another <branch>即可。更新后的答案。 - Sajib Khan
我正在尝试这个。为我祈祷吧! - MeeDNite
你可以使用 git push --all --tags 来简化初始恢复,或者如果重新创建的服务器可以向其中一个客户端进行出站连接,则可以从任何一个不同的客户端使用 git clone --bare(即将客户端放入服务器角色一段时间)。但请注意,这会发布所有内容!@MeeDNite:由于不同的用户有不同程度的进展...好吧,如果你愿意,我可以写一个长答案,但它归结为,你想要制作所有公共提交、分支和标签名称集合的并集。你最好从“最完整”的用户开始。 - torek

3

由于您的远程已被删除,因此您还没有任何起点,因此您将需要在本地签出“远程”分支并为其分配原始名称,然后将所有分支推送到远程。

如果您不想要本地分支,请仅推送您需要的分支。

这是我用来签出所有分支,然后将它们推送到新远程的脚本。

#!/bin/bash

# add the new origin 
git remote add origin2 <url>

# loop over all the original branches and set the new remote as the new track origin
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
    git branch --track ${branch#remotes/origin2/} $branch
done

# now push all branches and tags
git push origin2 --all    
git push origin2 --tags

这段脚本做什么?

git branch -a
获取所有本地分支列表

| grep remotes
分支名称为'remotes/origin/',这将从分支名称中删除'remotes'

| grep -v HEAD | grep -v master
删除主分支(current branch)和最新提交的别名HEAD


不错的脚本!有一件事让我困惑,这里的 | grep remotes 是否应该改为 | grep -v remotes 来反转(删除 remotes)? - Sajib Khan
不,我们只搜索所有远程分支,因为所有本地分支都已经检出,remotes 是用来搜索远程分支的,而 -v 则是用来移除 HEADmaster - CodeWizard
好的。谢谢。实际上,我把这一行搞混了:“'remotes/origin/'”,所以这将移除远程... - Sajib Khan
1
请注意,如果您已经有一个名为X的本地分支,并且其上游是origin/X,则“git branch --track”命令将失败。只要您的本地分支X相当新,这没关系,尽管在这种特殊情况下,我实际上会以稍微不同的方式开始。这还假定只有一个远程,脚本应该在这里使用“git for-each-ref”而不是“git branch -a”,并且还有一些其他可能的细化,但总体而言,这是一个非常好的方法。 - torek
我同意,这个脚本是针对单个存储库和本地分支的。感谢指出这一点。 - CodeWizard

2

您可以复制(或克隆--bare)本地存储库之一,并重新基于/删除未合并到远程存储库的提交。之后,您可以将此存储库用作远程存储库。


这样我们就不会丢失未合并的提交。它们很重要。 - MeeDNite
不,你只是暂时失去了远程仓库中未合并的提交记录。从克隆的本地仓库推送它们的方式与标准推送到远程仓库没有任何问题。 - Niklas P
根据不同仓库中的内容以及客户端作为服务器的易用性,我会这样做。请注意,在暂时将服务器作为客户端时,您可能需要执行git clone --bare --mirror其中一个客户端作为服务器,然后删除git remote delete origin以避免让服务器的克隆看起来像是客户端(但这只是一个整洁问题而非正确性问题)。 - torek
1
我还应该补充一点,就像CodeWizard的脚本一样,你可能想为所有远程跟踪分支设置本地分支名称。 - torek

0

我不小心删除了我的“origin”分支。但我仍然有本地副本。以下是我如何在“origin”上重新创建分支的方法:

当我切换到本地副本时,我看到了这个消息:

Switched to branch 'my-special-branch'
Your branch is based on 'origin/my-special-branch', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

我使用了:

git branch --unset-upstream

这将分支恢复到正常的未推送状态。要将其放回原点,我只需运行

git push --set-upstream origin my-special-branch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接