繁体   English   中英

在子文件夹中作为git钩子的一部分运行时,为什么git命令失败?

[英]Why does `git` commands fail when run as part of a git hook in a subfolder?

最近,我们将Node项目移到了Mono-repo的子文件夹中,此后,由于在错误的目录中执行,我们的提交挂钩(使用Husky安装)开始失败:

{ Error: Command failed: git rev-parse HEAD
fatal: not a git repository: '.git'

    at ChildProcess.exithandler (child_process.js:297:12)
    at ChildProcess.emit (events.js:197:13)
    at maybeClose (internal/child_process.js:978:16)
    at Socket.stream.socket.on (internal/child_process.js:395:11)
    at Socket.emit (events.js:197:13)
    at Pipe._handle.close (net.js:611:12)
  killed: false,
  code: 128,
  signal: null,
  cmd: 'git rev-parse HEAD' }

我没有解决该问题的问题(基本上在执行钩子中的任何git命令之前将cd -ing到根目录),但是我没有得到的是为什么(未修复的)脚本在命令行上可以工作-无论如何我从哪个文件夹执行它们?

该脚本的失败部分基本上是:

console.log('PWD', cp.execSync('pwd'));
console.log(cp.execSync('git rev-parse HEAD'));

项目布局

.git/
frontend/
  package.json
backend/

将触发上述错误的示例命令:

git checkout master

除错误外,它PWD /tmp/foo/myproj/frontend打印工作目录: PWD /tmp/foo/myproj/frontend

如果我手动触发脚本,则一切正常:

npm run postcheckout
PWD /tmp/foo/myproj/frontend

82dc6d2089a397f0889addb562ea84ba8d846215

无论是根文件夹还是子文件夹,此方法都有效,我看不出有什么区别。 Husky应该找到了.git文件夹,这似乎可以证明这一点,但是当它作为一个钩子脚本运行时,显然会有所改变。 自动生成的Husky脚本的相关部分是:

cd "frontend"
...
...
npm run postcheckout

TL; DR:未设置$GIT_DIR (在sh脚本中,未unset GIT_DIR )。

githooks文档中有一个提示:

在Git调用钩子之前,它将其工作目录更改为裸存储库中的$ GIT_DIR或非裸存储库中工作树的根。 例外是在始终在$ GIT_DIR中执行的推送( 预接收更新接收 后,更新推送到结帐 )期间触发的钩子。

顶层Git手册页中另加了一些:

--git-dir = <路径>
设置存储库的路径。 也可以通过设置GIT_DIR环境变量来控制。 它可以是当前工作目录的绝对路径或相对路径。

GIT_DIR
如果设置了GIT_DIR环境变量,则它为存储库的基础指定要使用的路径,而不是默认的.git --git-dir命令行选项也会设置该值。

这里发生的是,顶层Git 程序$GIT_DIR设置为要找到.git目录的路径。 由于挂钩已将其工作目录更改为工作树,因此Git程序已将$GIT_DIR设置为.git 如果您在其他地方使用chdir ,则必须适当地调整$GIT_DIR如果您将chdir完全远离主存储库并希望Git再次发现 $GIT_DIR ,则必须取消设置 $GIT_DIR

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM