我正在使用一个存储库,其中有大量的文件,需要几个小时才能签出。我正在研究Git是否能很好地使用这种存储库的可能性,因为它支持稀疏签出,但我能找到的每个例子都是这样的:

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

这个命令序列的问题是原来的克隆也做一个签出。如果在原来的clone命令中添加了-n,则read-tree命令将导致以下错误:

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

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


我是新的git,但似乎如果我做每个目录的git签出,然后它工作。同样,稀疏签出文件需要在每个目录后面都有一个斜杠。有人更有经验,请确认这将工作。

有趣的是,如果签出不在稀疏签出文件中的目录,似乎没有什么区别。它们不会显示在git状态中,git read-tree -m -u HEAD不会导致它被删除。Git reset -hard也不会导致目录被删除。有没有更有经验的人愿意评论一下git对签出但不在稀疏签出文件中的目录的看法?


请注意,这个答案确实从存储库下载了数据的完整副本。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

现在你会发现你有一个“修剪”签出,只有从路径/within_repo/到/desired_subdir的文件存在(并且在该路径中)。

注意,在windows命令行中,你不能引用路径,也就是说,你必须用这个命令来改变第6个命令:

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

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


Git克隆有一个选项(——no-checkout或-n),可以做你想做的事情。

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

git clone <path>

:

git clone --no-checkout <path>

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


不幸的是,上面没有一个对我有用,所以我花了很长时间尝试不同的稀疏签出文件组合。

在我的情况下,我想跳过IntelliJ IDEA配置的文件夹。

以下是我所做的:


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

执行git config core命令。sparsecheckout真实

创建了.git\info\稀疏签出,包含以下内容

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

运行'git checkout——'获取所有文件。


