Reputation:
I would like to use the prepare-commit-msg hook. I am using feature and bugfix branches (feature/ISSUEKEY-23123-some-feature) and I would like to prepend the ISSUEKEY-23123 into the commit message:
#!/bin/bash
BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')
STR=`echo $BRANCH_NAME | grep -E 'ISSUEKEY-[0-9]*' -o`
if [[ $BRANCH_NAME == *"feature"* ]] || [[ $BRANCH_NAME == *"bugfix"* ]]
then
echo $STR > $1
fi
This works, but it discards the standard message vi is showing me for commits, e.g.:
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Explicit paths specified without -i or -o; assuming --only paths...
# On branch feature/ISSUEKEY-1716-model-implement
# Your branch is based on 'origin/feature/ISSUEKEY-1716-model-implement', but the upstream is gone.
# (use "git branch --unset-upstream" to fixup)
#
# Changes to be committed:
# new file: asd
#
# Untracked files:
# FSTD-1716
# TMP
#
Is there a way to either prepend the STR
to the output, or to call a git command what prints me the mentioned standard commit message?
The opened commit message should be:
ISSUEKEY-1716
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Explicit paths specified without -i or -o; assuming --only paths...
# On branch feature/ISSUEKEY-1716-model-implement
# Your branch is based on 'origin/feature/ISSUEKEY-1716-model-implement', but the upstream is gone.
# (use "git branch --unset-upstream" to fixup)
#
# Changes to be committed:
# new file: asd
#
# Untracked files:
# FSTD-1716
# TMP
#
Upvotes: 1
Views: 218
Reputation: 488183
Quoting from the githooks documentation:
This hook is invoked by git commit right after preparing the default log message, and before the editor is started. ... The purpose of the hook is to edit the message file in place, and ...
(boldface mine). This means you must do just what it says: edit the file in place. Don't just overwrite it! Hence, instead of:
echo $STR > $1
you might do:
ed - "$1" << end
0a
$STR
.
w
q
end
which runs the ed
editor on a "here document" script consisting of instructions to add the expansion of $STR
after line 0, then write that and exit the editor. (You can use any editor; sed
is popular here as well.)
As an aside, don't do this:
BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')
since it's overly dependent on various "porcelain" command output styles. Instead, use git symbolic-ref
(usually the preferred method for scripts) or git rev-parse
. The difference between these two is a bit philosophical:
git symbolic-ref <options> HEAD
gets you the name of the branch you are currently on, or fails if you are on the special anonymous "detached HEAD" case. (The <options>
you would want here is just --short
to omit the refs/heads/
prefix.)
git rev-parse <options> HEAD
is mostly guaranteed to produce a successful name of some sort, since HEAD
is always a valid name1 and therefore will correspond to something. It's meant to turn HEAD
into a revision hash ID, but with the --symbolic
option it will leave a name "as symbolic as possible" and with --abbrev-ref
it will also leave out refs/heads/
when it does so.
The key difference is that the rev-parse
method does not fail when HEAD is "detached", while the symbolic-ref
method does. The failure lets you distinguish this case, which is sometimes important. For your purposes it's not so important and when using symbolic-ref
you need a fallback for the "no name for current branch" detached HEAD case.
Hence, you want either:
BRANCH_NAME=$(git rev-parse --symbolic --abbrev-ref HEAD)
or:
BRANCH_NAME=$(git symbolic-ref --short HEAD || echo HEAD)
(curiously, these are exactly the same number of bytes of command).
1There's one corner case here. While HEAD
is always valid—if it's not valid, you don't have a Git repository (Git will give you a "fatal:" message to that effect)—if you are on an "unborn branch", HEAD
is a symbolic reference to a branch name that does not exist. In this particular case, git symbolic-ref
will succeed and git rev-parse HEAD
will fail, which is backwards from the more usual case of a detached HEAD.
Upvotes: 1
Reputation:
I fixed it:
#!/bin/bash
BRANCH_NAME=$(git branch | grep '*' | sed 's/* //')
COMMIT_MSG=`echo $BRANCH_NAME | grep -E 'ISSUEKEY-[0-9]*' -o`
if [[ $BRANCH_NAME == *"feature/"* ]] || [[ $BRANCH_NAME == *"bugfix/"* ]]
then
PRE_COMMIT_MSG=$(cat $1)
if [ -z "$COMMIT_MSG" ] ; then
exit 0
else
COMMIT_MSG="$COMMIT_MSG - $PRE_COMMIT_MSG"
echo "$COMMIT_MSG" > $1
fi
fi
Upvotes: 0