我们最近将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' }
我没有解决问题的方法(基本上在执行钩子中的任何cd
命令之前将git
插入根目录),但是我没有得到的是为什么(未固定的)脚本在命令行上起作用-不管我从哪个文件夹执行它们?。
该脚本的失败部分基本上是:
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
如果我手动触发脚本,一切正常:
npm run postcheckout
PWD /tmp/foo/myproj/frontend
82dc6d2089a397f0889addb562ea84ba8d846215
无论根文件夹还是子文件夹,此方法均有效,我看不出有什么区别。赫斯基应该找到.git
文件夹,这似乎可以证明这一点,但是当它作为一个钩子脚本运行时,显然会有所改变。自动生成的Husky脚本的相关部分是:
cd "frontend"
...
...
npm run postcheckout
答案 0 :(得分:1)
TL; DR:未设置$GIT_DIR
(在sh脚本中,unset GIT_DIR
)。
the githooks documentation中有一个提示:
在Git调用一个钩子之前,它将其工作目录更改为裸存储库中的$ GIT_DIR或非裸存储库中工作树的根。推送期间触发的挂钩是一个例外(预接收,更新,后接收,后更新 ,按一下付款),它们始终在$ GIT_DIR中执行。
加上the top level Git manual page中的其他几个:
-git-dir = <路径>
设置存储库的路径。也可以通过设置GIT_DIR
环境变量来控制。它可以是当前工作目录的绝对路径或相对路径。
GIT_DIR
如果设置了GIT_DIR
环境变量,那么它将为存储库的基础指定要使用的路径,而不是默认的.git
。--git-dir
命令行选项也设置了该值。
这里发生的是顶级Git 程序将$GIT_DIR
设置为要找到.git
目录的路径。由于挂钩已将其工作目录更改为工作树,因此Git程序已将$GIT_DIR
设置为.git
。如果您在其他地方chdir
,则必须适当地调整$GIT_DIR
-如果您chdir完全远离主存储库,并且希望再次Git discover $GIT_DIR
,则您必须取消设置 $GIT_DIR
。