【问题标题】:git pre-receive hook fails to execute git commands for other repository on servergit pre-receive 钩子无法为服务器上的其他存储库执行 git 命令
【发布时间】:2020-09-21 05:32:17
【问题描述】:

我的本​​地 docker 上有一个 git 服务器,我在其中托管 2 个存储库:main.gitsub.gitsubmain 存储库中的子模块。两个都是光秃秃的。我尝试在我的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 HEADgit branchfatal: 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


【解决方案1】:

事实证明,git 设置了一些环境变量,为了让 git hook 能够在其他一些 repo 上工作,我们需要取消设置一些变量。添加 unset $(git rev-parse --local-env-vars) 在另一个 repo 上调用 git 命令之前修复了问题。我更新了 gist 脚本,所以它现在应该可以工作了。剩下要做的一件事是检查是否取消设置所有这些变量不会破坏其他东西(例如,如果有更多的子模块等)

@EDIT 在另一个 repo 上调用 git 命令之前添加以下两行可修复此行为。测试了 2 个子模块和一次推送的许多提交

unset GIT_ALTERNATE_OBJECT_DIRECTORIES
unset GIT_OBJECT_DIRECTORY

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2016-06-20
    • 2018-03-25
    • 1970-01-01
    相关资源
    最近更新 更多