从commit-msg挂钩中有条件地跳过预提交挂钩

时间:2020-08-22 05:48:40

标签: git githooks pre-commit-hook

我有一个预提交钩子,可确保在任何提交之前始终使用devel重新创建主题分支。但是,有时在工作的中间,我想完成未完成的工作,而不是将其存放以防万一,然后在恢复之前重置。对于这样的工作保存提交,提交消息必须完全相同,例如“ workave commit”。我希望commit-msg钩子检查这种情况,如果是节省工作的提交,则跳过precommit钩子。 precommit hook一直都在侦听环境变量'override_hooks',因此我试图在commit-msg内更改它,但是没有用。我知道我可以手动设置override_hooks,但我希望我不必每次都这样做。我将不胜感激。

2 个答案:

答案 0 :(得分:1)

prepare-commit-msg钩子在pre-commit钩子之后运行 ,因此将不起作用。

最好设置一个别名:

# call 'git commits with
# -n to skip all pre-commit hooks
# -m msg to provide the commit message from the command line
git config alias.worksave 'commit -n -m "works save commit"'

# you can now type :
git worksave

答案 1 :(得分:0)

您可以改用由 commit-msg 调用的 pre-commit 钩子。我的钩子使用了太多内部结构,无法包含在此处,但其想法是读取 $1(提交消息文件)并相应地执行检查以确定退出代码和/或消息。

我当前实现此功能的 commit-msg 有许多独立的依赖项,并且是用 R 编写的,但我会将其粘贴到此处,以防万一。

#!/usr/local/bin/Rscript

## check if commit msg has 'resetme' or 'worksave' (a save-work commit)
## if not, check and ensure 'devel' branch is not ahead

.stop <- function(msg) {
    stop('\n\n', msg, '\n\n', call. = FALSE)
}

## source utilities from GitHub
## ------------------------------------------------------------------------ ##
source('https://raw.githubusercontent.com/ajabadi/Altools/master/R/get_package_version.R')
## ------------------------------------------------------------------------ ##
source('https://raw.githubusercontent.com/ajabadi/Altools/master/R/bump_up_version.R')

## get commit message
commit_message <- commandArgs(trailingOnly = TRUE)
commit_message <- paste0(readLines(commit_message), collapse = ' ')

## ascertain if it was a worksave commit
its_a_save_work_commit <- grepl('^resetme', tolower(commit_message)) | grepl('^worksave', tolower(commit_message))


## exit with 1 if devel is ahead of topic and it's not a worksave commit
## exit with 0 otherwise
currBranch <- current_branch()
if (isFALSE(its_a_save_work_commit)) {
    ## remind to rebase devel for topic branches if necessary
    if (!any(currBranch %in% c('master', 'devel'))) {
        devel_is_ahead <- length(system(sprintf('git log %s..devel', currBranch), intern = TRUE)) > 0
        if (devel_is_ahead) {
            .stop('devel is ahead by some changes, rebase or start the commit message with either "worksave" or "resetme"\n')
        }
}
TRUE
}