我想为git repo设置一个pre-push
钩子:
1)检查我们是否正在推动掌握,
2)如果我们是,运行webpack,将已编译的.js
文件复制到另一个repo,并将该编译文件提交到实用程序repo。
背景:我正在使用webpack +做出反应,使用leaflet.js构建地图。我想让实用程序repo始终保存最新编译的.js
文件,以便我可以使用rawgit在不同的静态站点中获取它。
这是我到目前为止(工作不正常):
#!/bin/bash
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [[ $current_branch == 'master' ]]; then
webpack
cp bundle.js ../utility
eval 'cd ../utility && git add bundle.js && git commit -m "updated east_boston.js"'
fi
我知道有一些自动设置的环境变量(如$GIT_DIR
和$GIT_INDEX
),但我不知道如何使这项工作。我不断变得奇怪的行为,主要仓库的自述文件意外地被提交到实用程序仓库,或者我将获得删除主仓库中的文件的实用程序仓库的提交(这些文件在实用程序中不存在)回购)。
基本上我不知道如何正确使用git hook。我是否正在使用合适的钩子来满足我的需求?这可能吗?
我应该注意上面的shell脚本可以自己正常工作 - 所以如果我bash pre-push
我得到了我想要的行为。
答案 0 :(得分:1)
这里有很多问题需要解决。第一个是绊倒你的那个:git hooks可以从奇数目录运行(所以../something
可能不是你期望的那样)和有$GIT_DIR
设置为某些内容(通常为.
或.git
,具体取决于他们所在的目录)。移动到另一个目录并运行git命令不起作用,因为你在错误的地方结束或$GIT_DIR
指向错误的地方,或两者兼而有之。
我相信预推钩是从您正在考虑的目录中运行的(在大多数情况下:如果您从git --work-tree=<path>
完全在<path>
以外的地方使用$GIT_DIR
1}}),所以它只是造成直接问题的git rev-parse
设置。
不太明显但仍然非常重要的是,您使用$ git push origin zog~3:master
找到的当前分支不一定是被推送到的分支,并且提交被推送-from不一定是任何分支的一角。例如:
master
告诉git要求远程设置他们的zog~3
到任何提交ID rye
的结果,即使您当前在分支<local ref> SP <local sha1> SP <remote ref> SP <remote sha1> LF
上。您可能不关心处理这种情况,但 可以处理:预推钩在其标准输入上接收以下形式的一系列行:
while read lref lsha rref rsha; do
...
done
(这是直接来自文档)。要在sh或bash中处理这个问题:
...
其中$lref
部分使用$lsha
和master
来计算本地引用名称(如果有)和SHA-1,以及远程引用名称和SHA-1(远程名称将是完全限定的,因此推送到refs/heads/master
会在$rref
中为您提供git --work-tree=$tmpdir checkout $lsha
。
最棘手的一点是,如果你想使用提交的东西,遥控器将其标签设置为(假设推送最终成功 - 这不是你可以在钩子中告诉的东西!),你不能依赖当前工作树的文件:
要完成检查或使用它们的全面工作,您需要将所有这些文件提取到临时工作区(这实际上非常简单,仅$lsha
$tmpdir
是您从输入中读取的SHA-1,$GIT_INDEX_FILE
是一个合适的临时工作树,一旦您完成它就会删除;但是您可能还需要覆盖sh
同样)。
忽略大部分内容,以下非常俗气(和未经测试)的脚本(用#! /bin/sh
. git-sh-setup # for require_clean_work_tree() and die()
check_push_to_master()
{
# we're pushing to remote "master"; reject if
# the work tree is not clean or is not at the
# commit-ID ($1) being pushed
local headsha pushsha
require_clean_work_tree 'push to master'
headsha=$(git rev-parse HEAD)
pushsha=$1
[ $headsha = $pushsha ] ||
die "HEAD commit $headsha does not match push to master $pushsha"
}
to_master=false
while read lref lsha rref rsha; do
case $rref in
refs/heads/master) check_push_to_master $lsha; to_master=true;;
esac
done
# if we get here it's OK to try the push, but first...
if $to_master; then
unset GIT_DIR # make git work normally again
# set -e # might want this to make sure any failures => stop push
webpack
cp bundle.js ../utility
cd ../utility && git add bundle.js && git commit -m "updated east_boston.js"
fi
exit 0 # allow push to proceed
编写,但应该可以正常使用bash)可能会在那里大部分时间:
localhost:3000/api/v1/posts