How to add Git's branch name to the commit message?

GitBashGit Branch

Git Problem Overview


I need some help with a Bash script that will automatically add the git's branch name as a hash in commit messages.

Git Solutions


Solution 1 - Git

Here is my commit-msg script as an example:

#!/bin/sh
#
# Automatically adds branch name and branch description to every commit message.
#
NAME=$(git branch | grep '*' | sed 's/* //') 
DESCRIPTION=$(git config branch."$NAME".description)

echo "$NAME"': '$(cat "$1") > "$1"
if [ -n "$DESCRIPTION" ] 
then
   echo "" >> "$1"
   echo $DESCRIPTION >> "$1"
fi 

Creates following commit message:

[branch_name]: [original_message]

[branch_description]

I'm using issue number as branch_name, issue description is placed to the branch_description using git branch --edit-description [branch_name] command.

More about branch descriptions you can find on this Q&A.

The code example is stored in following Gist.

Solution 2 - Git

Use the prepare-commit-msg or commit-msg githook.

There are examples already in your PROJECT/.git/hooks/ directory.

As a security measure, you will have to manually enable such a hook on each repository you wish to use it. Though, you can commit the script and copy it on all clones into the .git/hooks/ directory.

Solution 3 - Git

A bit simpler script that adds the branch name to the commit message before you edit it. So if you want want to change or remove it you can.

Create this file .git/hooks/prepare-commit-msg:

#!/bin/bash

branchPath=$(git symbolic-ref -q HEAD) #Somthing like refs/heads/myBranchName
branchName=${branchPath##*/}      #Get text behind the last / of the branch path

firstLine=$(head -n1 $1)

if [ -z "$firstLine"  ] ;then #Check that this is not an amend by checking that the first line is empty
    sed -i "1s/^/$branchName: \n/" $1 #Insert branch name at the start of the commit message file
fi

Solution 4 - Git

You can do it with a combination of the prepare-commit-msg and pre-commit hooks.

.git/hooks/prepare-commit-msg

#!/bin/sh

BRANCH=`git branch | grep '^\*' | cut -b3-`
FILE=`cat "$1"`
echo "$BRANCH $FILE" > "$1"

.git/hooks/pre-commit

#!/bin/bash

find vendor -name ".git*" -type d | while read i
do
        if [ -d "$i" ]; then
                DIR=`dirname $i`
                rm -fR $i
                git rm -r --cached $DIR > /dev/null 2>&1
                git add $DIR > /dev/null 2>&1
        fi
done

Set permissions

sudo chmod 755 .git/hooks/prepare-commit-msg
sudo chmod 755 .git/hooks/pre-commit

Solution 5 - Git

add the below code in prepare-commit-msg file.

#!/bin/sh
#
# Automatically add branch name and branch description to every commit message except merge commit.
#

COMMIT_EDITMSG=$1

addBranchName() {
  NAME=$(git branch | grep '*' | sed 's/* //') 
  DESCRIPTION=$(git config branch."$NAME".description)
  echo "[$NAME]: $(cat $COMMIT_EDITMSG)" > $COMMIT_EDITMSG
  if [ -n "$DESCRIPTION" ] 
  then
     echo "" >> $COMMIT_EDITMSG
     echo $DESCRIPTION >> $COMMIT_EDITMSG
  fi 
}

MERGE=$(cat $COMMIT_EDITMSG|grep -i 'merge'|wc -l)

if [ $MERGE -eq 0 ] ; then
  addBranchName
fi

It will add branch name to commit message except merge-commit. The merge-commit has branch information by default so extra branch name is unnecessary and make the message ugly.

Solution 6 - Git

Inspired by Tim's answer which builds upon the top answer, it turns out the prepare-commit-msg hook takes as an argument what kind of commit is occurring. As seen in the default prepare-commit-msg if $2 is 'merge' then it is a merge commit. Thus the case switch can be altered to include Tim's addBranchName() function.

I've included my own preference for how to add the branch name, and all the uncommented parts of the default prepare-commit-msg.sample hook.

>prepare-commit-msg

#!/bin/sh

addMyBranchName() {
  # Get name of current branch
  NAME=$(git branch | grep '*' | sed 's/* //')

  # First blank line is title, second is break for body, third is start of body
  BODY=`cut -d \| -f 6 $1 | grep -v -E .\+ -n | cut -d ':' -f1 | sed '3q;d'`

  # Put in string "(branch_name/): " at start of commit message body.
  # For templates with commit bodies
  if test ! -z $BODY; then
    awk 'NR=='$BODY'{$0="\('$NAME'/\): "}1;' $1 > tmp_msg && mv tmp_msg "$1"
  else
    echo "title\n\n($NAME/):\n`cat $1`\n" > "$1"
  fi
}

# You might need to consider squashes
case "$2,$3" in
  # Commits that already have a message
  commit,?*)
  ;;

  # Messages are one line messages you decide how to handle
  message,)
  ;;

  # Merge commits
  merge,)
    # Comments out the "Conflicts:" part of a merge commit.
    perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1"
  ;;

  # Non-merges with no prior messages
  *)
    addMyBranchName $1
  ;;
