Gitのブランチ名をコミットメッセージに追加するにはどうすればよいですか?


102

コミットメッセージでgitのブランチ名をハッシュとして自動的に追加するBashスクリプトのヘルプが必要です。


3
ここに来る誰にとっても、最良の答えはページの下部にあるようです
Ben Taliadoros

補足:git branch | grep ...現在のブランチを取得するためのはすべて、これを行うための間違った方法です。git symbolic-ref -q HEADこの回答に示されているように)またはを検討してくださいgit rev-parse --abbrev-ref HEAD。切り離されたHEADを使用している場合、symbolic-refコマンドは失敗するので、そのケースを検出したい場合は、それを使用してください。それ以外の場合は、rev-parse --abbrev-refメソッドがおそらく最適です。
トレック

回答:


53

prepare-commit-msgまたはcommit-msg githookを使用します。

すでにPROJECT/.git/hooks/ディレクトリに例があります。

セキュリティ対策として、使用する各リポジトリでこのようなフックを手動で有効にする必要があります。ただし、スクリプトをコミットして、すべてのクローンで.git/hooks/ディレクトリにコピーできます。


素晴らしいリードに感謝します。ありがとうございました。スクリプト自体でさらに私を助けることができれば、私は感謝します:)
Tomer Lichtash '

5
私がする必要はありません。すでに言ったように、あなたはすでにあなたが望んいることを正確に実行する例を持っています.git/hooks/prepare-commit-msg.sample。=)(コメントの指示に従って)変更する必要があるのは、stackoverflow.com
questions / 1593051 /

4
@ninjagecko、私にとって.git/hooks/prepare-commit-msg.sampleは3つの例が含まれています。1つは、競合セクションをコメント化し、git diff --name-status -rそれに出力を追加し、Signed-off-by行を追加するためのものです...コミットメッセージにブランチ名を追加しません。だから私は自分のフックを書くことを余儀なくされました。
shytikov

1
これyou will have to manually enable such a hook on each repository you wish to use itは、FILEに実行権限を与える必要があることを意味しますか?もしそうなら、私はそれを含めるように答えを編集することができますか?
Dan Rosenstark、2016

1
なぜこれが答えなのですか?それはあなたのためにそれをグーグルさせてくれるようなものです。@shytikovによる回答を選択する必要があります
TheRealFakeNews

177

ここに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_descriptionusing git branch --edit-description [branch_name]コマンドに配置されています。

このQ&Aで見つけることができるブランチの説明の詳細。

コード例は、次のGistに格納されています。


8
このスクリプトは、複数行のコミットメッセージを1行に圧縮します。echoステートメントを次のように置き換えました:echo -n "$ NAME" ':' | cat-"$ 1"> / tmp / out && mv / tmp / out "$ 1"
Alex Spence

4
このファイルをフォルダーPROJECT / .git / hooks /に配置します
catanore

2
それはうまくいきます。しかしMacの場合は、権限を設定して機能させる必要もありました。>>> sudo chmod 755 .git / hooks / commit-msg
Manoj Shrestha

1
@ManojShresthaはい、実行可能である必要があります
David Mann

2
@AlexSpenceより簡単に使用できますecho $NAME: "$(cat $1)" > $1。これが機能するのは、改行が失われた理由は、エコーがの各行を$(cat "$1")新しい引数として扱い、それぞれの間にスペースを入れてエコーするためです。$(cat "$1")二重引用符で囲むことにより、echoはcat出力を単一の引数として扱います。また$1、その値は.git/COMMIT_EDITMSG
次のとおりな

30

編集する前に、ブランチメッセージをコミットメッセージ追加する少し単純なスクリプト。したがって、変更または削除したい場合は、できます。

このファイル.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

4
私が得る:sed: 1: ".git/COMMIT_EDITMSG": invalid command code .これを使用するとき。
アダムパーキン2013


2
修正と修正のケースのチェックのように
pogopaule 2015年

3
OSX:上記のエラーメッセージが表示される場合は、機能するファイル拡張子が必要です。sed -i '.bak' "1s/^/$branchName : \n/" $1
canintex 2015

スラッシュはブランチ名やコミットメッセージに表示される可能性が高いため、代わりに区切り文字@として使用できます。sed/sed
Oryバンド

28

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
Ory Band

10

以下のコードを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にはデフォルトでブランチ情報があるため、追加のブランチ名は不要であり、メッセージが見苦しくなります。


1
したがって、メッセージにマージという単語が見つかった場合、これはコミットメッセージを修正しませんか?
thoroc

1
技術的に正しい@thoroc。ただし、通常の使用では、これは大した問題ではありません。解析されるコミットメッセージは、編集する前の「デフォルトのもの」です。コミットテンプレートに「merge」という単語が含まれていない限り、大丈夫だと思います(他の「デフォルト」メッセージがデフォルトのマージコミットメッセージ以外にない限り)。私はもともとこれを誤解しており、今は正しいと信じています。
初心者C

5

上位の回答に基づいたTimの回答に触発されて、prepare-commit-msgフックが引数としてどのような種類のコミットが発生しているかがわかります。デフォルトのprepare-commit-msgに見られるように、$ 2が「マージ」の場合、それはマージコミットです。したがって、ケーススイッチを変更してTimのaddBranchName()関数を含めることができます。

ブランチ名を追加する方法と、デフォルトprepare-commit-msg.sampleフックのすべてのコメント化されていない部分について、独自の設定を含めました。

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

4

グローバルにする場合(すべてのプロジェクトに対して):

shytikovの回答の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再びあなたがそれを使いたい各プロジェクトで。


2
この機能を使用するには、「init.templatedir」用に設定されたディレクトリ内の「hooks」ディレクトリに「commit-msg」を配置する必要があり、templatedir全体が「git init」にコピーされると「commit- msg 'はプロジェクトの' .git / hooks 'ディレクトリに置かれます。
ダン

2

sedGNUではなくBSD を使用しているため、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、ホームディレクトリに名前の付いたファイルが必要です。


2

JIRAチケットをコミットメッセージに追加したい場合は、以下のスクリプトを使用してください。

次のようなメッセージをコミットします PROJECT-2313: Add awesome feature するには、ブランチ名がjiraチケットで始まる必要があります。

これは、このソリューションの組み合わせです。

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

これはクライアント側のファイルで正常に動作しています:prepare-commit-msgはコミットプレフィックスを自動入力します。しかし、ビットサイドサーバー(私の場合)であるサーバーサイドフックで同じことを行いたい場合、このロジックをビットバケットサーバーパスの事前受信フックに追加しようとしています:BITBUCKET_HOME / shared / data / repositories / <repository-id> / hooks / 21_pre_receive、それは "git symbolic-ref -q HEAD"として機能していないため、クライアント側からfeature / abcブランチからコミットしていますが、「master」を提供しています。ここに別の方法はありますか?
サントッシュ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.