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

Tom*_*ash 93 git bash git-branch

我需要一些Bash脚本的帮助,它会自动将git的分支名称添加为提交消息中的哈希.

shy*_*kov 176

这是我的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 
Run Code Online (Sandbox Code Playgroud)

创建以下提交消息:

[branch_name]: [original_message]

[branch_description]
Run Code Online (Sandbox Code Playgroud)

我正在使用问题编号branch_name,问题说明放在branch_descriptionusing git branch --edit-description [branch_name]命令中.

有关此问答的分支说明的更多信息.

代码示例存储在以下Gist中.

  • 此脚本将多行提交消息压缩为单行.我将echo语句替换为:echo -n"$ NAME"':'| cat - "$ 1">/tmp/out && mv/tmp/out"$ 1" (7认同)
  • 将此文件放入PROJECT/.git/hooks /文件夹 (4认同)
  • 它运作良好。但是对于Mac,我也必须设置权限才能使其正常工作:>>> sudo chmod 755 .git / hooks / commit-msg (2认同)
  • @AlexSpence可以更简单地使用`echo $ NAME:“ $(cat $ 1)”> $ 1`。之所以这样有效是因为丢失了换行符,原因是echo将$$(cat“ $ 1”)`的每一行都当作一个新的参数,并在每行之间加一个空格。通过将$(cat“ $ 1”)`用双引号引起来,echo将cat输出视为单个参数。我也不认为没有必要引用`$ 1`,因为它的值是`.git / COMMIT_EDITMSG`。 (2认同)

nin*_*cko 48

使用prepare-commit-msgcommit-msg githook.

您的PROJECT/.git/hooks/目录中已有示例.

作为安全措施,您必须在要使用它的每个存储库上手动启用此类挂钩.但是,您可以提交脚本并将其复制到所有克隆中的.git/hooks/目录中.

  • 我不需要,你已经有一个例子,它正是你想要的**,正如我已经说过的那样,在`.git/hooks/prepare-commit-msg.sample`中.=)您需要修改的所有内容(遵循评论中的说明)是从http://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-复制粘贴任何解决方案你想要的out-git-branch (5认同)
  • @ninjagecko,对我来说.git/hooks/prepare-commit-msg.sample`包含三个例子.一个用于注释冲突部分,向其添加`git diff --name-status -r`输出并添加Signed-off-by行......不向提交消息添加分支名称.所以我被迫写自己的钩子. (4认同)
  • 为什么是这个答案?这更像是让我为你谷歌搜索。应选择@shytikov 的回答 (2认同)

Pyl*_*nux 29

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

创建此文件.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
Run Code Online (Sandbox Code Playgroud)

  • 我得到:`sed:1:".git/COMMIT_EDITMSG":无效的命令代码.`当使用它时. (4认同)
  • 您可以使用“@”作为“sed”分隔符而不是“/”,因为正斜杠更有可能出现在分支名称或提交消息中,从而搞乱“sed”。 (3认同)
  • 比如检查修改和修正案例 (2认同)
  • OSX:如果您收到上述错误消息,则需要使用文件扩展名.`sed -i'.bak'"1s/^/$ branchName:\n /"$ 1` (2认同)

Far*_*mov 28

您可以使用prepare-commit-msg和pre-commit钩子的组合来完成它.

的.git /钩/准备提交-MSG

#!/bin/sh

BRANCH=`git branch | grep '^\*' | cut -b3-`
FILE=`cat "$1"`
echo "$BRANCH $FILE" > "$1"
Run Code Online (Sandbox Code Playgroud)

的.git /钩/预提交

#!/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
Run Code Online (Sandbox Code Playgroud)

设置权限

sudo chmod 755 .git/hooks/prepare-commit-msg
sudo chmod 755 .git/hooks/pre-commit
Run Code Online (Sandbox Code Playgroud)

  • 为简单起见 (4认同)

Tim*_*Tim 9

在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
Run Code Online (Sandbox Code Playgroud)

它将添加分支名称以提交除merge-commit之外的消息.合并提交默认具有分支信息,因此不需要额外的分支名称并使消息变得丑陋.

  • @thoroc 这在技术上是正确的;然而,在正常使用中这并不是什么大问题。在编辑它们之前,正在解析的提交消息是“默认消息”。因此,只要您的提交模板中没有“合并”一词,我相信您应该没问题(只要其他“默认”消息不包含默认合并提交消息)。我最初误解了这一点,现在相信我是正确的。 (3认同)
  • 那么当它在消息上找到单词 merge 时,这不会修改提交消息吗? (2认同)

Mih*_*scu 7

如果您希望将 JIRA 票证添加到提交消息中,请使用以下脚本。

提交类似这样的消息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
Run Code Online (Sandbox Code Playgroud)


Nov*_*e C 5

受蒂姆基于最高答案的答案的启发,事实证明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
Run Code Online (Sandbox Code Playgroud)


Mar*_*oun 5

如果你想使其成为全球性的(对于所有项目):

使用shytikov 的答案git-msg的内容创建文件,并将其放在某个文件夹中:

mkdir -p ~/.git_hooks
# make it executable
chmod a+x ~/.git_hooks/commit-msg
Run Code Online (Sandbox Code Playgroud)

现在启用钩子:

git config --global init.templatedir '~/.git_hooks'
Run Code Online (Sandbox Code Playgroud)

git init再次在您想要使用它的每个项目中。

  • 我发现要使用此功能,我必须将“commit-msg”放入为“init.templatedir”配置的目录内的“hooks”目录中,这样当整个 templatedir 被复制到“git init”时,“commit- msg' 最终位于项目的 '.git/hooks' 目录中。 (2认同)

Joh*_*aes 5

我编辑了这个答案(/sf/answers/1208960371/),因此它也适用于名称中包含斜杠的分支,@而不是/用作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
Run Code Online (Sandbox Code Playgroud)