Git की शाखा का नाम कमिट मैसेज में कैसे जोड़ें?


103

मुझे बैश स्क्रिप्ट के साथ कुछ मदद की ज़रूरत है जो प्रतिबद्ध संदेशों में हैश के रूप में स्वचालित रूप से गिट की शाखा का नाम जोड़ेगी।


4
यहाँ आने वाले किसी व्यक्ति के लिए ऐसा लगता है कि सबसे अच्छा उत्तर पृष्ठ के निचले भाग पर है
बेन टालियाडोरस

साइड नोट: git branch | grep ...वर्तमान शाखा प्राप्त करने के लिए सभी ऐसा करने का गलत तरीका है। या तो git symbolic-ref -q HEAD(जैसा कि इस उत्तर में दिखाया गया है ) पर विचार करें या git rev-parse --abbrev-ref HEAD। प्रतीकात्मक-रेफ कमांड विफल हो जाएगी यदि आप एक अलग हेड पर हैं, इसलिए यदि आप उस मामले का पता लगाना चाहते हैं, तो इसका उपयोग करें। अन्यथा रेव-पार्से - बाबरेव-रेफ विधि शायद सबसे अच्छा है।
torek

जवाबों:


53

prepare-commit-msgया commit-msg githook का उपयोग करें ।

आपकी PROJECT/.git/hooks/निर्देशिका में पहले से ही उदाहरण हैं ।

सुरक्षा उपाय के रूप में, आपको मैन्युअल रूप से इस तरह के हुक को प्रत्येक रिपॉजिटरी पर सक्षम करना होगा जिसे आप इसका उपयोग करना चाहते हैं। हालाँकि, आप स्क्रिप्ट को कमिट कर सकते हैं और इसे सभी क्लोन पर .git/hooks/डायरेक्टरी में कॉपी कर सकते हैं ।


धन्यवाद एक महान नेतृत्व; धन्यवाद। यदि आप मुझे आगे की मदद कर सकते हैं, तो स्क्रिप्ट के साथ ही, मैं आभारी रहूँगा :)
तोमर लिक्टाश

5
मुझे इसकी आवश्यकता नहीं है, आपके पास पहले से ही एक उदाहरण है जो आप जैसा चाहते हैं वैसा ही करते हैं , जैसा कि मैंने पहले ही कहा था .git/hooks/prepare-commit-msg.sample। =) तुम सब (टिप्पणी में निर्देशों का पालन करने के बाद संशोधित करने के लिए) की जरूरत है कॉपी-पेस्ट करने से जो कुछ भी समाधान है stackoverflow.com/questions/1593051/... आप चाहें
ninjagecko

4
@ninjagecko, मेरे लिए .git/hooks/prepare-commit-msg.sampleतीन उदाहरण हैं। टकराव अनुभाग को टिप्पणी करने के लिए एक, इसमें git diff --name-status -rआउटपुट जोड़ना और हस्ताक्षरित-बंद लाइनों को जोड़ना ... प्रतिबद्ध संदेश में शाखा का नाम नहीं जोड़ना। इसलिए मुझे अपना हुक लिखने के लिए मजबूर होना पड़ा।
शिटिकोव

1
क्या you will have to manually enable such a hook on each repository you wish to use itइसका मतलब यह है कि आपको एफआईएल निष्पादित की अनुमति देनी है? यदि ऐसा है, तो क्या मैं उसे (या आप, कृपया) शामिल करने के लिए उत्तर को संपादित कर सकता हूं?
डेन रोसेन्स्टार्क

2
इसका जवाब क्यों है? यह और अधिक है जैसे कि मुझे आपके लिए Google बनाना है। @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_descriptionउपयोग के लिए रखा गया है git branch --edit-description [branch_name]

शाखा विवरण के बारे में अधिक जानकारी आप इस प्रश्नोत्तर पर पा सकते हैं ।

कोड उदाहरण Gist के बाद संग्रहीत किया जाता है ।


