Belirli bir şubeyle ilgilenmek için git sonrası alma kancası yazma


107

İşte şirketin sunucusunda yaşayan çıplak bir depodaki mevcut kancam: git push origin master Bu kancalar Assembla'yı zorluyor. İhtiyacım olan şey, birisi sunucumuzdaki o dala yapılan değişiklikleri ittiğinde yalnızca bir dalı (ideal olarak ana) itmek ve diğer şubelere yapılan itmeleri yok saymaktır. Şubeyi çıplak bir depodan seçip sadece o şubeyi Assembla'ya itmek mümkün müdür?


Ne demek istiyorsun? git push origin mastersadece Assembla olarak tanımlandığını varsaydığım masterdalı originuzak tarafa itecek . Eğer gerektiğini söylüyorsunuz tetiklemek için sadece birisi iter kanca masteraksine, feature1ya da böyle bir şey?
Stefan Kendall

@Stefan Aynen öyle. Kelimeyi bulamadım hehe.
Jorge Guberte

Yanıtlar:


386

Alma sonrası kancası argümanlarını stdin'den formda alır <oldrev> <newrev> <refname>. Bu argümanlar bir komut satırı argümanından değil, stdin'den geldiği için, readyerine kullanmanız gerekir $1 $2 $3.

Alım sonrası kancası aynı anda birden fazla dalı alabilir (örneğin, birisi a yaparsa git push --all), bu yüzden readbir whiledöngü içinde sarmamız gerekir .

Bir çalışma pasajı şuna benzer:

#!/bin/bash
while read oldrev newrev refname
do
    branch=$(git rev-parse --symbolic --abbrev-ref $refname)
    if [ "master" = "$branch" ]; then
        # Do something
    fi
done

2
"==" benim için çalışmıyor. Tekli "=" benim için iyi çalışıyor.
Ray

1
Eski bir ileti dizisini açtığım için özür dilerim ama if ifadesinde bir hata alıyorum. ölümcül: uzak uç beklenmedik bir şekilde kapattı. hata: yan bant çoğullama çözücüsünde hata. İf ifadesinin dışında $ dalını yankılayacaktır.
gin93r

5
@Ray, #!/bin/shyerine var #!/bin/bashmı?
shuttle87

2
Aklıma gelen bir risk, isimleri şube isimleriyle örtüştüğü için etiketler olabilir. Eğer için bakarsak refs/heads/masteryerine refs/tags/mastersize tamam olmalıdır. Aklıma gelmeyen bunun gibi başka uç durumlar da olabilir. Kendi başına iyi bir StackOverflow sorusu olabilir.
pauljz

1
@pauljz if branch=$(git rev-parse --symbolic --abbrev-ref $refname 2>/dev/null); thenBir dalı kaldırdığımda git şikayet etmesin diye kullanıyorum .
Jérôme

8

Bir alım sonrası kancanın stdin üzerinde aldığı son parametre, ref değiştirilen değerdir, bu nedenle, bu değerin "refs / Heads / master" olup olmadığını kontrol etmek için bunu kullanabiliriz. Alım sonrası kancasında kullandığıma benzer bir miktar yakut:

STDIN.each do |line|
    (old_rev, new_rev, ref_name) = line.split
    if ref_name =~ /master/
         # do your push
    end
end

İtilen her referans için bir satır aldığına dikkat edin, bu nedenle, sadece ustadan daha fazlasını ittiyseniz, yine de çalışacaktır.


Ruby örneği için teşekkürler. Buna benzer bir şey yapacağım.
Leif

6

Stefan'ın cevabı benim için işe yaramadı ama bu işe yaradı:

#!/bin/bash

echo "determining branch"

if ! [ -t 0 ]; then
  read -a ref
fi

IFS='/' read -ra REF <<< "${ref[2]}"
branch="${REF[2]}"

if [ "master" == "$branch" ]; then
  echo 'master was pushed'
fi

if [ "staging" == "$branch" ]; then
  echo 'staging was pushed'
fi

echo "done"

