我有一个设置服务器的脚本。在脚本中,我生成了一个git钩子,当推送到裸仓库(我使用推送部署工作流)时,该钩子就会运行。
在挂钩中,我想检查自新修订版以来旧修订版中的特定文件是否已更改。如果是这样,请运行特定命令。
是否可以这样做?我创建的脚本如下:
cat >$home/api.git/hooks/post-receive <<'ILOVEBASH'
#!/bin/bash
while read oldrev newrev ref
do
if [[ $ref =~ .*/master$ ]];
then
echo "Master ref received: Deploying ..."
git --work-tree=$webroot --git-dir=$home/api.git/ checkout -f
# If the /composer.json file in the oldrev differs from newrev
# Do something ...
else
echo "Only the master branch may be deployed on this server."
fi
done
ILOVEBASH
答案 0 :(得分:2)
这是可能的,甚至很容易。
但是,首先,这是测试ref的错误方法:
if [[ $ref =~ .*/master$ ]];
因为这意味着,如果我向您发送refs/heads/not/master
,您会认为我已经向您发送了分支master
,而我实际上已经向您发送了分支not/master
。如果您确实要测试master
,请测试refs/heads/master
,而不是.*/master
:
if [ "$ref" = refs/heads/master ];
这也可能是错误的:
else [...complain...]; fi
例如,每次您按下标签时,这都会抱怨。 (因为它只握住而不是停止推动,所以它是无害的。)
现在,要比较两个文件,只需对它们运行git diff
。或者,运行git diff-tree
(仅限于这两个文件),并使用诸如补丁程序的-p
之类的其他选项:
git diff-tree -p $oldrev $newrev -- composer.json
使用git diff-tree
的原因是其行为是可预测的,因此可在任何地方进行测试。 git diff
前端遵循配置条目,这些条目可以根据用户设置从一个存储库更改为另一个存储库。
git diff-tree
的输出告诉您更改了什么。当您不使用-p
时,如果您只想知道是否有所更改,输出将特别方便。我在外壳中而不是从钩子中运行它们,因此我使用了HEAD^
和HEAD
而不是$oldrev
和$newrev
,但是输出应该是不言自明的:
$ git diff-tree HEAD^ HEAD -- Documentation/RelNotes/2.20.1.txt
:040000 040000 12fe36dc6cb8966bfa24b832fe2d3d78cce152b5 04a4194134826e9a84a513a79a1b9f8f428f7f5d M Documentation
如果文件不在顶层(在我的示例中,但不在您的示例中),则可能需要-r
:
$ git diff-tree -r HEAD^ HEAD -- Documentation/RelNotes/2.20.1.txt
:000000 100644 0000000000000000000000000000000000000000 dcba888dba4d12d745a796de39b45b4c9a0497b5 A Documentation/RelNotes/2.20.1.txt
当然,您可以消除文件名以查找更改:
$ git diff-tree -r HEAD^ HEAD
:000000 100644 0000000000000000000000000000000000000000 dcba888dba4d12d745a796de39b45b4c9a0497b5 A Documentation/RelNotes/2.20.1.txt
:100755 100755 216beefc50d54d132991636d5f049ea0916f1696 d1a2814ec7e415a525e58ac234df8184a2d0f93c M GIT-VERSION-GEN
:120000 120000 8d0b1654d25536f72abe885634c36412ae8b3246 463a237c65db66593e317d55103a6212a095b8aa M RelNotes
尽管仅测试一个文件,但这种情况太过夸张了。