8
यह स्क्रिप्ट एक लाइन के लिए मल्टी लाइन प्रतिबद्ध संदेश स्क्वैश करता है। मैंने आपका इको स्टेटमेंट बदल दिया है: इको-एन "$ नेम" ": '| बिल्ली -" $ 1 "> / tmp / out && mv / tmp / out" $ 1 "
एलेक्स स्पेंस

4
इस फाइल को PROJECT /
.OG

2
यह अच्छा काम करता है। लेकिन मैक के लिए, मुझे इसे काम करने के लिए अनुमति भी निर्धारित करनी थी: >>> sudo chmod 755 .git / हुक / प्रतिबद्ध-संदेश
मनोज श्रेष्ठ

1
@ManojShrestha हाँ, इसे निष्पादन योग्य बनाना होगा
डेविड मैन

2
@AlexSpence और अधिक बस आप उपयोग कर सकते हैं echo $NAME: "$(cat $1)" > $1। यह काम करता है क्योंकि जिस कारण से नई सुर्खियाँ खोई जा रही थीं वह यह है कि इको प्रत्येक लाइन $(cat "$1")को एक नए तर्क के रूप में मान रहा था और प्रत्येक को बीच के स्थान के साथ प्रतिध्वनित कर रहा था । आसपास के द्वारा $(cat "$1")दोहरे उद्धरण चिह्नों के साथ, व्यवहार करता है एक भी तर्क के रूप में बिल्ली उत्पादन गूंज। इसके अलावा, मुझे नहीं लगता कि यह जरूरी है $1क्योंकि इसका मूल्य है.git/COMMIT_EDITMSG
PiersyP

30

थोड़ी सी सरल स्क्रिप्ट जो आपको संपादित करने से पहले शाखा का नाम प्रतिबद्ध संदेश में जोड़ देती है। इसलिए यदि आप इसे बदलना या हटाना चाहते हैं तो आप कर सकते हैं।

इस फ़ाइल को बनाएँ .it / हुक / तैयार-कमिट-संदेश :

#!/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 .जब यह प्रयोग करते हैं।
एडम पार्किन


2
संशोधन और
फिक्सअप

3
OSX: यदि आपको उपरोक्त त्रुटि संदेश मिल रहा है तो काम करने के लिए फ़ाइल एक्सटेंशन की आवश्यकता है। sed -i '.bak' "1s/^/$branchName : \n/" $1
कैनिनटेक्स

इसके बजाय आप @एक sedविभाजक के रूप में उपयोग कर सकते हैं /क्योंकि आगे की स्लैश शाखा नाम या प्रतिबद्ध संदेश दिखाने, खराब होने की अधिक संभावना है sed
ओरी बैंड

28

आप इसे तैयार-कमिट-मैसज और प्री-कमिट हुक के संयोजन के साथ कर सकते हैं।

.git / हुक / तैयार-लिखें-msg

#!/bin/sh

BRANCH=`git branch | grep '^\*' | cut -b3-`
FILE=`cat "$1"`
echo "$BRANCH $FILE" > "$1"

.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

अनुमतियाँ सेट करें

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

नीचे दिए गए कोड को तैयार-कम-मेस फाइल में जोड़ें।

#!/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

यह मर्ज-कमिट को छोड़कर संदेश देने के लिए शाखा का नाम जोड़ेगा। मर्ज-कमिट में डिफ़ॉल्ट रूप से शाखा जानकारी होती है इसलिए अतिरिक्त शाखा नाम अनावश्यक है और संदेश को बदसूरत बना देता है।


1
तो यह प्रतिबद्ध संदेश में संशोधन नहीं करेगा जब यह शब्द को संदेश पर मिल जाए?
थोरोक

