【问题标题】:Is it possible to do a sparse checkout without checking out the whole repository first?是否可以在不先检出整个存储库的情况下进行稀疏检出?
【发布时间】:2011-05-06 02:52:12
【问题描述】:

我正在使用一个包含大量文件的存储库,这些文件需要数小时才能签出。我正在研究 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 sparse-checkout git-sparse-checkout


【解决方案1】:

请注意,此答案确实会从存储库下载数据的完整副本。 git remote add -f 命令将克隆整个存储库。来自man page of git-remote

使用-f 选项,git fetch &lt;name&gt; 在远程信息设置后立即运行。


试试这个:

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 命令行中,您不能引用路径,即您必须将第 6 个命令更改为:

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

如果你不这样做,你会在 sparse-checkout 文件中得到引号,并且它不会起作用

【讨论】:

  • 我不能使用命令“git checkout [branchname]”(还发现错误:稀疏结帐在工作目录上没有留下任何条目)。我用过“git pull origin master”,它工作正常。
  • 在 linux 上使用 git 版本 1.7.2.5,我得到以下结果: echo 'dir/*' 检出 dir/ 中的文件,但不检出其子目录中的文件; echo 'dir/' (没有星号!)正确地检查出 dir/ 下的整个树。 HTH
  • 这对我不起作用——“git remote”命令导致整个 repo 被签出——bam! - 就在那时;因此,以下命令中感兴趣的子目录的“git config ...”和规范无效。 “git remote”命令中指定的 repo URL 是否只是顶级 .git 文件的路径?还是应该是感兴趣的子目录的路径?
  • 这是一个精简的版本(不需要手动创建目录,进行初始化和远程添加,只需使用@onionjake 提到的 --no-checkout 选项执行正常的 git clone+checkout 循环) : git clone --no-checkout cd echo > .git/info/sparse-checkout git checkout
  • git remote add 命令会下载所有内容,因为这就是-f 所做的——告诉它在您定义稀疏结帐选项之前立即获取。但是省略或重新排序不会有帮助。稀疏检出只影响工作树,而不影响存储库。如果您希望您的存储库改为节食,则需要查看 --depth--single-branch 选项。
【解决方案2】:

在 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

【讨论】:

  • 这是真的,好点。赞成。我关注了stackoverflow.com/a/59515426/6309中的sparse-checkout --cone功能
  • @mropp,我通过添加--depth 参数更新了答案,该参数允许我们进行浅层克隆。那会有帮助吗? @Tao,不知道在这种情况下如何使用--filter,我没有尝试过。你能提供一个例子,或者发布这个主题的另一个答案吗?
  • 请注意,它在 2.27 版本中的工作方式不同 - 我不知道为什么。
  • 正如 Blazes 所说,它在 2.27 中不再工作,无法找到如何让它再次工作。
  • 我想我在 2.28 上完成了这项工作:git clone &lt;url&gt; --no-checkout &lt;dir&gt; cd dir git sparse-checkout set &lt;git dir to checkout&gt; git checkout master 最后一次结帐在我的工作目录中填充了我在 中需要的文件
【解决方案3】:

Git 克隆有一个选项(--no-checkout-n)可以满足您的需求。

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

git clone <path>

到这里:

git clone --no-checkout <path>

然后您可以使用问题中所述的稀疏结帐。

【讨论】:

  • 是的,它不进行结帐,但仍会进行提取以下载整个回购历史记录
  • @JasonS 这个问题是关于不结账的。如果您不想要,那么整个历史记录使用 git clone 上的 --depth &lt;depth&gt; 选项。这只会下载历史记录中最后的&lt;depth&gt; 提交。目前无法使用 git 部分下载单个提交,但如果您的远程支持它,您可以使用 git archive --remote 下载部分文件集。
  • 您现在还可以使用vfsforgit.org“签出”提交,而无需下载任何文件。如果有人试图只签出单个提交的一小部分,这可能会很有用。
【解决方案4】:

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

【讨论】:

  • --depth 1 被称为浅克隆,仅供参考。
  • 谢谢。在尝试了许多其他方法来阻止下载整个 repo 之后,它是正确的。
【解决方案5】:

在 git 2.28 中工作

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

指定要克隆的文件和文件夹

git sparse-checkout add <folder>/<innerfolder> <folder2>/<innerfolder2>
git checkout

【讨论】:

  • 谢谢,找了一个小时简洁的答案,这是最新的,并且有效。
【解决方案6】:

我从 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 步中路径末尾是否存在尾部斜杠“/”。

【讨论】:

  • 你确定这是你想要的吗? -f 表示获取所有数据,您仍然可以获得所有其他不需要的信息,而且速度很慢。 (这仍然是“检查整个存储库”)
  • 我在 Windows 中尝试了上述步骤,但备用结帐在命令提示符下不起作用,所以我尝试了 Git Bash shell,它成功了!!。命令提示符能够执行所有 git 命令,例如 push、pull 等,但是当涉及到稀疏结帐时,它会失败。
  • 如何只做子目录的文件。我只想获取特定子目录中的文件。
  • @BabishShrestha 查看 onionjake 对 FWIW 其他答案的评论:|
  • 这不会进行稀疏克隆,不如更新的答案有用。顺便说一句,-f 强制执行完整克隆。
