如何克隆包含所有分支的git存储库?

时间:2017-06-13 07:11:08

标签: git

我有一个服务器,其中包含一个包含多个分支的git存储库。 我用“git branch -r”检查了服务器git并显示:
出身/ HEAD
原产地/开发
产地/ neatUI
产地/ iOS的
......还有一些

如果我克隆此存储库: “git clone [path_to_server] / ATS ATS” 我收到一个只包含“develop”的存储库。 “git branch -a”显示:
*发展中 遥控器/原产地/ HEAD - >原产地/开发
遥控/起源/发展

所有其他分支都不见了。

如果我使用--mirror选项克隆存储库,则所有分支都存在,但我无法使用它们。 “git branch -a”显示:
遥控器/产地/ HEAD
遥控器/原产地/开发
遥控器/产地/ neatUI
遥控器/产地/ iOS版
......其余的

如果我试图结帐分支git告诉我 “致命:此操作必须在工作树中运行”

我还尝试使用“SourceTree”来克隆repoistory,但SourceTree也只创建了“develop”分支。

有想法的人吗?

3 个答案:

答案 0 :(得分:2)

如果您使用git clone <url>克隆了工作树中的所有分支,请放心。你只需要剥离原点/何时想要签入其他分支。例如,如果要结帐iOS,请执行git checkout iOS

git branch -r显示存储库中的所有远程分支

git branch -a显示远程和本地分支(如果您在本地仓库中创建了任何分支)

答案 1 :(得分:1)

这里有一些独立但相互交织的关键概念。

第一个是,虽然Git有分支名称,但这并不是Git所具有的(并且就此而言,术语分支是不明确的:另见{{3 }})。 Git还有标签和Git所谓的远程跟踪分支名称,这些都属于一个名为 references 的通用类别。

  • master这样的分支名称只是 完整 名称以refs/heads/开头的参考。

  • 远程跟踪分支名称origin/iOS 完整 名称以refs/remotes/开头,后跟名称的引用遥控器本身(origin)和另一个斜线。 last 部分iOS是您的Git通常从另一个Git 复制的内容。

    远程部分是一个几乎任意的字符串。您可以创建自己的远程名称。但是,之后添加斜杠名称的斜杠名称与你应该注意在远程名称中使用斜杠。)

  • 要完成此特定列表,标记名称v1.0只是 完整 名称以refs/tags/开头的引用。还有更多形式的引用(例如refs/notes/用于Git的git notes,而GitHub用于refs/pull/)但是分支,标记和远程跟踪分支都是内置的,并且是标准的,最重要的是,高度可见 - 所以你应该了解它们。

当您运行git branch时,Git会找到您的所有refs/heads/个引用名称,并在refs/heads/被剥离后显示它们。当您运行git branch -r时,Git会找到您的所有refs/remotes/个引用,并在refs/remotes/被剥离后显示它们。当您运行git branch -a时,Git会同时找到这两个,并显示第一个被refs/heads/剥离的内容,但会显示仅剥离refs/的第二个。 (为什么?谁知道!这是Git很棒。:-))

这解释了为什么你看到了什么,但没有看到git clone --mirror发生了什么,也没有为什么你git checkout iOS突然有了新的refs/heads/iOS;为此,我们还需要两个项目,关于 refspecs (与git fetchgit push一起使用),以及What exactly do we mean by "branch"?

为了简短起见: refspec 只是一对引用,用冒号分隔,有时一部分用*替换。例如,refs/heads/*:refs/remotes/origin/*是refspec。您也可以在refspec前加上前导加号;这会设置--force标志。 git fetchgit push都使用refspecs(两者都有自己的--force标志,这有效地为您在命令行上提供的任何refspec添加+。冒号前的引用是 source ,冒号后的引用是 destination ,这很重要,因为{em>中有两个 Gits {1}}和git fetch:你的,以及其他一些Git。

当你git push时,源引用是其他Git的引用,目标是你的引用。当您git fetch时,源引用是您的,目标是他们的。

使用git push告诉您的Git设置存储库(我将在此处保留未定义)并将git clone --mirror设置为{{1的refspec }}。这会复制所有来自+refs/*:refs/*的其他Git的引用,但这意味着你不能拥有自己的分支:你的Git现在是他们的精确副本,每次你运行{{ 1}}你替换你所拥有的一切......再一次是他们的精确副本。

大多数git fetch操作的要点是获取“他们的Git”的不精确副本。这里的基本想法是你想要所有的他们的分支名称将成为您的远程跟踪分支名称。他们的origin成为您的git fetch;他们的git clone成为您的master

这为他们的 origin/master留下了空间,因为你的不精确副本有自己的 iOS。如果你想获得他们的远程跟踪分支,你可以 - 但你需要为其他名称命名!

一旦你拥有(非镜像)克隆,并且他们的 origin/iOS 成为你的origin/*,你可以origin/*和我提到的DWIM行动上面(和链接)发挥作用,使用您自己的whatever创建一个新的本地 origin/whatever - 您从 git checkout whatever

答案 2 :(得分:0)

我遇到了同样的问题。 我之前使用 --branch <branch-name>--depth 1 选项克隆了我的存储库。
这会将 remote.origin.fetch 的配置条目分别设置为 +refs/heads/<branch-name>:refs/remotes/origin/<branch-name>+refs/heads/<default-branch>:refs/remotes/origin/<default-branch>

<default-branch> 通常为 mainmaster,或者在 OP develop 的情况下。

你可以用这个命令检查:

git config --get remote.origin.fetch

如果您的遥控器名称不同,请替换 origin,请参阅 git remote -v

您可以使用

更新设置
git config --replace-all remote.origin.fetch +refs/heads/*:refs/remotes/origin/*

您还可以使用 git config -e 在配置的编辑器中编辑配置。

[remote "origin"]
    url = https://github.com/<some-user>/<some-repo>.git
    fetch = +refs/heads/*:refs/remotes/origin/*

现在 git fetch 应该获取所有远程分支(和相关标签)。

详情见@torek s answer