我需要一些帮助,编写一个Bash脚本,可以自动将git分支名称作为哈希值添加到提交消息中。
我需要一些帮助,编写一个Bash脚本,可以自动将git分支名称作为哈希值添加到提交消息中。
这是我作为示例的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
,使用 git branch --edit-description [branch_name]
命令将问题描述放置到 branch_description
中。
有关分支描述的更多信息,请参见此问答。
代码示例存储在以下Gist中。
echo $NAME: "$(cat $1)" > $1
。这个方法有效的原因是因为换行符被丢失的原因是 echo 将 $(cat "$1")
的每一行作为新的参数,并在它们之间加上空格进行回显。通过用双引号括起来 $(cat "$1")
,echo 将 cat 输出视为单个参数。此外,我认为没有必要引用 $1
,因为它的值是 .git/COMMIT_EDITMSG
。 - PiersyP使用 prepare-commit-msg
或 commit-msg
githook。
在您的 PROJECT/.git/hooks/
目录中已经有一些示例。
作为安全措施,您需要手动在每个要使用该钩子的存储库上启用此钩子。不过,您可以提交脚本并将其复制到所有克隆存储库的 .git/hooks/
目录中。
.git/hooks/prepare-commit-msg.sample
中。=)在遵循注释中的说明后,你只需要复制粘贴来自https://dev59.com/5HI-5IYBdhLWcg3w9thw的任何解决方案即可。 - ninjagecko.git/hooks/prepare-commit-msg.sample
包含三个例子。其中一个是将冲突部分注释掉,将git diff --name-status -r
的输出添加到其中,以及添加Signed-off-by行...没有将分支名称添加到提交消息中。所以我被迫编写自己的钩子。 - shytikov#!/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 -i '.bak' "1s/^/$branchName : \n/" $1
- canintexsed
命令出现错误,你可以使用符号@
作为分隔符代替正斜杠/
。因为正斜杠在分支名称或提交信息中可能会出现,导致sed
命令无法正常工作。 - Ory Band您可以通过准备提交消息和预提交钩子的组合来完成。
.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
等选项,则此操作可能会删除原始提交消息。您应该使用sed
而不是echo
。以下是一行命令:sed -i "1s@^@$(git branch | grep '^\*' | cut -b3-) @" $1
。 - Ory Band在 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
除了合并提交,它将在提交消息中添加分支名称。合并提交默认情况下具有分支信息,因此额外的分支名称是不必要的,并且会使消息变得不美观。
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
PROJECT-2313:添加了很棒的功能
,这需要您的分支名称以jira工单开头。 这是这些解决方案的组合:
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
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
。@
替代 /
作为 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
sed -i "" "1s@^@\n\n$branchName@" $1
。 - PJCHENder#!/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 commit
和git commit -m …
命令时将分支名称添加进去,而在合并(merge)、变基(rebase)等操作时不进行任何处理。
git branch | grep ...
获取当前分支的方法都是错误的。考虑使用git symbolic-ref -q HEAD
(如此答案所示)或git rev-parse --abbrev-ref HEAD
。如果你处于分离头状态并希望检测到该情况,请使用 symbolic-ref 命令。否则,rev-parse --abbrev-ref 方法可能是最好的选择。 - torek