【问题标题】:git post-receive hook can not jump back into original cwdgit post-receive hook 不能跳回原来的 cwd
【发布时间】:2011-10-03 05:34:56
【问题描述】:

当推送到我们共享的裸存储库(通过 ssh)时,提交后无法正常工作。
这是很常见的,因为我在这里的许多线程中都发现了它,它适用于同一服务器上的其他两个存储库,这让我发疯了。

#!/bin/sh
GIT_WORK_TREE=/ab/cd/staging git checkout -f

存储库本身与钩子要签出到的目录位于同一目录中

/ab/cd/barerepo

推送时,它不会将文件检出到预期的路径,但会给出以下错误消息:

Writing objects: 100% (3/3), 299 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
fatal: Could not jump back into original cwd
error: hooks/post-receive exited with error code 128

我找不到任何关于这意味着什么的信息。 (据我所知,Google 只会从对 git 本身的贡献中提出提交)。所以我阅读并猜测并尝试了......

  • 在接收后挂钩中额外设置 GIT_DIR
  • 使用 --git-dir=/ab/cd/barerepo --working-dir=/ab/cd/staging 重新初始化裸仓库
  • 在 barerepo/config 中手动设置工作目录
  • 将裸仓库设置为空白并提交
  • 通过克隆设置裸仓库

现在的配置是这样的

[core]
     repositoryformatversion = 0
     filemode = true
     bare = true

但我也有这个(不费吹灰之力)

[core]
    repositoryformatversion = 0
    filemode = true
    bare = true
    sharedrepository = 1
    worktree = /ab/cd/staging
    logallrefupdates = true
[receive]
    denyNonFastforwards = true

我还在 post-receive 钩子中添加了第二行

echo "post-receive done" > updated.txt

它将文件写入裸存储库的目录。这对我来说很有意义,因为 GIT_DIR 似乎设置为“。”,这得到了我从另一个 SO 问题中得到的后接收片段的证实

echo Running $BASH_SOURCE
set | egrep GIT
echo PWD is $PWD

结果:

Running hooks/post-receive
GIT_DIR=.
PWD is /ab/cd/barerepo

那么我怎样才能让 git 跳回原来的 cwd(当前工作目录?)? 仅供参考:我对 git 仍然很陌生,并且有一种愚蠢的感觉,我错过了一些明显的东西,但是没有找到关于这个特定错误消息的任何重要信息让我感到奇怪。推送本身工作正常,顺便说一句。

【问题讨论】:

  • 此存储库的暂存目录的权限是否正确?也就是说,它们是否与有效的存储库相同?
  • 是的,暂存目录都有drwxrwxr-x,相同的用户和相同的组(gitusers)。推送到 repo 的用户也是该组的成员。存储库中的子目录具有drwxrwsr-x,因此当用户推送他们的提交时,该组保持 gitusers。

标签: git git-post-receive


【解决方案1】:

我在十分之一的网站上也遇到过这个问题,托管在同一台服务器上。

每个站点在我们的开发人员推送的 Web 服务器上都有一个裸仓库(不暴露在 Web 上)。和你一样,我们使用 git post-receive 钩子然后将GIT_WORK_TREE=/whatever/livesite git checkout -f 放入包含实际 Web 服务器根目录的目录。

检查与fatal: Could not jump back into original cwd 失败的那个有什么不同,我发现在所有工作情况下,存储库名称都是这样的:

/var/www/coolsite.com.git   <-- bare repo
/var/www/coolsite.com.live  <-- checked out from hook; contains site root in public subdir

一个错误是这样的:

/var/www/brokensite.com.git  <-- bare repo
/var/www/brokensite.com      <-- checked out from hook; contains site root in public subdir

因此,让实时签出副本具有这样的名称会导致 git 抛出此错误。将实时站点工作副本 repo 的名称更改为以“.wtf”结尾解决了问题(我最终像其他人一样使用了“.live”)。

在我的例子中,Git 的服务器版本是 1.6.1,而开发机器都是 1.7.5.4。

所以裸回购和实时回购的名称似乎有影响。不确定这是 git 中的错误还是只是 'foo' 和 'foo.git 的某些神奇等效性的副作用。

【讨论】:

  • 对于那些在那里搜索的人来说,这也解决了我的问题。
  • 为我修复了它。摘要:签出的 repo 不能与裸 repo 具有相同的目录名称(唯一的区别是 .git dirname 后缀)。更改其中一个的名称。谢谢!
  • 奇怪。如果工作目录是裸仓库的任何子字符串,则它会失败,例如$HOME/www$HOME/www-repo
  • 有这个完全相同的问题(由上述解决方案修复)。根本没想到会这样,这可能是 .git 错误吗?
【解决方案2】:

根据我的经验,您的问题在于您的 .git 存储库和工作树目录(您的 post-receive 挂钩正在检出的目录)在同一个目录中:ab/cd。

我也是 GIT 新手,这篇文章对我帮助很大,非常感谢!在消除了您已经尝试过的所有修复程序之后,我偶然发现了一个帖子(恐怕我现在找不到它)读取 .git 存储库并且工作树目录不能在同一个目录中。

我不知道为什么。

例如,您的 /var/www 中有 /staging/ 目录。这意味着您应该将裸露的 .git 存储库放在 /var/GIT(或其他东西)中,而不是 /var/www。

我遇到的另一个问题是权限,因此我对两个目录进行了chown'ed 和chmod'ed,以确保与我一起推送的远程用户有权读取/写入这两个目录。

无论如何,我做到了,我从你所在的地方得到了这个:

Counting objects: 3357, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2848/2848), done.
Writing objects: 100% (3057/3057), 15.20 MiB | 4.70 MiB/s, done.
Total 3057 (delta 1536), reused 0 (delta 0)
Checking out files: 100% (3720/3720), done.
To ssh://xxxxxx@xxxxxxxxxxxxxxx/var/GIT/project.git
   945fe94..dbe1f0b  master -> master

那还有一个很好的检查目录,里面装满了代码:)

【讨论】:

  • 我们问题的根源不可能真的是同一个基目录,因为它也适用于其他存储库。
  • 完全正确!!!我花了半天时间调试它。一些指针。它只发生在钩子上而不是直接发生。输入export PATH=$PATH:"/usr/local/ 以确保 git 命令可用。把exec &amp;&gt;&gt; $LOGFILE从你的git命令中捕获错误信息。
【解决方案3】:

服务器更新到 git v1.7.5.4 后问题就消失了。看来从 v1.5x(服务器)到 1.7x(本地)的差异太大了。

【讨论】:

    猜你喜欢
    • 2015-03-22
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多