如何在不下载其父文件夹的情况下签出或克隆文件夹

Posted

技术标签:

【中文标题】如何在不下载其父文件夹的情况下签出或克隆文件夹【英文标题】:How to checkout or clone a folder without downloading its parent folder 【发布时间】:2021-03-14 09:45:47 【问题描述】:

我只想从 gitlab 中检出一个文件夹,而没有它的父文件夹和层次结构中的其他父文件夹。 我们的 gitlab 存储库结构类似于 hybris/bin/custom/asampasamp 文件夹还有其他文件夹。我只想签出 asamp 文件夹 我一直在尝试此链接上给出的解决方案 - How do I clone a subdirectory only of a Git repository? 但我无法仅下载 asamp 文件夹,它还会下载完整的层次结构,即我可以在本地存储库中看到 hybris/bin/custom/asamp。请注意,当我进行稀疏检出时,不会下载与 asamp 同级的其他文件夹,但会检出我不想要的完整层次结构。我只想下载 asamp 文件夹,而不是其父文件夹。 我正在使用 gitlab。

【问题讨论】:

有很多方法可以做到这一点,但到目前为止,最简单的方法是上游维护各个历史记录的分支。切片和切块历史涉及权衡,目前尚不清楚您最有兴趣在这里避免什么痛苦; Git 之所以如此高效,是因为它不会让每个人都为每个人都很少需要的灵活性支付每个操作的开销,而缺点是确实需要它的人有一些工作要做。请详细说明您所处的情况,包括您不想支付的具体费用,然后我可以提供帮助。 @jthill 有一个客户使用的 hybris 框架,安装此框架后客户试图从自定义目录中获取项目,例如 asamp 直接签出到 hybris 框架的安装目录,这样他们可以快速测试更改并最终推送到 gitlab 【参考方案1】:

在您链接的帖子中:答案使用了一些需要 git 服务器支持的选项(即:--filter=blob:none)。

此答案的作者强调 Github 现在支持它,而且它的支持似乎是最近才出现的——“Github 支持它”是作者在 2020-09-18 上添加的(两个月前),我还没有扫描 github 的更新日志来查看他们添加支持的确切日期。

您必须检查 Gitlab(或 Gitlab 社区版,如果您使用的是该版本)是否特别支持此功能。如果没有:仅通过 git 命令下载“仅该文件夹”将没有简单的方法。


另一方面,常规 Gitlab 的 Web GUI 允许您浏览到任何提交中的任何子目录,并下载该子目录(“克隆”按钮旁边的下载图标,然后选择“下载此目录”选项)。

弄清楚下载网址是如何构建的,您可以使用任何网络客户端下载相同的存档(例如:curlwget ...)

【讨论】:

您好 LeGEC,gitlab CE 支持此功能--filter=blob:none,但我看到同样的问题,即层次结构中的父文件夹已签出。 你运行了什么命令只签出子目录? git checkout master -- path/to/asamp ? 是的,我运行了你提到的命令git checkout master -- hybris/bin/custom/asamp 可能是gitlab不支持的那部分。尝试设置GIT_TRACE=1 git checkout ...,或者设置GIT_TRACE_PACKET=1 git checkout ...,以便更深入地了解在该特定步骤中发生的情况。 即使下载也获得完整的文件夹层次结构,即当我尝试下载 asamp 目录时,我得到完整的层次结构下载为hybris/bin/custom/asamp【参考方案2】:
git clone -n --depth 1 --filter=tree:0 u://r/l asamp; cd $_
git read-tree -um @:hybris/bin/custom/asamp
git reset --soft $(git commit-tree -p @ -m "just asamp" `git write-tree`)

将为您提供该目录的最低下载检查。 Git(但我认为不是 github 之类的子集/超集替代品)甚至可以通过最小结帐合并和 -s subtree 合并策略将其合并回来。

要将您的工作重新插入上游历史记录,您需要使用该子树合并策略。 git branch 会告诉你你开始的分支的名称,我假设它是 master

$ git branch
* asamp
  master
$

现在制作一个无签出的临时克隆,并将您的工作合并到上游主节点而不签出:

git clone -nsb master -o local `mktemp -d`; cd $_
git reset -q
git merge -s subtree asamp

将其推回您的本地仓库:

git push local master
cd -

并将其推回您的上游:

git push origin master

【讨论】:

您好@jthill 感谢您的回答,我只能签出 asamp 文件夹,而层次结构中没有父文件夹,但在推送操作中它完全弄乱了我的存储库,不用担心我正在测试 gitlab 实例上做这个练习。运行 push 命令后,我的整个存储库都被替换为 asamp 文件夹的内容,请查看我下面的评论作为此评论的扩展名 最初存储库结构是hybris/bin/custom/asamp/* custom 文件夹下有很多文件夹,即asamp 文件夹的同级文件夹,但在运行asamp 文件夹是直接上传的存储库,替换了之前的所有内容,即在根级别之前有 hybris 文件夹,但现在在根级别有 asamp 文件夹 是的,您必须将其与子树策略合并回来,您必须在本地执行此操作。为了避免检查整个事情,您需要进行最小检查合并。我错误地从“asamp”中推断出您正在查看样本或做作业,并且将继续前进到第二个分支。您没有弄乱您的存储库,您可以将其重置回旧提示。我将编辑如何进行最小结帐合并。 如果你的客户不想做subtree mergeback,他们可以push他们做的asamp分支,你就可以合并了。

以上是关于如何在不下载其父文件夹的情况下签出或克隆文件夹的主要内容,如果未能解决你的问题,请参考以下文章

如何在不知道 JGit 本地是不是存在的情况下签出远程分支?

在不签出的情况下将文件提交到不同的分支

如何在不首先克隆整个 repo 的情况下将文件添加到远程 Git repo (Github)

如何在不首先克隆的情况下“连接”一个 git 存储库?

如何在不添加我自己的 prop 的情况下将内置的 Vuetify 组件 prop 从其父级应用到 SFC 的根元素?

如何在不克隆它所连接的存储库的情况下触发 Jenkins 构建?