Benim için basit bir adı olan şubeler için çalıştı (ana, test, vb.), Ama şube ismine sahip olduğumda: prod12 / proj250 / ropesPatch12. pek işe yaramıyor. Bu özel karakterlerle çalışabilecek bir çözümünüz var mı?
Shachar Hamuzim Rajuan

3

Yukarıdaki çözümlerin hiçbiri benim için işe yaramadı. Çok, çok fazla hata ayıklamadan sonra, 'oku' komutunu kullanmanın işe yaramadığı ortaya çıkıyor - bunun yerine, komut satırı argümanlarını her zamanki şekilde ayrıştırmak iyi çalışıyor.

İşte şimdi CentOS 6.3'te başarıyla test ettiğim güncelleme sonrası kancası.

#!/bin/bash

echo "determining branch"

branch=`echo $1 | cut -d/ -f3`

if [ "master" == "$branch" ]; then
    echo "master branch selected"
fi

if [ "staging" == "$branch" ]; then
    echo "staging branch selected"
fi

exec git update-server-info

GÜNCELLEME: Daha da garip bir notta, ön alım kancası girişini stdin aracılığıyla alır, bu nedenle 'oku' ile okuyun (vay, bunu söyleyeceğimi hiç düşünmemiştim). Güncelleme sonrası kancası hala benim için 1 $ ile çalışıyor.


2
Değeri ne olursa olsun, yukarıdaki çözümler işe yaramayabilir çünkü bunlar özellikle post-receivekancalar için değil, post-updatekancalar içindir. Görüşlerini farklı şekillerde alıyorlar.
pauljz

post-receiveburada belirtildiği gibi stdin alır: git-scm.com/book/en/v2/Customizing-Git-Git-Hooks
h4xnoodle

1

@Pauljz'den gelen yanıt, gibi belirli git kancaları için iyi çalışıyor pre-push, ancak pre-commitbu değişkenlere erişimi yokoldrev newrev refname

Bu yüzden, ön işleme için veya gerçekten ve kanca için çalışan bu alternatif sürümü yarattım. Bu, dalda DEĞİLSEK, pre-commitbir huskykomut dosyası çalıştıracak bir kancadır master.

#!/bin/bash
# git 'commit' does not have access to these variables: oldrev newrev refname
# So get the branch name off the head

branchPath=$(git symbolic-ref -q HEAD) # Something like refs/heads/myBranchName
branch=${branchPath##*/}      # Get text behind the last / of the branch path

echo "Head: $branchPath";
echo "Current Branch: $branch";

if [ "master" != "$branch" ]; then

   # If we're NOT on the Master branch, then Do something
   # Original Pre-push script from husky 0.14.3

   command_exists () {
     command -v "$1" >/dev/null 2>&1
   }

   has_hook_script () {
     [ -f package.json ] && cat package.json | grep -q "\"$1\"[[:space:]]*:"
   }

   cd "frontend" # change to your project directory, if .git is a level higher

   # Check if precommit script is defined, skip if not
   has_hook_script precommit || exit 0

   # Node standard installation
   export PATH="$PATH:/c/Program Files/nodejs"

   # Check that npm exists
   command_exists npm || {
     echo >&2 "husky > can't find npm in PATH, skipping precommit script in package.json"
     exit 0
   }

   # Export Git hook params
   export GIT_PARAMS="$*"

   # Run npm script
   echo "husky > npm run -s precommit (node `node -v`)"
   echo

   npm run -s precommit || {
     echo
     echo "husky > pre-commit hook failed (add --no-verify to bypass)"
     exit 1
   }
fi

Umarım bu birine yardımcı olur. İhtiyaçlarınız için ifve fiifadeleri arasındaki her şeyi kolayca değiştirebilirsiniz .


0

Bu işlevi yapabilmek için kendime bir PHP betiği yazmıştım.

https://github.com/fotuzlab/githubdump-php

Bu dosyayı sunucunuzda, tercihen repo kökünde barındırın ve url'yi github web kancalarında tanımlayın. 8. satırdaki 'allcommits'i şube adınızla değiştirin ve kodunuzu / işlevinizi 18. satıra ekleyin.

Örneğin

function githubdump($payload_object) {
    // Write your code here.
    exec('git push origin master');
}

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.