Kaydetme mesajına Git'in şube adı nasıl eklenir?


103

Git'in şube adını kaydetme mesajlarına karma olarak otomatik olarak ekleyecek bir Bash komut dosyasıyla ilgili yardıma ihtiyacım var.


4
Buraya gelenler için en iyi cevap sayfanın alt kısmında görünüyor
Ben Taliadoros

Yan not: git branch | grep ...Mevcut şubeyi elde etmek, bunu yapmanın yanlış yoludur. Ya git symbolic-ref -q HEAD( bu cevapta gösterildiği gibi ) veya git rev-parse --abbrev-ref HEAD. Bağımsız bir HEAD üzerindeyseniz sembolik-ref komutu başarısız olacaktır, bu nedenle bu durumu tespit etmek istiyorsanız, onu kullanın. Aksi takdirde, rev-parse --abbrev-ref yöntemi muhtemelen en iyisidir.
torek

Yanıtlar:


53

prepare-commit-msgVeya commit-msg githook'u kullanın .

Dizininizde zaten örnekler var PROJECT/.git/hooks/.

Bir güvenlik önlemi olarak, kullanmak istediğiniz her depoda böyle bir kancayı manuel olarak etkinleştirmeniz gerekecektir. Yine de, komut dosyasını işleyebilir ve tüm klonlarda .git/hooks/dizine kopyalayabilirsiniz .


Teşekkürler büyük bir ipucu; teşekkür ederim. Bana daha fazla yardım edebilirsen, senaryonun kendisiyle minnettar olacağım :)
Tomer Lichtash

5
Buna ihtiyacım yok, zaten söylediğim gibi , tam olarak istediğini yapan bir örneğe sahipsiniz.git/hooks/prepare-commit-msg.sample . =) Değiştirmeniz gereken tek şey (yorumlardaki talimatları izledikten sonra), stackoverflow.com/questions/1593051/…
adresinden

4
@ninjagecko, benim için .git/hooks/prepare-commit-msg.sampleüç örnek içeriyor. Çakışmalar bölümünü yorumlamak, git diff --name-status -rona çıktı eklemek ve Signed-off-by satırları eklemek için bir tane ... commit mesajına dal adı eklemek yok. Bu yüzden kendi kancamı yazmaya zorlandım.
shytikov

1
Bu you will have to manually enable such a hook on each repository you wish to use it, FILE'a yürütme izinleri vermeniz gerektiği anlamına mı geliyor? Öyleyse, cevabı bunu içerecek şekilde düzenleyebilir miyim (veya lütfen, lütfen)?
Dan Rosenstark

2
Cevap neden bu? Daha çok senin için google'layayım gibi. Cevap @shytikov seçilmelidir
TheRealFakeNews

177

commit-msgÖrnek olarak benim senaryom:

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

Aşağıdaki commit mesajını oluşturur:

[branch_name]: [original_message]

[branch_description]

Sorun numarasını kullanma komutuna branch_namesorun açıklaması yerleştirildiği için branch_descriptionkullanıyorum git branch --edit-description [branch_name].

Bu Soru-Cevap bölümünde bulabileceğiniz şube açıklamaları hakkında daha fazla bilgi .

Kod örneği aşağıdaki Gist'te depolanır .


9
Bu komut dosyası, çok satırlı commit mesajlarını tek bir satıra sıkıştırır. Echo ifadenizi şu şekilde değiştirdim: echo -n "$ NAME" ':' | cat - "$ 1"> / tmp / out && mv / tmp / out "$ 1"
Alex Spence

4
Bu dosyayı PROJECT / .git / hooks /
catanore

2
İyi çalışıyor. Ancak Mac için, çalışmasını sağlamak için de izni ayarlamam gerekiyordu: >>> sudo chmod 755 .git / hooks / commit-msg
Manoj Shrestha

1
@ManojShrestha evet çalıştırılabilir olmalı
David Mann

2
@AlexSpence daha basit bir şekilde kullanabilirsiniz echo $NAME: "$(cat $1)" > $1. Bu işe yarıyor çünkü satırsonlarının kaybolmasının nedeni, yankının her satıra $(cat "$1")yeni bir argüman olarak davranması ve her birini aralarında boşluk bırakarak yankılamasıdır. $(cat "$1")Çift tırnak içine alarak, echo cat çıktısını tek bir argüman olarak ele alır. Ayrıca $1değeri olduğu için alıntı yapmanın gerekli olduğunu düşünmüyorum.git/COMMIT_EDITMSG
PiersyP

30

Siz düzenlemeden önce commit mesajına dal adını ekleyen biraz daha basit bir komut dosyası . Yani, değiştirmek ya da kaldırmak istiyorsanız, yapabilirsiniz.

Bu dosyayı .git / hooks / ready-commit-msg oluşturun :

#!/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
Anlıyorum: bunu sed: 1: ".git/COMMIT_EDITMSG": invalid command code .kullanırken.
Adam Parkin

1
Aha, Mac OSX farkı, bkz .: hintsforums.macworld.com/showpost.php?p=393450&postcount=11 düzeltme için
Adam Parkin

2
değişiklik ve düzeltme davasının kontrol edilmesi gibi
pogopaule