【解决方案7】:

遗憾的是,上述方法都不适合我,所以我花了很长时间尝试 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

【讨论】:

  • 不,它仍然会下载所有内容,所有提交和所有文件,git 2.3.2
  • 稀疏检出只影响工作树。它们不会影响存储库大小或获取的内容。如果你愿意,你需要不同的选择。
  • 如果在 Windows 中工作,下次尝试 Git Bash Shell 并通过 'pbetkier' 使用上述步骤,效果很好
【解决方案8】:

2020 年更新答案:

现在有一个命令git sparse-checkout,我详细介绍了with Git 2.25(2020 年第一季度)

niconoanswer 说明了它的用法:

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

它有evolved with Git 2.27 并且知道如何“重新应用”稀疏结帐as in here
请注意,对于 Git 2.28,git status will mention that you are in a sparse-checked-out repository

原答案:2016

git 2.9(2016 年 6 月)将把 --no-checkout 选项推广到 git worktree add(允许与 multiple working trees for one repo 一起使用的命令)

commit ef2a0ac(2016 年 3 月 29 日)Ray Zhang (OneRaynyDay)
帮助者:Eric Sunshine (sunshineco)Junio C Hamano (gitster)
(由 Junio C Hamano -- gitster -- 合并于 commit 0d8683c,2016 年 4 月 13 日)

git worktree man page 现在包括:

--[no-]checkout:

默认情况下,add 签出&lt;branch&gt;,但是,--no-checkout 可用于禁止签出以进行自定义,例如配置稀疏签出

【讨论】:

    【解决方案9】:

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

    这样做的好方法

    D:\Lab>git svn clone https://github.com/Qamar4P/LolAdapter.git/trunk/lol-adapter -r HEAD
    
    1. -r HEAD 只会下载最新版本,忽略所有历史。

    2. 注意trunk和/specific-folder

    /trunk/ 前后复制和更改 URL。我希望这会对某人有所帮助。享受:)

    2019 年 9 月 26 日更新

    【讨论】:

    • 仅适用于来自或使用svn的人。不会赞成这个。
    • @CJohnson 如您所见,我正在克隆 git repo 文件夹。工作正常
    • 请注意,这不是 git 开箱即用的东西,而是 Github 提供的与常规 Git 产品相邻的东西。但是,当您可以使用它时,它会很好地工作。谢谢!
    【解决方案10】:

    基于apenwarrthis answerMiralthis comment,我想出了以下解决方案,在本地克隆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 clone --depth 1 --no-checkout --filter=blob:none file:///…/linux linux-sparse-test (hinted here) 一起工作,因为丢失的文件都作为已删除的文件添加到索引中。因此,如果有人知道git clone --filter=blob:none 对应于git fetch,我们可能可以节省更多兆字节。 (阅读git-rev-list 的手册页也暗示有类似--filter=sparse:path=… 的东西,但我也没有让它工作。

    (全部使用 Debian Buster 的 git 2.20.1 进行了尝试。)

    【讨论】:

    • 有趣的反馈。赞成。我也不知道--filter=sparse:path=…
    • 现在git-rev-list 的手册页已被修改以反映删除--filter=sparse:path 选项:Note that the form --filter=sparse:path=&lt;path&gt; that wants to read from an arbitrary path on the filesystem has been dropped for security reasons.
    【解决方案11】:

    仅稀疏结帐特定文件夹的步骤:

    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。只需克隆整个 repo,然后执行以下所有步骤 2-5(如上所述),您将获得所需的输出。如果您不明白,请告诉我。
    【解决方案12】:

    我是 git 的新手,但似乎如果我为每个目录执行 git checkout 就可以了。此外,稀疏签出文件需要在每个目录之后都有一个斜杠,如所示。请有更多经验的人确认这会起作用。

    有趣的是,如果您签出不在 sparse-checkout 文件中的目录,似乎没有什么区别。它们不会出现在 git status 中,并且 git read-tree -m -u HEAD 不会导致它被删除。 git reset --hard 也不会导致目录被删除。任何更有经验的人愿意评论 git 对已签出但不在稀疏签出文件中的目录的看法?

    【讨论】:

      【解决方案13】:

      在 git 2.27 中,看起来 git sparse checkout 已经进化了。 this 答案中的解决方案并不完全相同(与 git 2.25 相比)

      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 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 --sparsegit-sparse-checkout add

      【讨论】:

      【解决方案14】:

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

      假设 repo 有这样的结构:

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

      您的目标:仅结帐身份/文件夹。包含所有内容,包括子文件夹。

      ⚠️ 这需要至少 git version 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 将通过截断提交历史来进一步提高克隆速度,但它可能会导致here 总结的问题。

      【讨论】:

        【解决方案15】:

        就我而言,我想在克隆项目时跳过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
        

        备注,如果您想跳过更多文件夹,只需在 sparse-checkout 文件中添加更多行。

        【讨论】:

          猜你喜欢
          • 2020-06-10
          • 2016-09-13
          • 2012-06-03
          • 1970-01-01
          • 1970-01-01
          • 2018-04-13
          • 2018-06-18
          • 1970-01-01
          • 2016-02-10
          相关资源
          最近更新 更多