1
@thoroc जो तकनीकी रूप से सही है; हालाँकि, सामान्य उपयोग में यह कोई बड़ी बात नहीं है। आपके द्वारा संपादित किए जाने से पहले प्रतिबद्ध संदेश को "डिफ़ॉल्ट वाले" कहा जाता है। इसलिए जब तक आपके कमिटमेंट टेम्पलेट में "मर्ज" शब्द नहीं है, मेरा मानना ​​है कि आपको ठीक होना चाहिए (जब तक कि अन्य "डिफ़ॉल्ट" संदेश डिफ़ॉल्ट मर्ज कमिट के अलावा न हों)। मैंने इसे मूल रूप से गलत समझा, और मुझे विश्वास है कि मेरे पास अभी यह है।
Novice C

5

टिम के उत्तर से प्रेरित होकर जो शीर्ष उत्तर पर बनता है, यह पता चलता है कि तैयार-कमिट-मेस हुक एक तर्क के रूप में लेता है कि किस प्रकार की प्रतिबद्धता हो रही है । जैसा कि डिफ़ॉल्ट तैयार-कमिट-मेस में देखा जाता है यदि $ 2 'मर्ज' है तो यह मर्ज कमिट है। इस प्रकार टिम के ऐडब्रांचनाम () फ़ंक्शन को शामिल करने के लिए केस स्विच को बदला जा सकता है।

मैंने शाखा के नाम, और डिफ़ॉल्ट prepare-commit-msg.sampleहुक के सभी अपूर्ण भागों को जोड़ने के लिए अपनी स्वयं की प्राथमिकता शामिल की है ।

तैयार-लिखें-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

यदि आप इसे वैश्विक बनाना चाहते हैं (सभी परियोजनाओं के लिए):

शिटिकोव के उत्तर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' के लिए कॉन्फ़िगर की गई निर्देशिका के अंदर 'प्रतिबद्ध-संदेश' को 'हुक' निर्देशिका में रखना था ताकि जब पूरा टेम्पलेटेडिट 'गिट इनिट', 'प्रतिबद्ध' पर कॉपी हो जाए संदेश 'परियोजना की' .git / हुक 'निर्देशिका में समाप्त होता है।
दान

2

मैं इन समाधानों को MacOS पर काम करने के लिए इस तथ्य के कारण प्राप्त कर रहा था कि यह sedGNU के बजाय BSD का उपयोग करता है 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। यदि आपकी शाखा का नाम केवल आपका जीरा टिकट नंबर है, तो आप पाइप से f2 तक सभी चीजों से छुटकारा पा सकते हैं। इसके लिए यह भी आवश्यक है कि आपके पास .gitmessageअपने घर निर्देशिका में एक फ़ाइल हो ।


2

यदि आप चाहते हैं कि JIRA टिकट कमिट मैसेज में जोड़े गए स्क्रिप्ट बलो का उपयोग करे।

संदेश कुछ ऐसा करें PROJECT-2313: Add awesome feature इस यह आपकी शाखा का नाम जीरा टिकट के साथ शुरू हो।

यह इस समाधान का एक संयोजन है:

यह ओएस एक्स के लिए संशोधित है, sed -i '.bak'और यह सोर्सट्री से भी काम करता है।

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

यह क्लाइंट साइड फ़ाइल पर अच्छा काम कर रहा है: ऑटो-पॉप्युलेट कमिट प्रीफिक्स के लिए तैयार-कमिट-एमएसएन। लेकिन अगर मैं सर्वर साइड हुक पर वही करना चाहता हूं, जो बिटबकेट सर्वर (मेरे मामले में) है और मैं बिटकबेट सर्वर पथ पर पूर्व-प्राप्त हुक पर इस तर्क को जोड़ने की कोशिश कर रहा हूं: BITBUCKET_HIT / साझा / डेटा / रिपॉजिटरी / <रिपॉजिटरी-आईडी> / हुक / 21_pre_receive, यह "git प्रतीकात्मक-रेफ -q HEAD" के रूप में काम नहीं कर रहा है, जो 'मास्टर' दे रहा है, हालांकि मैं क्लाइंट की तरफ से अपनी सुविधा / abc शाखा से कर रहा हूं। क्या यहां कोई और रास्ता है?
संवत
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.