【问题标题】:Git checkout in post-receive hook: "Not a git repository '.'"接收后挂钩中的 Git 结帐:“不是 git 存储库 '。'”
【发布时间】:2012-05-17 11:41:52
【问题描述】:

我的服务器上有一个非裸存储库(目录 /home/andrew/web 和 /home/andrew/web/.git),将 receive.denyCurrentBranch 设置为忽略并创建 post-receive 钩子:

#!/bin/sh
GIT_WORK_TREE=/home/andrew/web git checkout -f

当我运行 sh .git/hooks/post-receive 时,一切正常。但是当我从我的电脑推送时,我收到了这个错误:

remote: fatal: Not a git repository: '.'

有什么办法可以解决这个问题吗?最终无需切换裸仓库?

谢谢

编辑:这是我的新接收后挂钩。接受的答案中已经描述了为什么会这样。

echo "\nChecking out $PWD"
GIT_DIR=/home/andrew/web/.git
GIT_WORK_TREE=/home/andrew/web git checkout -f

【问题讨论】:

  • 你使用什么命令来推送,特别是:远程 url 是什么?
  • @Simon 我使用“git push origin”,我的远程 URL 是“andrew@example.com:web”。
  • 您可以尝试完整路径andrew@example.com:/home/andrew/web,但我认为真正的问题是您的远程仓库不是裸露的。您可以尝试强制推送:git push -f origin
  • 好的,所以我再次尝试了裸仓库,这是一场艰苦的斗争。我有 web.git/ 但想将文件放在 web/ 中 - 我尝试设置“git config core.worktree /home...web/”,但随后它抱怨说使用 worktree 毫无意义。我还尝试在 web/ 目录中创建一个“ln -s /home...web.git .git”,但是如果我在 web/ 和 web.git/ 中键入“git log”,我看不到web/中的最新提交。有没有办法做到这一点?

标签: git


【解决方案1】:

[编辑,2017 年 2 月:这个旧答案仍然受到一点影响,所以让我们添加一些注释。 (1) 这种实时更新通常是一个坏主意:确保您知道为什么要这样做,并且不会破坏自己的工作。 (2) 在 Git 2.3 之后,您现在可以将 receive.denyCurrentBranch 配置为 updateInstead,以及 Git 2.4 及更高版本中的挂钩调整。详情请见the git config documentation。]

$GIT_DIR 设置为. 的情况下运行接收后挂钩。这会导致 git 寻找./HEAD./refs/heads/master 等,而不是.git/HEAD.git/refs/heads/master 等。但是,由于您没有做任何事情来更改挂钩中的$PWD(反正如图所示) ),钩子将在.git 子目录(/home/andrew/web/.git)中运行,因此这个失败非常神秘:. 实际上是一个有效的 git 存储库。

避免硬编码路径名的一个标准技巧是使用cd ..; git checkout -f 作为接收后挂钩。这就是$GIT_DIR 的设置成为问题的地方,因为在cd .. 之后,钩子正在运行(仍然假设这种情况)/home/andrew/web,当然此时$GIT_DIR 应该是.git 而不是@ 987654341@。对此的标准解决方法是简单地取消设置 GIT_DIR(将其设置为 .git 也可以)。

不过,您的 post-receive 挂钩对我来说效果很好(通过适当的硬编码路径更改)。然后我再次从类似 Unix 的机器上推送,而不是 PC。是否有可能发生其他事情,将目录从.git 子目录中更改出来?您可以在钩子中执行echo running in $PWD 之类的操作,以查看您的位置。

【讨论】:

  • 谢谢!我花了很长时间,没有人能够解释。
  • $GIT_DIR 设置为 .gitcding 到该目录对我有用。谢谢!
  • @Timo:我不确定您对这个特定评论的要求是什么(我已经回答了另一个评论),但总的来说,前面的 --git-dir--work-tree 选项结束git 命令实际上只是设置了环境变量GIT_DIRGIT_WORK_TREE。前端git 准备环境,将Git 自己的git-core 目录添加到$PATH,进行任何其他适当的内务管理,然后——已被调用为git [flags] subcommand [more-flags-and-args]——运行git-subcommand 并带有额外的标志和论据。 [继续]
  • 这是环境中GIT_WORK_TREE的设置,此时,导致由于core.baretrue而通常会停止的Git命令忽略core.bare设置并继续并使用指定的工作树。所以git checkout master -f 运行git-checkout master -f,并设置了这些环境变量。其余的取决于git-checkout 程序本身。 [继续]
  • git-checkout 所做的,只要它做任何事情,就是:(1) 确保工作树存在(通过创建它,或者通过测试它,谁知道哪个版本的 Git 会做哪一个)。 (2) 阅读索引,看看它认为会有什么。 (3) 阅读 commit-to-be-checked-out 以查看需要存在的内容(替代或附加)。 (4) 如果没有-f,请确认可以删除和/或替换任何需要换出的文件和/或创建任何需要创建的目录。使用 -f,继续。 (6) 根据需要删除、创建等。 (7) 更新索引。
猜你喜欢
  • 2011-01-09
  • 1970-01-01
  • 2020-12-19
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-15
  • 2011-03-28
相关资源
最近更新 更多