如何使用git获得完整的回购副本

  • 本文关键字:副本 何使用 git git
  • 更新时间 :
  • 英文 :


我克隆了一个远程repo,并希望在本地git服务器上有一个自己的副本。

所以我做了:

git clone ssh...

我在我的服务器上创建了一个新的回购

git init --bare

我添加了新的服务器

git remote add bm ssh...

然后我推到新的远程

git push --mirror bm

现在我可以在我的裸服务器回购上看到:

[gitmini@blaumeise simulavr]$ git branch -a
* master
remotes/bm/master
remotes/savannah/HEAD
remotes/savannah/devel-tomk
remotes/savannah/master
remotes/savannah/oldstable
remotes/savannah/python_3
remotes/savannah/rel-1.0
remotes/savannah/rel-1.1
remotes/savannah/sbi_cbi_rework

我觉得看起来不错。

但现在我从本地服务器上注销了

git clone ssh...

我只得到:

git branch -a
[krud@blaumeise simulavr]$ git branch -a
* master
remotes/origin/HEAD -> origin/master
remotes/origin/master

我已经做了:git fetch --allgit pull --all,没有任何变化。

我自己的服务器repo有什么问题吗?或者克隆时有什么问题?在这样糟糕的情况下我能做什么。

我已经阅读:如何获取所有Git分支

git clone默认只复制其他Git的(本地)分支和标记。可以获取其他引用,包括remotes/savannah/oldstable等远程跟踪名称。但这通常不是一个好主意。相反,在您的裸存储库中,使it具有具有这些名称的分支

起初这一切都有点棘手,但最终一切都开始有意义了。这些名称源于使用两个独立的Git存储库。每个Git存储库都有自己的分支名称,因此:

  • 分支名称是一个全名以refs/heads/开头的引用。所以refs/heads/master表示分支master,依此类推

  • 远程跟踪名称是全名以refs/remotes/开头的引用。全名的下一部分与远程的名称相同,之后(和另一个斜杠)您将获得来自其他Git的分支名称

这是正常克隆的正常使用模式。有一些现有的存储库,一些人或许多人已经在网络上的某个地方(例如,在GitHub上)建立了它,它有很多分支:masterdevelopfeature/Afeature/B等等。你可以将该存储库克隆到你自己的机器(笔记本电脑或其他什么)上,并希望让你的Git记住他们的分支,而不是创建一堆(本地)分支。现在,您可能选择做一些工作,稍后将其作为feature/A的一部分发送给他们,因此您创建自己的名称feature/A,在其上进行新的提交以发送给他们并建议他们将这些提交放在feature/A中。您根本没有使用feature/B,因此没有获得feature/B,也没有使用master,因此可以删除自己的master

一旦有了一些新的提交,您将使用:

git push origin feature/A

将您的新提交发送到他们的Git,并立即作为git push本身的一部分,要求他们的Git设置feature/A分支来记住这些新提交。

这不是你想要的

当您第一次设置集中式服务器存储库时,您通常不希望遵循正常模式。您已经或者想要复制一些现有的存储库,比如说,有十几个分支名称。如果您自己的笔记本电脑上还没有这个存储库,您可以使用git clone --mirror在自己的笔记本上制作一个临时副本:

git clone --mirror <url> [<path>]

现在,您的笔记本电脑上有一个裸克隆(--mirror表示--bare),它根本没有origin/*远程跟踪名称。相反,Git在其存储库的副本中创建了与分支名称相对应的常规旧分支名称,而不是远程跟踪名称。因此,有与其相同的十几个分支名称。

镜像克隆对你自己做任何工作都没有用您临时创建此镜像克隆,以获取其存储库的副本,其中的分支名称也是您的分支名称。如果您已经有一个完整的工作存储库,其中包含十几个(或其他)分支,则跳过此步骤。

现在您有了包含所有分支的克隆,现在您可以在服务器(或GitHub)上创建一个空存储库现在您可以运行:

git push --all <url-of-server-repository>

现在,如果您制作了镜像克隆,您可以丢弃镜像克隆。您创建它只是为了将所有内容(包括所有分支名称)发送到服务器。因此,现在您可能需要删除镜像克隆,并制作服务器克隆的正常克隆以用于执行实际工作。

(如果您从已经全部设置好的本地存储库中执行了git push,则不希望或不需要删除本地克隆,并且您可能希望在git push之前使用git remote add。请参阅下文。)

以上内容有些浪费

您可能会反对必须制作这个愚蠢的镜像克隆,但在将镜像克隆推送到服务器后,必须将其丢弃并制作一个正常的非裸克隆。

您不必制作镜像克隆。这只是为了方便。

相反,您可以:

  • 制作常规克隆
  • 根据需要创建本地分支,以表示所有远程跟踪名称
  • 使用git push --all将这些全部发送到服务器
  • 删除所有您创建的本地名称(但保留任何您不必创建的名称)

或者,您可以:

  • 制作(或拥有)常规克隆
  • 使用不带--allgit push:相反,使用refspecs将您端的远程跟踪名称推送到其端的分支名称

最后一种方法在某些方面是最整洁的,但它需要理解refspec。

refspec的第二种最简单的形式是一对引用——像refs/heads/masterrefs/remotes/feature/A这样的全名——用冒号:分隔。冒号左侧的名称是,右侧的名称是目标。Refspecs在git fetchgit push中的行为相似,但并不完全相同:ref在发送Git中提供提交哈希,目标ref提供要在接收Git中设置的名称。由于git push您的Git存储库发送到他们的Git存储,您可以在左侧使用您的远程跟踪名称,在右侧使用他们的分支名称:

# after creating an empty repository on github
git remote add origin <url-on-github>
git push origin master   # send your refs/heads/master to theirs
git push origin refs/remotes/savannah/devel-tomk:refs/heads/devel-tomk
git push origin refs/remotes/savannah/python_3:refs/heads/python_3

(假设您希望您的远程跟踪savannah/devel-tomk成为他们的devel-tomk分支,依此类推)。

你可以把所有的refspec放在一个大的git push行中,但它的一部分很容易拼写错误,这很烦人:

git push origin master refs/remotes/savannah/devel-tomk:refs/heads/devel-tomk refs/remotes/savannah/python_3:refs/heads/python_3

例如,如果我没有错别字的话。

您没有创建整个repo的副本。您只创建了一个带有master分支的repo。

默认情况下,push只推送一个分支。尝试添加--all标志

git push --mirror --all bm

最新更新