1. 概述
Git 没有直接 clone 子目录的方法,但可以通过 sparse-checkout 实现类似效果,当我们只想检出特定的文件或文件夹时非常有用。
2. 使用 git sparse-checkout
需要说明的是 git sparse-checkout 是实验性的。因此,可能会出现一些非预期行为。
首先我们使用 git clone 克隆仓库:
$ git clone --depth=1 https://github.com/Baeldung/stackify.git
注意我们使用 –depth=1
选项进行浅克隆,仅包含最近的提交。
然后执行 cd 命令,进入仓库所在目录:
$ cd stackify
当前目录包含了全部的文件,我们使用 git sparse-checkout set 检出到所需的子目录如 tomcat-app
:
$ git sparse-checkout set tomcat-app
运行 git sparse-checkout set
后,我们使用 ls -F 列出目录中的文件:
$ ls -F
pom.xml README.md tomcat-app/
可以看到,现在只包含 tomcat-app 文件夹,还有与其平级的文件(这是因为 git sparse-checkout 默认以 cone 模式运行)
在 cone 模式下,同级文件会被包含在检出中。但我们可以通过执行 no-cone 避免这种情况:
$ git sparse-checkout set --no-cone tomcat-app
然后检查列表
$ ls -F
tomcat-app/
然而,如果 working tree 中其他位置存在名为 tomcat-app 的资源,该命令会将它们包含在sparse-checkout中。但是,我们也可以通过pattern来限制:
$ git sparse-checkout set --no-cone tomcat-app/ '!*/tomcat-app'
‘!\*/tomcat-app’
pattern会指导命令忽略 tomcat-app 子目录的兄弟子目录中任何名为 tomcat-app 的子资源:
$ ls -F
tomcat-app/
2.1. git sparse-checkout add
重复运行 git sparse-checkout set 会覆盖先前的设置,如果我们要添加另一个子目录到working tree中,我们可以使用 git sparse-checkout add 命令:
$ git sparse-checkout add webservices
现在,我们有了 tomcat-app 和 webservices 两个子目录:
$ ls -F
tomcat-app/ webservices/
如果一开始想要检出多个目录或文件,我们可以在 git sparse-checkout set 命令中一次性设置。
我们还可以使用 git sparse-checkout 来处理文件。但是,由于 git sparse-checkout 命令仍处于实验阶段,使用它可能会产生意外的结果。
2.2. 禁用sparse-checkout
如果需要恢复原始状态,则运行 disable 命令:
$ git sparse-checkout disable
这样,全部文件又回来了:
$ ls -F
core-java/ core-kotlin/ junit5-example/ logback-example/ pom.xml remote-debugging/ spring-boot-app/ spring-security/ tomcat-app/
core-java-9/ deep-jsf/ log4j2-example/ memory-leaks/ README.md slf4j/ spring-mvc/ thread-pools/ webservices/
3. 使用 git checkout
使用 -no-checkout 克隆时先不检出文件:
$ git clone --no-checkout --depth=1 https://github.com/Baeldung/stackify.git
上面命令只会在本地创建 .git 文件夹,没有其他文件或子目录。我们可以通过 tree 命令验证这一点:
$ tree stackify
stackify
0 directories, 0 files
进入仓库:
$ cd stackify
然后,我们使用 git checkout 检出所需子目录或文件:
$ git checkout master -- tomcat-app
现在,我们只有 tomcat-app 子目录:
$ ls -F
tomcat-app/
使用这种方法从 Git 仓库克隆单个子目录或文件意味着 当我们提交更改时,仓库的其他文件和子目录将会被删除。
因此,当我们可以删除仓库的其他资源时,我们会使用这种方法。或者,我们可以使用这种方法获取文件或子目录,然后通过删除 .git 目录将其从仓库中解关联 - 基本上就像下载文件或子目录。
与 git checkout 方法不同, git sparse-checkout 在我们提交更改时不会删除其他文件和子目录。我们对跟踪资源所做的任何更改都仅影响该资源。因此,即使我们向远程仓库推送,远程仓库中仅跟踪的文件才会更新。
4. 使用 git show
如果已经有一个本地仓库并且我们想下载其中一个文件,我们可以将 git show 的输出重定向到本地文件:
$ git --git-dir ./stackify/.git show master:README.md > /home/baeldung/stackify-README.md
与 git checkout 方法类似,我们仅在需要文件(而不需要整个仓库)时使用此方法。
5. 总结
在这篇文章中,我们讨论了如何使用 git 克隆存储库的子目录以及 git sparse-checkout 的方法。我们也谈到了如何从仓库中克隆资源,而不将其链接到仓库的情况。