我需要有关Bash脚本的一些帮助,该脚本会自动将git的分支名称添加为提交消息中的哈希。
我需要有关Bash脚本的一些帮助,该脚本会自动将git的分支名称添加为提交消息中的哈希。
Answers:
使用prepare-commit-msg
或commit-msg
githook。
PROJECT/.git/hooks/
目录中已经有示例。
作为安全措施,您将必须在要使用它的每个存储库上手动启用此类挂钩。但是,您可以提交脚本并将其在所有克隆上复制到.git/hooks/
目录中。
.git/hooks/prepare-commit-msg.sample
。=)您需要进行的所有修改(按照注释中的说明进行操作)都是从stackoverflow.com/questions/1593051/复制粘贴任何解决方案
.git/hooks/prepare-commit-msg.sample
包含三个示例。一个用于注释冲突部分,向其中添加git diff --name-status -r
输出并添加签名行...无需在提交消息中添加分支名称。所以我被迫写自己的钩子。
you will have to manually enable such a hook on each repository you wish to use it
意味着您必须授予FILE执行权限?如果是这样,我可以编辑答案以包括该答案吗(或者,可以吗?)?
这是我的commit-msg
脚本示例:
#!/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]
我使用的问题编号为branch_name
,问题说明放置在branch_description
using git branch --edit-description [branch_name]
命令中。
您可以在此问答中找到有关分支描述的更多信息。
该代码示例存储在下面的Gist中。
echo $NAME: "$(cat $1)" > $1
。之所以可行,是因为丢失了换行符,原因是echo将的每行都$(cat "$1")
当作一个新的参数,并在每行之间加一个空格。通过$(cat "$1")
用双引号引起来,echo将cat输出视为单个参数。我也不认为有必要报价,$1
因为它的价值是.git/COMMIT_EDITMSG
稍微简单一些的脚本,它将分支名称添加到提交消息之前您编辑。因此,如果您想更改或删除它,可以。
创建此文件.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
sed: 1: ".git/COMMIT_EDITMSG": invalid command code .
使用时。
sed -i '.bak' "1s/^/$branchName : \n/" $1
@
用作sed
分隔符,/
因为分支名称或提交消息中更可能出现正斜杠,从而造成乱码sed
。
您可以结合使用prepare-commit-msg和pre-commit挂钩来做到这一点。
.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
设定权限
sudo chmod 755 .git/hooks/prepare-commit-msg
sudo chmod 755 .git/hooks/pre-commit
--amend
是例如,这可以删除原始的提交消息。除了使用之外,echo
还应该使用sed
。它在一个衬里中:sed -i "1s@^@$(git branch | grep '^\*' | cut -b3-) @" $1
将以下代码添加到prepare-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
它将为合并消息添加分支名称,但merge-commit除外。默认情况下,merge-commit具有分支信息,因此不需要多余的分支名称,并且使消息难看。
蒂姆(Tim)的答案基于最重要的答案,结果证明了prepare-commit-msg钩子将发生哪种提交作为参数。。从默认的prepare-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
如果要使其全局(对于所有项目):
创建git-msg
包含shytikov的答案内容的文件,并将其放在某个文件夹中:
mkdir -p ~/.git_hooks
# make it executable
chmod a+x ~/.git_hooks/commit-msg
现在启用挂钩:
git config --global init.templatedir '~/.git_hooks'
并git init
在每个要使用它的项目中。
由于它们使用BSD sed
而不是GNU 的事实,使这些解决方案在MacOS上运行时遇到了问题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
在主目录中有一个名为的文件。
如果要将JIRA票证添加到提交消息中,请使用以下脚本。
提交类似的消息 PROJECT-2313: Add awesome feature
这样的这要求您的分支机构名称以jira Ticket开头。
这是以下解决方案的组合:
使用OS对其进行了修改,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