如何将 Git 的分支名添加到提交消息中?

我需要一些关于 Bash 脚本的帮助,该脚本将自动在提交消息中将 git 的分支名称作为散列添加。

74280 次浏览

使用 prepare-commit-msgcommit-msg githook

PROJECT/.git/hooks/目录中已经有一些示例。

作为一种安全措施,您必须在希望使用它的每个存储库上手动启用这样的钩子。不过,您可以提交该脚本并将其复制到所有克隆的 .git/hooks/目录中。

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

创建以下提交消息:

[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.

你可以在这个 问与答上找到更多关于分支的描述。

代码示例存储在以下 要点中。

一个比较简单的脚本,它将分支名称添加到您编辑的提交消息 之前中。因此,如果你想改变或删除它,你可以。

Create this file . git/hook/ready-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

将下面的代码添加到 ready-commit-msg 文件中。

#!/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.

您可以结合使用 ready-commit-msg 和 pre-commit 钩子来完成这项工作。

. git/hook/ready-commit-msg

#!/bin/sh


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

. git/hook/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

设置权限

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

受到 Tim 建立在顶级答案基础上的答案的启发,结果显示 ready-commit-msg 钩子采用的是 争论正在发生什么样的提交。如默认的 ready-commit-msg 所示,如果 $2是“ merge”,那么它就是合并提交。因此,可以修改大小写开关以包含 Tim 的 addBranchName ()函数。

对于如何添加分支名称以及默认 prepare-commit-msg.sample钩子的所有未注释部分,我已经包含了自己的首选项。

准备-投入-味精

#!/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

由于 MacOS 使用的是 BSD sed而不是 GNU sed,所以我在使用这些解决方案时遇到了一些问题。我设法创建了一个简单的脚本来完成这项工作。仍在使用 .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

这假设一个类似于 functional-desc_JIRA-NUMBER的分支命名标准。如果您的分支名称只是您的 Jira 票号,那么您可以简单地删除从管道到 f2的所有内容。它还要求在主目录中有一个名为 .gitmessage的文件。

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

创建包含 希提科夫的回答内容的 git-msg文件,并将其放在某个文件夹中:

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

现在启用钩子:

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

git init再次在每个项目你想使用它。

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

提交消息类似于 PROJECT-2313: Add awesome feature 这需要您的分行名称以 jira Ticket 开头。

这是这些解决方案的组合:

它针对 OS X 进行了修改,使用了 sed -i '.bak',并且在 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

我编辑了这个答案(https://stackoverflow.com/a/17270862/9266796) ,所以它也适用于名称中包含斜杠的分支,使用 @而不是 /作为 sed分隔符。现在使用 git branch --show-current获取分支名称也更简单了。我还将分支名称移动到提交消息的底部,因为消息的实际标题是您首先看到的内容更有意义。

该文件仍应称为 .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

我根据自己的需要改编了这个:

#!/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

复制这个剪切在一个名为 prepare-commit-msg的文件内的回购 .git/hooks文件夹。

这应该在 git commitgit commit -m …的情况下添加分支名称,而在 merge、 rebase 等情况下什么也不做。