是否可以进行稀疏签出而无需先签出整个存储库?


171

我正在使用包含大量文件的存储库,这些文件需要几个小时才能结帐。我正在研究Git支持稀疏签出的情况,现在它是否可以与这种存储库一起很好地工作,但是我能找到的每个示例都执行以下操作:

git clone <path>
git config core.sparsecheckout true
echo <dir> > .git/info/sparse-checkout
git read-tree -m -u HEAD

此命令序列的问题是原始克隆也执行检出。如果将-n添加到原始克隆命令,则read-tree命令将导致以下错误:

错误:稀疏签出在工作目录上没有任何条目

如何在不先检出所有文件的情况下进行稀疏检出?



注意:在git 2.9(2016年7月)中git worktree add --no-checkout也可以(不只是git clone --no-checkout)使用。请参阅下面的答案
VonC

在尝试了所有解决方案之后,唯一下载目录(以后不推送!)的就是this
LondonRob

Answers:


24

在2020年,有一种更简单的方法来处理稀疏签出,而不必担心.git文件。这是我的做法:

git clone <URL> --no-checkout <directory>
cd <directory>
git sparse-checkout init --cone # to fetch only root files
git sparse-checkout set apps/my_app libs/my_lib # etc, to list sub-folders to checkout
# they are checked out immediately after this command, no need to run git pull

请注意,它需要安装git版本2.25。在此处了解更多信息:https : //github.blog/2020-01-17-bring-your-monorepo-down-to-size-with-sparse-checkout/

更新:

上面的git clone命令仍将克隆具有完整历史记录的存储库,尽管不检出文件。如果不需要完整的历史记录,可以在命令中添加--depth参数,如下所示:

# create a shallow clone,
# with only 1 (since depth equals 1) latest commit in history
git clone <URL> --no-checkout <directory> --depth 1

1
是的,很好。已投票。我遵循了stackoverflow.com/a/59515426/6309sparse-checkout --cone
VonC中

值得--filter在此处将部分克隆()添加到您的答案中。

@ alexey-grinko,第一个命令仍然必须克隆整个有问题的存储库,即使它没有将其检出...我希望节省不克隆我不需要的所有内容的时间。 。
mropp

1
@mropp,我通过添加--depth允许我们进行浅表克隆的参数来更新了答案。有帮助吗?@Tao,不确定--filter在这种情况下如何使用,我没有尝试过。您能否提供一个示例,或对此主题发表另一个答案?
Alexey Grinko

4
请注意,它在2.27版本中无法正常工作-我不知道为什么。
Blazes

162

请注意,此答案确实会从存储库下载数据的完整副本。该git remote add -f命令将克隆整个存储库。从手册页git-remote

-f选项,git fetch <name>在设置远程信息后立即运行。


试试这个:

mkdir myrepo
cd myrepo
git init
git config core.sparseCheckout true
git remote add -f origin git://...
echo "path/within_repo/to/desired_subdir/*" > .git/info/sparse-checkout
git checkout [branchname] # ex: master

现在,您将发现您已经“修剪”了检出项,仅存在path / within_repo / to / desired_subdir中的文件(以及该路径中的文件)。

请注意,在Windows命令行上,您必须不要引用路径,即必须使用此命令更改第六条命令:

echo path/within_repo/to/desired_subdir/* > .git/info/sparse-checkout

如果不这样做,您将在稀疏签出文件中得到引号,它将不起作用


3
我不能使用命令“ git checkout [branchname]”(也发现错误:稀疏签出不会在工作目录上留下任何条目)。我使用了“ git pull origin master”,它可以正常工作。
Natty 2013年

2
在Linux上的git版本1.7.2.5中,我得到以下结果:echo'dir / *' 检出dir /中的文件,而不检出其子目录中的文件;echo'dir /'(没有星号!)正确地检出dir /下的整个树。HTH
pavek

37
这对我不起作用-“ git remote”命令导致整个仓库被检出-bam!-那时候 因此,以下命令中的“ git config ...”和感兴趣的子目录的规范无效。是在“ git remote”命令中指定的回购URL只是顶级.git文件的路径吗?还是应该成为感兴趣的子目录的路径?
Rob Cranfill

10
这是一个简化的版本(不需要手动创建目录,进行初始化和远程添加,只需使用@onionjake提到的--no-checkout选项执行正常的git clone + checkout周期即可):git clone --no-checkout <project> cd <project> echo <dir>> .git / info / sparse-checkout git checkout <分支>
Gregor

22
git remote add命令下载所有内容,因为这样做-f是正确的-告诉它在定义稀疏签出选项之前立即进行提取。但是,省略或重新排序将无济于事。稀疏检出仅影响工作树,而不影响存储库。如果您想让存储库节食,则需要查看--depth--single-branch选项。
Miral

43

Git克隆具有一个您想要的选项(--no-checkout-n)。

在命令列表中,只需更改:

git clone <path>

对此:

git clone --no-checkout <path>

然后,您可以按照问题中所述使用稀疏签出。


7
是的,它不会进行结帐,但仍会进行下载以下载整个回购历史记录
Jason S

9
@JasonS的问题专门是关于不进行结帐。如果您不想使用整个历史记录,请使用--depth <depth>git clone上的选项。那只会下载<depth>历史记录中的最后一次提交。当前无法使用git部分下载单个提交,尽管如果您的远程支持,则可以使用它git archive --remote来下载部分文件。
onionjake

现在,您还可以“检出”提交,而无需使用vfsforgit.org下载任何文件。如果有人尝试仅检出单个提交的一小部分,这可能很有用。
onionjake

22

我有一个类似的用例,只是我只想检出标签的提交并修剪目录。使用--depth 1使它真正稀疏并且可以真正加快速度。

mkdir myrepo
cd myrepo
git init
git config core.sparseCheckout true
git remote add origin <url>  # Note: no -f option
echo "path/within_repo/to/subdir/" > .git/info/sparse-checkout
git fetch --depth 1 origin tag <tagname>
git checkout <tagname>

3
--depth 1称为浅表克隆,仅供参考。
Mark Allison

1
这有帮助!谢谢
kp123 '19

1
谢谢你 在尝试了许多其他方法来防止下载整个仓库后,对此做对了。
J ... S

12

我从pavek早些时候发布的单行代码中找到了想要的答案(谢谢!),所以我想在一个适用于Linux(GIT 1.7.1)的单一答复中提供完整的答案:

1--> mkdir myrepo
2--> cd myrepo
3--> git init
4--> git config core.sparseCheckout true
5--> echo 'path/to/subdir/' > .git/info/sparse-checkout
6--> git remote add -f origin ssh://...
7--> git pull origin master

我稍微更改了命令的顺序,但这似乎没有任何影响。关键是步骤5中路径末尾的斜杠“ /”的存在。


3
您确定这是您想要的吗?-f表示获取所有数据,您仍然会获取所有其他不需要的信息,而且速度很慢。(这仍然是“检查整个存储库”)
Shuman

1
我在Windows中尝试了上述步骤,但是多余的签出在命令提示符下不起作用,所以我尝试了Git Bash shell,它起作用了!!命令提示符能够执行所有git命令,例如push,pull等,但在进行稀疏检出时会失败。
user593029 '16

如何只执行子目录中的文件。我只想获取特定子目录中的文件。
Babish Shrestha

@BabishShrestha见onionjake对其他答案FWIW的评论:|
rogerdpack

9

遗憾的是,上述方法都不适合我,因此我花了很长时间尝试各种不同的sparse-checkout文件组合。

就我而言,我想跳过具有IntelliJ IDEA配置的文件夹。

这是我所做的:


git clone https://github.com/myaccount/myrepo.git --no-checkout

git config core.sparsecheckout true

.git\info\sparse-checkout使用以下内容创建

!.idea/*
!.idea_modules/*
/*

运行“ git checkout-”以获取所有文件。


使其起作用的关键是/*在文件夹名称后添加。

我有git 1.9


3
不,它仍会下载所有内容,所有提交和所有文件,git 2.3.2
Tyguy7'9

6
稀疏检出仅影响工作树。它们不会影响存储库的大小或获取的内容。如果需要,您需要其他选项。
Miral 2015年

如果在Windows中工作,则下次尝试Git Bash Shell,并通过'pbetkier'使用上述步骤可以正常工作
user593029 '16

6

是的,可以下载一个文件夹而不是下载整个存储库。甚至任何/最后一次提交

做到这一点的好方法

D:\Lab>git svn clone https://github.com/Qamar4P/LolAdapter.git/trunk/lol-adapter -r HEAD
  1. -r HEAD将仅下载最新修订版,忽略所有历史记录。

  2. 注意行李箱和/ specific-folder

在之前和之后复制和更改URL /trunk/。希望对您有所帮助。请享用 :)

于2019年9月26日更新


仅适用于来自或使用svn的用户。不会支持这一点。
C约翰逊

如您所见,@ CJohnson,我正在克隆git repo文件夹。工作正常
Qamar

1
请注意,这不是git提供的开箱即用的东西,而是Git 集线器提供的与常规Git产品相邻的东西。但是,当您可以使用它时,它的效果很好。谢谢!
Qix-蒙尼卡(Monica)

1
在众多有关SO的建议中,您的是最简洁明了的解决方案。
boardrider19年

4

git 2.9(2016年6月)将把--no-checkout选项概括为git worktree add(该命令允许为一个仓库使用多个工作树

参见Ray Zhang()的commit ef2a0ac(2016年3月29日。 帮助:Eric Sunshine(Junio C Hamano((由Junio C Hamano合并--提交0d8683c中OneRaynyDay
sunshinecogitster
gitster,2016年4月13日)

git worktree手册页现在包括:

--[no-]checkout:

但是,默认情况下,add签出可用于抑制签出以进行自定义,例如配置sparse-checkout<branch>--no-checkout


4

稀疏检出仅特定文件夹的步骤:

1) git clone --no-checkout  <project clone url>  
2) cd <project folder>
3) git config core.sparsecheckout true   [You must do this]
4) echo "<path you want to sparce>/*" > .git/info/sparse-checkout
    [You must enter /* at the end of the path such that it will take all contents of that folder]
5) git checkout <branch name> [Ex: master]

仅供参考,在第一步(1)中,您无需使用--no-checkout。只需克隆整个仓库,然后执行下面的所有步骤2-5(如上所述),您将获得所需的输出。让我知道你是否不明白。
SANDEEP MACHIRAJU

4

基于此答案apenwarr此评论Miral我想出了以下解决方案克隆时救了我近94%的磁盘空间的linux git仓库在本地,而只想要一个文档子目录:

$ cd linux
$ du -sh .git .
2.1G    .git
894M    .
$ du -sh 
2.9G    .
$ mkdir ../linux-sparse-test
$ cd ../linux-sparse-test
$ git init
Initialized empty Git repository in /…/linux-sparse-test/.git/
$ git config core.sparseCheckout true
$ git remote add origin ../linux
# Parameter "origin master" saves a tiny bit if there are other branches
$ git fetch --depth=1 origin master
remote: Enumerating objects: 65839, done.
remote: Counting objects: 100% (65839/65839), done.
remote: Compressing objects: 100% (61140/61140), done.
remote: Total 65839 (delta 6202), reused 22590 (delta 3703)
Receiving objects: 100% (65839/65839), 173.09 MiB | 10.05 MiB/s, done.
Resolving deltas: 100% (6202/6202), done.
From ../linux
 * branch              master     -> FETCH_HEAD
 * [new branch]        master     -> origin/master
$ echo "Documentation/hid/*" > .git/info/sparse-checkout
$ git checkout master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Already on 'master'
$ ls -l
total 4
drwxr-xr-x 3 abe abe 4096 May  3 14:12 Documentation/
$  du -sh .git .
181M    .git
100K    .
$  du -sh
182M    .

所以我从2.9GB减少到182MB,这已经很安静了。

我虽然没有将其与git clone --depth 1 --no-checkout --filter=blob:none file:///…/linux linux-sparse-test在此处提示)一起使用,但随后丢失的文件全部作为已删除文件添加到索引中。因此,如果有人知道git clone --filter=blob:nonefor 的等效项git fetch,我们可能可以节省更多兆字节。(阅读的手册页git-rev-list还暗示有类似的东西--filter=sparse:path=…,但我也没有使它起作用。

(所有尝试使用Debian Buster的git 2.20.1。)


1
有趣的反馈。已投票。我也不知道--filter=sparse:path=…
VonC

3

我是git的新手,但如果我对每个目录执行git checkout,那么它就可以工作。同样,稀疏检出文件需要在每个目录后都带有一个斜杠,如所示。有其他经验的人请确认这将起作用。

有趣的是,如果您签出不在稀疏签出文件中的目录,则似乎没有什么区别。它们不会以git状态显示,并且git read-tree -m -u HEAD不会将其删除。git reset --hard也不会删除目录。还有谁更有经验地评论git对已签出但不在稀疏签出文件中的目录的看法呢?


0

就我而言,我想Pods在克隆项目时跳过该文件夹。我按照下面的步骤进行操作,对我有用。希望能帮助到你。

mkdir my_folder
cd my_folder
git init
git remote add origin -f <URL>
git config core.sparseCheckout true 
echo '!Pods/*\n/*' > .git/info/sparse-checkout
git pull origin master

备注,如果要跳过更多文件夹,只需在稀疏签出文件中添加更多行即可。

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.