3
OSX: Yukarıdaki hata mesajını alıyorsanız, çalışması için dosya uzantısı gerekir. sed -i '.bak' "1s/^/$branchName : \n/" $1
canintex

Bunun yerine ayırıcı @olarak kullanabilirsiniz sed, /çünkü eğik çizgilerin şube adında veya commit mesajında ​​görünme olasılığı daha yüksektir, berbattır sed.
Ory Band

28

Bunu, hazırlık-taahhüt-mesaj ve ön-teslim kancalarının bir kombinasyonu ile yapabilirsiniz.

.git / hooks / ready-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

İzinleri ayarlayın

sudo chmod 755 .git/hooks/prepare-commit-msg
sudo chmod 755 .git/hooks/pre-commit

--amendÖrneğin kullanıyorsanız , bunun orijinal kaydetme mesajını kaldırabileceğini unutmayın . Kullanmak yerine echokullanmalısınız sed. İşte tek satırda:sed -i "1s@^@$(git branch | grep '^\*' | cut -b3-) @" $1
Ory Band

10

Prepar-commit-msg dosyasına aşağıdaki kodu ekleyin.

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

Birleştirme-kesinleştirme dışında iletiyi işlemek için dal adı ekleyecektir. Birleştirme-kesinleştirme varsayılan olarak dal bilgisine sahiptir, bu nedenle fazladan dal adı gereksizdir ve mesajı çirkinleştirir.


1
Yani bu, mesajda kelime birleştirme kelimesini bulduğunda commit mesajını değiştirmeyecek mi?
thoroc

1
@thoroc teknik olarak doğru; ancak, normal kullanımda bu çok önemli değil. Ayrıştırılan commit mesajı, siz onları düzenlemeden önce "varsayılan olanlardır". Taahhüt şablonunuzda "birleştirme" kelimesi bulunmadığı sürece, iyi olmanız gerektiğine inanıyorum (diğer "varsayılan" mesajlar varsayılan bir birleştirme tamamlama mesajı dışında olmadığı sürece). Bunu başlangıçta yanlış anladım ve şimdi doğru yaptığıma inanıyorum.
Novice C

5

Tim'in en iyi cevaba dayanan cevabından esinlenerek hazırla-commit-msg kancasının ne tür bir işlemin gerçekleştiğini bir argüman olarak aldığı ortaya çıktı . Varsayılan hazırlama-kaydetme-msg'de görüldüğü gibi, $ 2 'birleştirme' ise, o zaman bu bir birleştirme işlemidir. Böylece, durum anahtarı Tim'in addBranchName () işlevini içerecek şekilde değiştirilebilir.

Dal adının nasıl ekleneceğine ilişkin kendi tercihlerimi ve varsayılan prepare-commit-msg.samplekancanın tüm yorumlanmamış kısımlarını ekledim .

hazırla-tamamla-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

Global yapmak istiyorsanız (tüm projeler için):

Shytikov'un cevabınıngit-msg içeriğiyle dosya oluşturun ve bir klasöre koyun:

mkdir -p ~/.git_hooks
# make it executable
chmod a+x ~/.git_hooks/commit-msg

Şimdi kancaları etkinleştirin:

git config --global init.templatedir '~/.git_hooks'

ve git inityine kullanmak istediğiniz her projede.


2
Bu özelliği kullanmak için, 'commit-msg' yi 'init.templatedir' için yapılandırılmış dizinin içindeki 'hooks' dizinine koymam gerektiğini fark ettim, böylece tüm templatedir 'git init', 'commit- msg 'projenin' .git / hooks 'dizininde biter.
Dan

2

sedGNU yerine BSD kullanması nedeniyle bu çözümleri MacOS üzerinde çalıştırmada sorunlar yaşıyordum sed. Yine de işi yapan basit bir senaryo oluşturmayı başardım. Hala kullanılıyor .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 

Bu, benzer bir dal adlandırma standardı olduğunu varsayar functional-desc_JIRA-NUMBER. Şube adınız yalnızca Jira bilet numaranızsa, borudan f2'ye kadar her şeyden kolayca kurtulabilirsiniz. Ayrıca .gitmessage, ana dizininizde adlandırılmış bir dosyanızın olmasını gerektirir .


2

JIRA biletinin commit mesajına eklenmesini istiyorsanız aşağıdaki komut dosyasını kullanın.

Commit message şuna benzer bir şey PROJECT-2313: Add awesome feature Bu, şube adınızın jira Ticket ile başlamasını gerektirir.

Bu, şu çözümlerin bir kombinasyonudur:

OS X için değiştirilmiştir sed -i '.bak've SourceTree'den de çalışır.

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

Bu, istemci tarafı dosyasında iyi çalışıyor: commit önekini otomatik olarak doldurmak için ready-commit-msg. Ancak aynısını bitbucket sunucusu olan sunucu tarafı kancasında yapmak istersem (benim durumumda) ve bu mantığı Bitbucket sunucu yolunda önceden alma kancasına eklemeye çalışıyorum: BITBUCKET_HOME / shared / data / repositories / <repository-id> / hooks / 21_pre_receive, istemciden özellik / abc dalımdan taahhüt etmeme rağmen 'ana' veren "git symbolic-ref -q HEAD" olarak çalışmıyor. Burada başka bir yol var mı?
santhosh
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.