git clone和git clone --mirror完全不同:
标准git clone可用作工作空间。 原产地已知的一组分支可供检查和处理。
镜像更像是备份。您不能将其直接用作工作区。
现在假设您克隆已经克隆的存储库 根据这个问题:Git cloning a repository that is already a clone
生成的存储库(clone2)只包含已在第一个克隆(clone1)中使用的分支。但是,clone1仍然知道原点的分支。有没有办法将clone1已知的分支添加到clone2而不将(原始)原点设置为远程?
如果不清楚,我们有:
repo1:
clone1 = git clone repo1.git:
clone2 = git clone clone1.git:
clone2似乎不知道branch3或branch4,因此无法检查它们。 我们如何从clone1获取该信息?
实际上这里有两个问题:
我相信,当repo1离线时,branch3和branch4可用于clone1。
有几个用例:
我认为它应该没有区别,但我使用本地文件而不是URL来测试它。所以clone2实际上是通过git clone /local/path/.git
制作的我最初没有注意到并且报告的并发症: git branch -r 在clone2上应该按照答案中的建议将clone1上的分支列为 origin / branch3 和 origin / branch4 。但是,对于这个特殊的回购,它没有。我不知道为什么。
这个回购可能有些特别之处包括:
用git pull origin'refs / replace / *:refs / replace / *'拉取替换件没有区别。
还有其他建议吗?
我已经确定了git branch -r工作的repos和它不能工作的repos之间的重要区别。
clone1和clone2都应该使用(/path/to/clone1/.git/packed-refs)等行列出.git / packed-refs中的遥控器:
2c3c761fbac82556c2178cb28a4e728360093e67 refs/remotes/origin/branch1
由于某些原因,受影响的存储库上的clone2没有.git / packed-refs中的所有条目。
我检查了一些提交ID,其中packed-ref文件(在clone2中)引用了克隆存储库packed-ref(clone2),但有些则没有。 我们似乎既失去了又获得了分支!
如果我通过实验方式将packed-ref文件从clone1复制到clone2,则分支显示在
git branch -r下,可以检出它们但会导致头状态分离。
这是'受影响'回购的git配置。
>cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = /path/to/clone1/.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "develop"] remote = origin merge = refs/heads/develop
用于抓取所有远程跟踪分支的[https://git.wiki.kernel.org/index.php|standard指令]即使对于损坏的回购也是如此:
git clone --mirror original-repo.git /path/cloned-directory/.git cd /path/cloned-directory git config --bool core.bare false git checkout anybranch
所以即使是破损的回购也有几种解决方法。
答案 0 :(得分:1)
在我看来,您正在查看具有--mirror
和没有{克隆号}的克隆的非常不同的典型用例,并让您认为它们根本不同。实际上,它们只是一般情况下常用的特殊情况。
这主要是暂时的,但我认为如果你研究git概念,着眼于真正理解上述陈述,那么其余部分也可能更清楚。
所以:在clone1
中,"知识"其他分支的形式是远程分支引用(refs/remotes/origin/branch3
,...)。签出的分支还有" local" branch refs(refs/heads/branch1
,...)。克隆中使用的默认refspec(无论是镜像还是其他)都设置为fetch refs/heads/*
。 (不同之处在于mirror
将其本地映射为refs/heads/*
,而#34;常规"克隆默认将它们映射到refs/remotes/origin/*
。)
您可以在clone2
中设置refspec - 通过设置,或在特定fetch
或pull
的参数中 - 从{{读取refs/remotes/origin/*
引用1}}。但是有一些问题要考虑。
首先,如果你要从clone1
映射本地和远程引用,那么你需要在clone1
中为它们提供不同的命名空间。也就是说,clone2
中的refs/heads/master
与clone1
中的refs/remotes/origin/master
不同,并且它们可能在任何给定时间引用不同的提交;所以他们不能两个映射到clone1
中的相同名称。
其次,clone2
的知识 - 例如 - clone2
,在这一点上是间接的。 "我最后一次与branch3
交谈,它告诉我上次与clone1
通话时,repo1
处于提交branch3
。"从马的口中获取XYZ
"的知识可能更有意义。您可以在branch3
上添加repo1
作为第二个遥控器。
是否通过添加clone2
作为来源,或使用非默认的refspec来复制来自repo1
的信息,最终在clone1
中您将拥有该信息。多个远程引用对应于某些分支名称(例如clone2
和refs/remotes/origin/branch3
)。这意味着可能并不总是清楚哪个分支应该被视为"上游"当地的refs/remotes/repo1/branch3
。您可以通过配置和/或通过特定refs/heads/branch3
和push
命令的参数来管理它,告诉他们您打算在该实例中将其作为上游。
将所有内容翻译成特定命令实际上取决于您要完成的任务;有太多的可能性将它们列出来并解释当你使用它们中的任何一个时。如果您需要这种详细程度,我建议fetch
,git config
,git fetch
和git push
的文档可以作为开始的地方。
答案 1 :(得分:0)
Git可以有多个远程连接。它不像一些其他类似系统那样限于单个主存储库。您可以使用以下命令将repo1添加为另一个远程存储库:
git remote add repo1 /path/to/your/original/complete/repository
然后你可以像往常那样得到你的分支:
git fetch repo1 branch3
git fetch repo1 branch4
如果您愿意,稍后可以结帐以进行处理:
git checkout branch4
答案 2 :(得分:0)
首先:您只能看到repo1
或git fetch
上的git pull
视图。
repo1
中的所有分支都将存储在origin
的{{1}}下。
您可以使用以下代码列出这些分支:clone1
。
答案 3 :(得分:0)
这应该是一个评论,但我需要格式化,我不能在评论中做(并且已经再次罗嗦了:-))。
除了Mark Adelsberger's answer(这是正确的和赞成的,你应该阅读它),我认为,有一个关键是理解这一点,这是通过你的措辞的这一点揭示的:
branch3 - 没有签出[在clone1上],但可以随时
关键是在这种状态下, branch3不存在。
这是我在其他答案中所说的内容,并将重复:远程跟踪分支不是分支。它是远程跟踪分支名称:一个名称,如origin/branch3
,是一个缩写形式的全名,以refs/remotes/
开头(与分支名称相比,如branch3
这是一个以refs/heads/
)开头的缩写形式的全名。
(事实上,"分支"并不总是"分支",在Git中,由于Git作者和重复使用不同相同单词的习惯意义 - 这是公平的,也是一直用英语发生的,这是我们得到puns的一种方式。另见What exactly do we mean by "branch"?在这种特殊情况下,我们的意思是"分支& #34;是分支名称,即全名以refs/heads/
开头的引用。)
当您要求git checkout
签出不存在的分支时,例如branch3
,Git将扫描您的所有远程跟踪分支名称。如果只有一个"类似于" branch3
正确地,git checkout
将创建一个,使用远程跟踪分支名称来派生新分支的初始哈希ID值。
对于存储库中存在的分支名称,该存储库必须具有其全名以refs/heads/
开头的引用。第二次斜线后出现的是分支的名称。要列出某个存储库中的所有引用,请运行git for-each-ref
,其默认输出是每个引用的列表,其哈希ID以及该哈希标识的Git对象的类型。
当你做一个克隆时,你告诉你的Git - 制作克隆的那个 - 如何操纵它从另一个Git获得的引用。这是--mirror
所做的关键:它说使用他们的引用来制作我的引用,而根本没有任何更改。普通克隆不会这样做,因为一旦你< em>做这样做,当你从另一个Git重新获取时,你有一个问题:你已经完全被它奴役了;您在自己的副本中更改的任何引用,您将其值替换为其值并返回到纯副本。