使用Git和Mercurial进行部分克隆


74

是否可以在Git和Mercurial中仅克隆一个分支(或从给定提交中克隆)?我的意思是,我想克隆一个中央存储库,但是由于存储库很大,所以我只希望得到其中的一部分,并且仍然能够回馈我的更改。可能吗?就像,我只想要Tag 130或类似的东西?

如果是这样,怎么办?


1
另请参阅Git 2.17部分克隆(或“窄克隆”)stackoverflow.com/a/48852630/6309
VonC

Answers:


76

在Git领域中,您正在谈论三种不同类型的部分克隆:

  • 浅表克隆:我想要从修订点X开始的历史记录。

    使用git clone --depth <n> <url>了这一点,但请记住浅克隆与其他信息库交互比较有限。您将能够生成补丁并通过电子邮件发送它们。

  • 按文件路径部分克隆:我希望所有修订历史记录都在某个目录中/path

    在Git中是不可能的。使用现代Git,虽然您可以进行稀疏签出,即您拥有完整的历史记录,但是仅签出(位于工作区中)所有文件的子集。

  • 仅克隆选定的分支:我只想克隆一个分支(或选定的分支子集)。

    可能的,并且

    以前的git 1.7.10并不简单:你需要做什么克隆手动做,即git init [<directory>],然后git remote add origin <url>,编辑.git/config替换*remote.origin.fetch所要求的分支(可能是“主”),然后git fetch

    从git 1.7.10版本开始, git clone提供的--single-branch选项似乎是为此目的而添加的,并且看起来非常简单。

    但是请注意,由于分支通常共享大部分历史记录,因此仅克隆分支的子集所获得的收益可能会比您想象的要小。

您也可以仅对选定的分支子集进行浅表克隆。

如果您知道人们将如何按文件路径(同一存储库中的多个项目)分解内容,则可以使用子模块(类似于svn:externals)将存储库预分割为可单独克隆的部分。


因此,如果我克隆分支“ XX”,它将从“ master”获得所有父提交,对吗?还是只有我在该分支上完成的一次提交?
pablo 2010年

1
如果仅克隆(获取)分支“ XX”,则将获得其所有提交,包括分支“ XX”与“ master”分支共有的那些提交。在Git中,提交不“属于”分支。
JakubNarębski2010年

好吧,那毕竟不是部分克隆,因为您得到了所有的父母,因此也得到了整个回购协议(好吧,最大的部分在掌握中)
pablo

1
在1.8.0(或更早的版本)中,单分支克隆现在变得容易得多。
雅库布·纳伦斯基(JakubNarębski)2012年

1
您可以将带有Git 2.17(2018年第二季度)的“部分克隆”(或“窄克隆”)添加到该列表中:stackoverflow.com/a/48852630/6309
VonC

51

在商业领域,您正在谈论三种不同类型的部分克隆:

  • 浅表克隆:我希望从修订点X开始的历史记录使用remotefilelog扩展名
  • 按文件路径进行部分克隆:我希望目录/ path中具有实验性窄扩展名的所有修订历史记录,或者只希望目录/ path中的文件位于实验性稀疏扩展名的工作目录中(从4.3版开始,请参见hg help sparse)。
  • 按分支的部分克隆:我想要分支Y上的所有修订历史记录:使用clone -r

如果您知道人们将如何按文件路径分解内容(同一存储库中有多个项目(让您感到羞耻)),则可以使用子存储库(类似于svn外部组件)将存储库预先拆分为可单独克隆的部分

另外,关于“我只想参与其中的一部分”:您真的只需要做一次。只需在午餐时克隆它,然后再永久食用即可。随后,您可以pull有效地获得增量。如果您想要它的另一个克隆,只需克隆您的第一个克隆。克隆的位置无关紧要(本地克隆不会占用额外的磁盘空间,因为它们是底层的硬链接)。


1
标签也不同于某些VCS中的分支,因此它与分支不同,因此这是第一个要点
jk。

有修整历史记录(mercurial.selenic.com/wiki/TrimmingHistory)和浅表克隆(mercurial.selenic.com/wiki/ShallowClone)插件。我不知道他们有多好。
panzi 2011年

8
这两个建议均被拒绝,没有实施。
Ry4an Brase 2011年

4
*现在可以使用'remotefilelog'进行浅克隆:bitbucket.org/facebook/remotefilelog *通过文件路径进行部分克隆是可能的(但仍处于试验阶段),请参见comment.gmane.org/gmane.comp.version-control.mercurial.devel/ …
Mathiasdm 2014年

1
2017年初:按文件路径进行的部分克隆(又称窄克隆)仍不在Mercurial的主线中,但可以通过Google的扩展名-bitbucket.org/Google/narrowhg来实现。同样,稀疏结帐(又称窄结帐)不在Mercurial主线中,但可以使用sparse.pyFacebook的Mercurial扩展名-bitbucket.org/facebook/hg-experimental进行
Anon

9

选定的答案提供了很好的概述,但缺少完整的示例。

最小化(a)(b)的下载和结帐空间 :

git clone --no-checkout --depth 1 --single-branch --branch (name) (repo) (folder)
cd (folder)
git config core.sparseCheckout true
echo "target/path/1" >>.git/info/sparse-checkout
echo "target/path/2" >>.git/info/sparse-checkout
git checkout

定期优化您的本地存储库占用空间 (c) (可选,请谨慎使用):

git clean --dry-run # consider and tweak results then switch to --force
git gc
git repack -Ad
git prune

另请参阅:如何使用git处理大型存储库


5

此方法创建不带子存储库的未版本控制的归档文件:

hg clone -U ssh://machine//directory/path/to/repo/project projecttemp

cd projecttemp

hg archive -r tip ../project-no-subrepos

没有子存储库的未版本化源代码位于project-no-subrepos目录中


2

关于Git,Linus Torvalds在2007年的一次演讲中从概念的角度回答了这个问题,这可能具有历史意义,该演讲已录制并可以在线获得。

问题是,是否有可能仅从Git存储库中检出某些文件。

技术讲座:Linus Torvalds在git t = 43:10上

总而言之,他说,Git的设计决策之一使Git与其他源代码管理系统区分开(他引用BitKeeper和SVN),这是Git管理内容而不是文件。其含义是,例如,通过首先获取整个差异然后仅将其修剪到所请求的文件来计算两个修订版中文件子集的差异。另一个是您必须查看整个历史记录。以全有或全无的方式。由于这个原因,他建议在多个存储库之间拆分松散相关的组件,并提到随后正在进行的工作,以实现用于管理存储库的用户界面,该用户界面被构造为拥有较小存储库的超级项目。

据我所知,这个基本的设计决策今天仍然很重要。超级项目的事情可能变成了现在的子模块


1
我知道该帖子...我最初将其提交给slashdot:P
pablo

-1

以水银为例,您应该可以使用以下方法进行一些操作:

hg convert --banchmap FILE SOURCEDEST REVMAP

您可能还需要:

--config convert.hg.startrev=REV

来源可以是git,Mercurial或其他各种系统。

我还没有尝试过,但是convert非常丰富。


4
转换扩展重写了哈希,因此这不是现有存储库的部分克隆,而是新的。这意味着它将是一个单独的存储库,无法从原始存储库中拉出或推送。
Priit
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.