esac

Solution 7 - Git

If you want to make it global (for all projects):

Create git-msg file with the content of shytikov's answer, and put it in some folder:

mkdir -p ~/.git_hooks
# make it executable
chmod a+x ~/.git_hooks/commit-msg

Now enable hooks:

git config --global init.templatedir '~/.git_hooks'

and git init again in each project you want to use it.

Solution 8 - Git

In case you want the JIRA ticket added to the commit message use the script bellow.

Commit message something like PROJECT-2313: Add awesome feature This requires your branch name to start with the jira Ticket.

This is a combination of this solutions:

It is modified for OS X, with the sed -i '.bak' and it works as well from SourceTree.

https://gist.github.com/georgescumihai/c368e199a9455807b9fbd66f44160095

#!/bin/sh
#
# A hook script to prepare the commit log message.
# If the branch name it's a jira Ticket.
# It adds the branch name to the commit message, if it is not already part of it.

branchPath=$(git symbolic-ref -q HEAD) #Somthing like refs/heads/myBranchName
branchName=${branchPath##*/}      #Get text behind the last / of the branch path

regex="(PROJECTNAME-[0-9]*)"

if [[ $branchName =~ $regex ]]
then
    # Get the captured portion of the branch name.
    jiraTicketName="${BASH_REMATCH[1]}"

    originalMessage=`cat $1`

    # If the message already begins with PROJECTNAME-#, do not edit the commit message.
    if [[ $originalMessage == $jiraTicketName* ]]
        then
        exit
    fi

    sed -i '.bak' "1s/^/$jiraTicketName: /" $1 #Insert branch name at the start of the commit message file
fi

Solution 9 - Git

I edited this answer (https://stackoverflow.com/a/17270862/9266796) so it also works for branches that contain slashes in their name, using @ instead of / as a sed separator. Getting the branch name is also simpler now with git branch --show-current. I also moved the branch name to the bottom of the commit message since it makes more sense that the actual title of the message is what you see first.

The file should still be called .git/hooks/prepare-commit-msg.

#!/bin/bash

branchName=$(git branch --show-current)
firstLine=$(head -n1 $1)

if [ -z "$firstLine"  ] ;then #Check that this is not an amend by checking that the first line is empty
    sed -i "1s@^@\n\n$branchName@" $1 #Insert branch name at the end of the commit message file
fi

Solution 10 - Git

I was having issues getting these solutions to work on MacOS due to the fact that it uses BSD sed instead of GNU sed. I managed to create a simple script that does the job though. Still using .git/hooks/pre-commit:

#!/bin/sh
BRANCH=$(cat .git/HEAD  | cut -d '_' -f2)
if [ ! -z "$BRANCH" ]
then
    echo "$BRANCH" > "/Users/username/.gitmessage" 
else
    echo "[JIRA NUMBER]" > "/Users/username/.gitmessage"
fi 

This assumes a branch naming standard similar to functional-desc_JIRA-NUMBER. If your branch name is only your Jira ticket number you can simply get rid of everything from the pipe to the f2. It also requires that you have a file named .gitmessage in your home directory.

Solution 11 - Git

I adapted this for my needs:

#!/bin/bash

# hook arguments
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3

BRANCH_NAME=$(git branch --show-current)

# check branch name isn’t empty (typical e.g. during rebase)
if [ -n "$BRANCH_NAME" ]
then
  # check that this is a regular commit
  if [ "$COMMIT_SOURCE" = "message" ] || [ -z "$COMMIT_SOURCE" ]
  then
      sed -r -i "1!b;/^(fixup|squash)/! s@^@$BRANCH_NAME @" $COMMIT_MSG_FILE # insert branch name at the start of the commit message file
  fi
fi

This should add the branch name in the case of git commit, git commit -m … and do nothing in case of merge, rebase etc.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTomer LichtashView Question on Stackoverflow
Solution 1 - GitshytikovView Answer on Stackoverflow
Solution 2 - GitninjageckoView Answer on Stackoverflow
Solution 3 - GitPylinuxView Answer on Stackoverflow
Solution 4 - GitFarid MovsumovView Answer on Stackoverflow
Solution 5 - GitTimView Answer on Stackoverflow
Solution 6 - GitNovice CView Answer on Stackoverflow
Solution 7 - GitMarounView Answer on Stackoverflow
Solution 8 - GitMihai GeorgescuView Answer on Stackoverflow
Solution 9 - GitJohan MaesView Answer on Stackoverflow
Solution 10 - GitPhPGuyView Answer on Stackoverflow
Solution 11 - GitPeterView Answer on Stackoverflow