Git repo其中每个子模块是同一个repo的一个分支。如何避免双/三...下载与git clone --recursive?

时间:2017-04-11 20:58:39

标签: git

假设我有以下项目树:

src
data
doc

我想将所有文件夹保存在Git存储库中,并发布到Gitlab。但我不想跟data一起追踪docsrc

所以我使用以下策略:

git remote add origin ADDRESS
git submodule add -b data ADDRESS data
git submodule add -b doc ADDRESS doc

它实际上工作正常,除非我尝试使用以下命令复制存储库:

git clone --recursive ADDRESS

所有对象都会被传输3次:根和data以及doc都包含:

  • 起源/主
  • 起源/数据
  • 起源/文档

有一种简单的方法可以避免这种情况吗?只是为了澄清我想要的东西:

  • 主存储库应仅提取origin/master,而不是其他两个
  • 数据子模块只应提取origin/data
  • doc子模块应该只提取origin/doc

使用3个独立的存储库很容易实现,但这太麻烦了,因为我将这种方法应用于多个项目。

更新

来自this answer

git worktree可让我实现我想要的手动。

但是现在,而不是自动方法(消耗4倍带宽):

git clone --recursive git@foo:foo/bar.git

我必须这样做:

git clone git@foo:foo/bar.git
cd bar
git worktree add data origin/data
git worktree add src/notebooks origin/notebooks
git worktree add doc origin/doc
git worktree add reports origin/reports

我可以使用一些脚本自动执行此过程,因为.gitmodules文件已包含完整信息:

[submodule "data"]
    path = data
    url = git@foo:foo/bar.git
    branch = data
[submodule "src/notebooks"]
    path = src/notebooks
    url = git@foo:foo/bar.git
    branch = notebooks
[submodule "doc"]
    path = doc
    url = git@foo:foo/bar.git
    branch = doc
[submodule "reports"]
    path = reports
    url = git@foo:foo/bar.git
    branch = reports

我想知道是否已经有一些标准的git脚本或标志处理这个?

2 个答案:

答案 0 :(得分:1)

Git旨在分发,这意味着每个用户都应该拥有完整的历史记录和所有分支。如果您想拥有一个裸存储库,但需要使用不同的工作树来减少网络流量,可以使用git worktree命令执行此操作:

所以在你的情况下,让我们说你有一个src文件夹作为src分支的主文件夹,从中创建另外两个文件应该就像

一样简单
git worktree add ../data data
git worktree add ../doc doc

请参阅此极好的答案https://stackoverflow.com/a/30185564/3066081以获取有关此命令的更多信息。但是如果你有一个没有worktree支持的旧git,你可以使用git-new-workdir脚本作为

git-new-workdir project-dir new-workdir branch

Multiple working directories with Git?

中也对此进行了描述

答案 1 :(得分:0)

警告:“ git worktree添加”在内部调用“ reset --hard”,即使设置了submodule.recurse,但该子模块也不应该属于子模块,但是受到了影响。

此问题已在Git 2.25(2020年第一季度)中得到纠正。

请参见commit 4782cf2Philippe Blain (phil-blain)(2019年10月27日)。
(由Junio C Hamano -- gitster --commit 05fc647中合并,2019年12月1日)

  

worktree:教导“添加”忽略子模块。递归配置

     

签名人:Philippe Blain

     

git worktree add”内部调用“ reset --hard”,但是如果设置了submodule.recurse,则reset尝试递归到初始化的子模块中,这使得start_command尝试进行{{1 }}进入不存在的子模块路径并消失。

     

通过确保不会重拨“ cd”中的调用来解决此问题。