커밋 메시지에 Git의 브랜치 이름을 추가하는 방법은 무엇입니까?


103

커밋 메시지에 git의 브랜치 이름을 해시로 자동 추가하는 Bash 스크립트에 대한 도움이 필요합니다.


4
사람이 여기에 오는 최선의 대답은 페이지의 하단에 보인다
벤 Taliadoros

참고 : git branch | grep ...현재 분기를 가져 오는 모든 방법은이 작업을 수행하는 잘못된 방법입니다. git symbolic-ref -q HEAD( 이 답변에 표시된대로 ) 또는을 고려하십시오 git rev-parse --abbrev-ref HEAD. 분리 된 HEAD에 있으면 symbolic-ref 명령이 실패하므로이 경우를 감지하려면 사용하십시오. 그렇지 않으면 rev-parse --abbrev-ref 방법이 아마도 가장 좋습니다.
torek

답변:


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는 세 가지 예를 포함합니다. 충돌 섹션을 주석 처리하고 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 itFILE 실행 권한을 부여해야 함을 의미 합니까 ? 그렇다면 그 내용을 포함하도록 답변을 편집 할 수 있습니까?
Dan Rosenstark

2
이것이 답인 이유는 무엇입니까? 그것은 내가 당신을 위해 그것을 구글하게하는 것과 같다. @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
이 스크립트는 여러 줄의 커밋 메시지를 한 줄로 정리합니다. echo 문을 다음으로 바꿨습니다. echo -n "$ NAME" ':'| cat- "$ 1"> / tmp / out && mv / tmp / out "$ 1"
Alex Spence

4
폴더 프로젝트에이 파일을 넣어 / .git / 후크 /
catanore

2
잘 작동한다. 하지만 Mac의 경우 작동하도록 권한을 설정해야했습니다. >>> sudo chmod 755 .git / hooks / commit-msg
Manoj Shrestha

1
@ManojShrestha 예는 실행 가능합니다
데이빗 만

2
@AlexSpence는 더 간단하게 사용할 수 있습니다 echo $NAME: "$(cat $1)" > $1. 줄 바꿈이 손실 된 이유는 에코가 각 줄을 $(cat "$1")새 인수로 취급하고 각 줄 사이에 공백을두고 에코하기 때문입니다. 주변으로 $(cat "$1")큰 따옴표로, 취급에게 하나의 인수로 고양이 출력을 에코. 또한 나는 그것을 인용하는 것이 필요하다 생각하지 않는다 $1값이기 때문에.git/COMMIT_EDITMSG
PiersyP

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 .이것을 사용할 때 얻는다 .
Adam Parkin 2013

1
Aha, Mac OSX 차이, 참조 : hintsforums.macworld.com/showpost.php?p=393450&postcount=11 수정 사항
Adam Parkin

2
수정 및 변경 수정 케이스의 확인 등
pogopaule

3
OSX : 위의 오류 메시지가 표시되는 경우 작동하려면 파일 확장자가 필요합니다. sed -i '.bak' "1s/^/$branchName : \n/" $1
canintex

슬래시가 브랜치 이름이나 커밋 메시지에 나타날 가능성이 높기 때문에 대신 구분 기호 @로 사용할 수 있습니다 . sed/sed
Ory Band

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
그래서 이것은 메시지에서 merge라는 단어를 찾을 때 커밋 메시지를 수정하지 않습니까?
thoroc

1
기술적으로 올바른 @thoroc; 그러나 정상적인 사용에서는 큰 문제가 아닙니다. 구문 분석중인 커밋 메시지는 편집하기 전에 "기본 메시지"입니다. 따라서 커밋 템플릿에 "merge"라는 단어가없는 한 괜찮습니다 (다른 "기본"메시지가 기본 병합 커밋 메시지를 제외하지 않는 한). 나는 이것을 원래 오해했고 지금 그것이 맞다고 믿습니다.
초보자 C

5

최상위 답변을 기반으로 한 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

4

글로벌로 만들려면 (모든 프로젝트에 대해) :

만들기 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다시 사용하려는 각 프로젝트에서.


2
이 기능을 사용하려면 'init.templatedir'에 대해 구성된 디렉터리 내의 'hooks'디렉터리에 'commit-msg'를 넣어야했기 때문에 전체 templatedir이 'git init', 'commit- msg '는 프로젝트의'.git / hooks '디렉토리에 있습니다.
Dan

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 서버 (내 경우) 인 서버 측 후크에서 동일한 작업을 수행하고 Bitbucket 서버 경로 : BITBUCKET_HOME / shared / data / repositories /에서 사전 수신 후크 에이 논리를 추가하려고합니다. <repository-id> / hooks / 21_pre_receive, 클라이언트 측의 기능 / abc 분기에서 커밋하고 있지만 '마스터'를 제공하는 "git symbolic-ref -q HEAD"로 작동하지 않습니다. 여기에 다른 방법이 있습니까?
santhosh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.