【发布时间】:2020-09-21 05:32:17
【问题描述】:
我的本地 docker 上有一个 git 服务器,我在其中托管 2 个存储库:main.git 和 sub.git。 sub 是 main 存储库中的子模块。两个都是光秃秃的。我尝试在我的main repo 中添加一个 pre-receive 挂钩,以检查我是否没有引用丢失的子模块修订版(例如,如果有人在推送主 repo 之前忘记推送子模块)。我使用这个脚本:https://gist.github.com/T3sT3ro/902d67f29d2c913b3fef6034776777e0,这是一个稍微固定的版本:https://gist.github.com/bagage/bdca3d4b66d43db7a5e3。
很遗憾,这个脚本不起作用。如果从 main 存储库的 pre-receive 钩子内部启动,为 sub 存储库执行的任何 git 命令都会失败。当手动运行时,一切似乎都很好。例如,执行git log|show 会导致bad object HEAD 和git branch 在fatal: missing object 78f5da8ed1f83047d0f68fe17e5eaf86060038c3 for refs/heads/master,即使在sub repo 中手动运行git branch --contains 78f5da8ed1f83047d0f68fe17e5eaf86060038c3 也可以正常工作:打印* master。
运行git fsck for sub repo in hook(设置调试变量)返回:
remote: 16:45:32.575940 trace.c:318 setup: git_dir: .
remote: 16:45:32.575961 trace.c:319 setup: git_common_dir: .
remote: 16:45:32.575967 trace.c:320 setup: worktree: (null)
remote: 16:45:32.575971 trace.c:321 setup: cwd: /var/www/git/sub.git
remote: 16:45:32.575976 trace.c:322 setup: prefix: (null)
remote: 16:45:32.575982 git.c:344 trace: built-in: git fsck
remote: error: HEAD: invalid sha1 pointer 78f5da8ed1f83047d0f68fe17e5eaf86060038c3
remote: error: refs/heads/master: invalid sha1 pointer 78f5da8ed1f83047d0f68fe17e5eaf86060038c3
remote: notice: No default references
remote: 16:45:32.580070 read-cache.c:1925 performance: 0.000004548 s: read cache ./index
remote: 16:45:32.580107 trace.c:420 performance: 0.004374272 s: git command: git fsck
remote: dangling commit 468626a3126e8139a08727ff3c1b25f37e23f957
我尝试将钩子的所有者和组更改为与其他文件相同,但它不起作用。这有点像某种安全机制,但另一方面,我可以在sub repo 中使用touch 文件。从上面的 fsck 日志中我们还可以看到 78f5da... 存在于某处...
repro 是这样的:创建 main 和 sub repo,向两者推送一些初始提交,将 sub 作为子模块添加到 main,在 sub 上提交而不推送,在 main 添加 sub(main 现在应该引用 sub repo 的本地提交) ,尝试推送主仓库(失败 - 预期),推送子仓库,尝试推送主仓库(再次失败 - 现在出现这些错误)。
服务器上的 git 版本:2.17.1
【问题讨论】:
-
您的示例脚本中没有
git fsck命令。当你添加它时,你是否也像脚本中的其他 Git 命令一样导出了GIT_DIR="$url"? -
是的,我尝试将 GIT_DIR 甚至
cding 设置到sub目录中 - 仍然是同样的错误。 -
对于
git fsck,如果它设置为完整路径就足够了;对于某些操作,您需要同时执行这两项操作。我注意到调试输出显示git_dir: .,这意味着您将再次需要两者。请注意,很难调试您实际上没有显示的脚本:-) -
脚本在 gist 中链接...无论如何:已修复
-
gist 链接没有
git fsck调用,这就是我在这里要说的。如果您的 Git 具有--local-env-vars标志,那么取消设置本地变量 仅用于子模块访问的技巧是您的方法。
标签: git git-submodules githooks