与git子模块共享工作树

8
假设我有一个名为 Common 的库,可以独立使用,并被项目 P1P2 使用,所以我想要的目录树应该是这样的:
/Common/.git
        ...
/P1/.git
    .gitmodules  # points to remote server
    Common/
    ...
/P2/.git
    .gitmodules  # points to remote server
    Common/
    ...

当我在/Common中进行更改时,我希望能够在提交之前使用P1P2进行测试。使用通常的git submodule命令集,我必须从/Common提交,推送到远程,然后从/P1/Common/P2/Common拉取。如果提交出现问题,则无法进行修改,因为坏的更改已经发布。或者,我可以从/P?/Common中使用git remote add quicktest /Common进行添加,以便能够在不触及远程服务器的情况下进行拉取。但这会有很多不一致的机会,而且将坏的提交从/P?/Common剥离以便在/Common中进行修改是不好的。
我希望在开发期间,P1P2都使用/Common的工作树,但我不能将/P1/Common设置为/Common的符号链接,因为git submodule将符号链接识别为与目录不同的东西。大多数文件系统不允许对目录进行硬链接。我可以使用以下方式来硬链接所有文件:
rm -rf /P1/Common
cp -rl /Common /P1/Common

这个方法在/Common目录下添加新文件时就无法正常工作了,需要重复执行这个过程。是否有更好的方法既能让最终用户保持使用git clone --recursive git://remote/P1.git,又能让我轻松测试/Common目录中对P1P2的更改是否有效呢?

  1. 如何保证最终用户能够继续使用git clone --recursive git://remote/P1.git
  2. 如何让我方便地测试/Common目录中对P1P2的更改是否有效?

尝试在你的子模块上使用git工作树功能(自git 2.5起)。并查看此答案:https://dev59.com/C14c5IYBdhLWcg3w7t_E#44649319 - Yue Lin Ho
2个回答

1
尝试使用自Git 2.5以来的git工作树功能。
  1. 删除/P1/Common
  2. cd /Common
  3. 为即将到来的/P1/Common工作树创建P1分支
  4. 运行git worktree add ../P1/Common P1

/P2上执行同样的操作。

然后,/P1/Common/P2/Common/Common工作树共享同一个存储库/Common/.git`

您可以轻松地检出在另一个工作树中提交的任何提交。

附注:您仍然可以使用git子模块命令来进行日常工作,同时使用此git工作树功能。


0

我宁愿建立一个中间的裸仓库,用于:

  • 推送Common的新提交
  • P1/CommonP2/Common拉取

至少,如果以后修改/删除提交,该中间仓库从未发布到外部,您仍然可以将P1/CommonP2/Common子模块重置为该中间仓库的内容。


更新:如果你正在使用git worktree,自 Git 2.5 起(本答案撰写于 5 年前的 2015 年 7 月),请确保使用Git 2.25 (2020 年第一季度)
在此之前,"git worktree add" 内部调用了 "reset --hard",这会影响子模块。

git clone --bare /Common /Common-bare; cd /P1/Common; git remote add quicktest-bare /Common-baregit remote add quicktest /Common进行比较。裸仓库似乎没有添加任何内容,也不涉及远程操作。但是这两种方法都需要多个步骤来测试补丁。使用git push -f可以清除/Common-bare,但是额外的间接性似乎没有增加任何内容。我的问题的重点是我想要减少步骤的数量,而不是增加步骤。 - Jed
@Jed:然后将Common(本地的,你提交的地方)作为P1/CommonP2/Common的远程仓库添加,并直接从那里拉取 - VonC
...并推送。您可能已经注意到/P1/.gitmodules现在指向一个不存在的版本。也许这正在变成一个新功能,但我认为将/P1/Common作为指向/Common的符号链接是可取的,而不会使git将符号链接视为普通文件(就子模块版本控制而言)。我想知道为什么git submodule拒绝跟随符号链接。 - Jed
@Jed:为什么这些pulls没有别名?(每次从P1和P2拉取的别名) - VonC
例如shell脚本?我不喜欢在脚本中放置破坏性操作,主要是因为错误处理和(在其他相关情况下)可组合性的原因。但我认为你说得对,在这种情况下,shell脚本是足够的。请注意,shell脚本也可以只是cp -rlTf /Common /P1/Common,然后甚至不需要提交,对现有文件的编辑也会自动显示(甚至不运行上述命令)。 - Jed
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接