让它正常工作的关键是在文件夹名称后添加/*。

我有1.9


我从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步中路径末尾的斜杠“/”。


2020年更新答案:

现在有一个命令git稀疏签出,我详细介绍了git 2.25(2020年Q1)

Nicono的回答说明了它的用法:

git sparse-checkout init --cone # to fetch only root files
git sparse-checkout add apps/my_app
git sparse-checkout add libs/my_lib

它随Git 2.27而发展,并且知道如何“重新应用”稀疏签出,就像这里一样。 注意,在Git 2.28中,Git状态会提示您处于稀疏签出的存储库中


注意/警告:某些在非锥模式下有效的稀疏签出模式会导致锥模式下的段错误,这已在Git 2.35 (Q1 2022)中得到纠正。

参见Derrick Stolee (derrickstolee)提交的commit a3eca58, commit 391c3a1, commit a481d43(2021年12月16日)。 (由Junio C Hamano—gitster—在commit 09481fe中合并,2022年1月10日)

稀疏检出:拒绝添加到不良模式 作者:Elijah Newren 署名:Derrick Stolee

When in cone mode sparse-checkout, it is unclear how 'git sparse-checkout'(man) add ... should behave if the existing sparse-checkout file does not match the cone mode patterns. Change the behavior to fail with an error message about the existing patterns. Also, all cone mode patterns start with a '/' character, so add that restriction. This is necessary for our example test 'cone mode: warn on bad pattern', but also requires modifying the example sparse-checkout file we use to test the warnings related to recognizing cone mode patterns. This error checking would cause a failure further down the test script because of a test that adds non-cone mode patterns without cleaning them up. Perform that cleanup as part of the test now.


在Git 2.36 (Q2 2022)中,“Git稀疏签出”(man)希望使用每个工作树的配置,但在连接到裸存储库的工作树中不能很好地工作。

参见Derrick Stolee (derrickstolee)的commit 3ce1138, commit 5325591, commit 7316dc5, commit fe18733, commit 615a84a, commit 5c11c0d (07 Feb 2022)。 (由Junio C Hamano—gitster—在commit 6249ce2中合并,2022年2月25日)

工作树:复制添加上的稀疏签出模式和配置 署名:Derrick Stolee 作者:Elijah Newren

When adding a new worktree, it is reasonable to expect that we want to use the current set of sparse-checkout settings for that new worktree. This is particularly important for repositories where the worktree would become too large to be useful. This is even more important when using partial clone as well, since we want to avoid downloading the missing blobs for files that should not be written to the new worktree. The only way to create such a worktree without this intermediate step of expanding the full worktree is to copy the sparse-checkout patterns and config settings during 'git worktree add'(man). Each worktree has its own sparse-checkout patterns, and the default behavior when the sparse-checkout file is missing is to include all paths at HEAD. Thus, we need to have patterns from somewhere, they might as well be the current worktree's patterns. These are then modified independently in the future. In addition to the sparse-checkout file, copy the worktree config file if worktree config is enabled and the file exists. This will copy over any important settings to ensure the new worktree behaves the same as the current one. The only exception we must continue to make is that core.bare and core.worktree should become unset in the worktree's config file.


原答案:2016年

git 2.9(2016年6月)将——no-checkout选项泛化到git工作树add(该命令允许在一个repo中使用多个工作树)

参见提交ef2a0ac(2016年3月29日)由Ray Zhang (OneRaynyDay)。 资助:Eric Sunshine (sunshineco)和Junio C Hamano (gitster) (由Junio C Hamano—gitster—在commit 0d8683c中合并,2016年4月13日)

git工作树手册页现在包括:

--[no-]checkout:

默认情况下,添加签出<分支>,但是,——no-签出可以用来抑制签出,以便进行定制,例如配置稀疏签出。


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

这样做不错

D:\Lab>git svn clone https://github.com/Qamar4P/LolAdapter.git/trunk/lol-adapter -r HEAD

-r HEAD将只下载最近的版本,忽略所有历史。 注意trunk和/specific文件夹

复制并更改URL在/trunk/之前和之后。我希望这能帮助到一些人。享受:)

2019年9月26日更新


我有一个类似的用例,除了我只想签出一个标记的提交和修剪目录。使用——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>

步骤稀疏签出只特定的文件夹:

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]

根据apenwarr的回答和Miral的评论,我提出了以下解决方案,在本地克隆linux git存储库时节省了近94%的磁盘空间,同时只需要一个文档子目录:

$ 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克隆-深度1 -no-checkout -filter=blob:none file:///…/linux linux-稀疏-测试(这里暗示)然后丢失的文件都作为删除文件添加到索引。因此,如果有人知道等价于git clone——filter=blob:none用于git读取,我们可能可以节省更多兆字节。(阅读git-rev-list的手册页还提示有像——filter=sparse:path=…这样的东西,但我也没有让它工作。

(都是用Debian Buster的git 2.20.1尝试过的。)


在我的例子中,我想在克隆项目时跳过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

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


在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
git checkout # or git switch

注意,它需要安装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

在git 2.27中,看起来git稀疏签出已经进化了。 这个答案中的解决方案并不完全相同(与git 2.25相比)

git克隆<URL>—no-checkout <目录> cd <目录> Git稀疏签出init——cone #只获取根文件 Git稀疏签出设置apps/my_app libs/my_lib # etc,列出要签出的子文件夹 #它们在这个命令后立即被签出,不需要运行git pull

下面这些命令效果更好:

git clone --sparse <URL> <directory>
cd <directory>
git sparse-checkout init --cone # to fetch only root files
git sparse-checkout add apps/my_app
git sparse-checkout add libs/my_lib

参见:git-clone—sparse和git-sparse-checkout add


痛苦的奥罗拉

git clone --filter=blob:none --no-checkout --depth 1 --sparse <project-url>
cd <project>

指定要克隆的文件夹

git sparse-checkout add <folder1> <folder2>
git checkout

我从TypeScript定义库@types中获取了这个:

让我们说回购有这样的结构:

types/
|_ identity/
|_ etc...

您的目标:仅签出标识/文件夹。包括子文件夹在内的所有内容。

⚠️这需要最低git版本2.27.0,这可能比大多数机器上的默认版本更新。更复杂的过程可以在旧版本中使用,但本指南没有涉及。

git clone --sparse --filter=blob:none --depth=1 <source-repo-url>
git sparse-checkout add types/identity types/identity ...

这将检出类型/标识文件夹到您的本地机器。

——sparse初始化稀疏签出文件,以便工作目录只从存储库根目录中的文件开始。

——filter=blob:none将排除文件,只在需要时获取它们。

——depth=1将通过截断提交历史来进一步提高克隆速度,但它可能会导致以下总结的问题。