【问题标题】:How to git clone a subdirectory of a particular branch of a remote repository?如何 git 克隆远程存储库的特定分支的子目录?
【发布时间】:2020-04-18 11:51:01
【问题描述】:

警告 - 不需要配置 git(如果在最近的 git 版本中将所需选项更改为正确的启用/禁用作为默认值,并且只需要为旧版本进行配置,那么应该没问题)。

git 存储库是托管在 Github 上的远程存储库。

使用--branch <branchname> --depth 1--branch <branchname> --single-branch 克隆单个分支似乎很容易。

克隆存储库的子目录有点棘手。我发现了几个 StackOverflow 问题,询问如何执行此操作 -

  1. How do I clone a subdirectory only of a Git repository?
  2. Cloning only a subdirectory with git
  3. clone parts of a github project

但唯一不涉及跳槽的答案对我的用例有一些不利之处 -

  1. https://stackoverflow.com/a/52269934/4647107 - 我认为文件有 成为本地仓库,不能与远程仓库一起使用。
  2. https://stackoverflow.com/a/37735157/4647107 - 缺点是 虽然它可以让我克隆远程 repo 的子目录,但它让我可以使用 master 而不是我选择的分支。

顺便说一句,我宁愿不必克隆所有历史记录和分支,因为它是一个巨大的存储库,并保留 --depth 1-r HEAD 或不会克隆所有内容的替代命令。但如果不可能,那也没关系。

【问题讨论】:

  • 分支是存储库的一个非常不同的“子集”,而不是子目录。 Git 处理提交。分支是提交的连续子集,作为一个单元获取是有意义的。但是,子目录由可能只需要一组“未连接”提交的文件组成,并且这些提交仍然包含有关存储库中所有文件的信息,而不仅仅是您想要的子目录中的文件。
  • @chepner 这让我觉得顺序需要正确——首先选择我们想要的分支,然后选择我们想要的子目录。这是git不允许的吗?
  • 基本上,Git 不是为支持 SVN 工作流而构建的。如果您死忠于 SVN 的做事方式,请坚持使用 SVN 并接受其局限性。但是要求一个特定的机制几乎是现在所谓的“xy 问题”的定义标志,你已经有了一些解决问题的解决方案,并且正在寻求帮助实施该解决方案中的一个步骤,而完全不同的方法会只是简单的工作更好。克隆提交的任意子目录到底是为了解决什么问题?

标签: git github


【解决方案1】:

你真的不能做你想做的事:git clone 不会克隆一个子目录。

您也许可以很容易地做到需要。这取决于您对远程计算机上的 Git 存储库拥有何种访问权限。

As chepner commented,Git 存储提交。提交本身形成链,人类倾向于将其称为分支。任何给定的链都在其最近的提交处结束,Git 将其称为分支的提示提交,并且分支名称通过其哈希 ID 简单地标识此最近的提交. (每个提交都有一个唯一的哈希 ID。)

现在,每个提交,无论它在存储库中的什么位置,都包含每个文件。每个提交中的文件都存储在一个特殊的、只读的、仅限 Git 的形式中,并应用了压缩和各种技巧,因此重新提交 same 文件不会占用额外的空间。只有 Git 本身可以读取这种特殊格式。1

更准确地说,提交包含应该在该提交中的每个文件,这样如果您拥有整个存储库,则可以告诉 Git:get me commit a123456...(通过它的哈希 ID),Git 会将提交提取到工作区。在工作区中,您现在将拥有可以使用的普通日常文件格式的普通文件。 (这就是为什么我们称它为您的工作区,或工作树工作树。)

但是请注意,这意味着每个提交也是一个存档。 Git 发行版包括 git archive 命令,它将特定于 Git 的文件归档转换为两种标准的非 Git 归档格式之一:zip 或 tar。 (未来可能会添加更多格式,但这两种格式在 Git 中存在的时间几乎与 git archive 存在的时间一样长。)

这意味着任何拥有存储库克隆的人都可以将任何提交转换为这些档案之一。然后,您可以使用存档器本身(unziptar)来仅提取此存档中所需的文件子集。

如果拥有 Git 存储库的站点允许您运行任意命令,请前往那里并从您想要的文件的提交中创建一个存档,然后在那里操作存档。如果站点是 GitHub 或类似站点,请注意它们提供了一个接口,可以从任何给定的提交中获取 tar 或 zip 存档,并使用该接口将此存档复制到您的计算机并在那里操作该存档。

git 存储库是托管在 Github 上的远程存储库。

因此,您可以使用任何网络浏览器获取任何提交的 zip 存档:导航到所需的提交,单击“克隆或下载”,选择“zip”,浏览器应将生成的 zip 文件保存在某处。

(要自动执行此操作,请注意下载 zip 文件的 URL。它可能会嵌入一个提交哈希 ID。使用类似 curl 的程序自行下载,而无需启动浏览器。)

请注意,这些档案不是 Git 存储库,您不能对它们进行任何 Git 工作。但是,如果您只打算提取文件的一个子集,那么结果将无法用于存储库的任何克隆 - 至少,如果这样做,则不会。2

如果这两个都不可用,您可以使用git clone -b <branch-name> --single-branch --depth 1 制作深度为 1 的 浅克隆(即,仅一次提交),仅复制由指定名称标识的一次提交分支。现在你有一个非常有限的克隆,其中只有一个提交,所以现在你可以在一个提交上运行git archive,如果你愿意的话。当然,此时您可以只git checkout 一次提交,然后将整个所需的子目录移出工作树,然后删除 Git 存储库。

无论您做什么,如果没有原始 Git 存储库的真实(可能是浅层)克隆,就无法将这些东西放回原始 Git 存储库。你的问题从来没有提到你打算用这个从一个特定提交中提取的子目录做什么。


1格式是公开的,所以任何人都可以编写程序来读取它。不过,读取它的程序基本上是 Git,所以你不妨只使用 Git——尤其是因为 Git 保留拥有未来格式的权利,如果你编写自己的 Git 版本,并且明年 Git 会添加一种新格式,那在某些情况下效果更好,您也必须更新自己的程序。

2git subtree 提供了一些工具来做一些在机制上非常不同但在某些目标方面相似的事情。只要您遵循许多非常特殊的规则,就可以稍后重新合并已拆分的子树。但是,要使用git subtree,您需要一个完整的克隆,您已经拒绝了它作为一个选项。规则本身也很繁琐(“跳过铁环”),你觉得这是不受欢迎的。

【讨论】:

    猜你喜欢
    • 2011-04-03
    • 1970-01-01
    • 2012-05-06
    • 2017-06-02
    • 2021-10-08
    • 1970-01-01
    • 2011-02-02
    • 2016-05-02
    • 2016-12-17
    相关资源
    最近更新 更多