एक विशिष्ट शाखा से निपटने के लिए गिट पोस्ट-प्राप्त हुक लिखना


107

यहाँ नंगे रेपो में मेरा वर्तमान हुक है जो कंपनी के सर्वर में रहता है: git push origin master यह हुक असेंबला को धक्का देता है। जब किसी को हमारे सर्वर पर उस शाखा में परिवर्तन होता है, और अन्य शाखाओं की ओर ध्यान नहीं जाता है, तो मुझे केवल एक शाखा (मास्टर, आदर्श) को पुश करने की आवश्यकता है। क्या नंगे रेपो से शाखा का चयन करना और केवल उस शाखा को असेंबला पर धकेलना संभव है?


आपका क्या अर्थ है? git push origin masterकेवल masterशाखा को originरिमोट पर धकेल देगा , जो मुझे लगता है कि असेंबला के रूप में परिभाषित किया गया है। क्या आप कह रहे हैं कि आपको हुक को ट्रिगर करने की ज़रूरत है जब कोई व्यक्ति धक्का देता है master, जैसा कि विरोध किया जाता है feature1, या ऐसा कुछ?
स्टीफन केंडल

@ सफ़्फ़ान बिल्कुल वही। मुझे शब्द नहीं मिला, हे।
जॉर्ज गुबेरटे सेप

जवाबों:


386

एक पोस्ट-प्राप्त हुक स्टड से अपने तर्क प्राप्त करता है, फॉर्म में <oldrev> <newrev> <refname>। चूँकि ये तर्क स्टड से आ रहे हैं, कमांड लाइन के तर्क से नहीं, आपको readइसके बजाय उपयोग करने की आवश्यकता है $1 $2 $3

पोस्ट-प्राप्त हुक एक बार में कई शाखाएं प्राप्त कर सकता है (उदाहरण के लिए अगर कोई करता है git push --all), तो हमें लूप readमें लपेटने की भी आवश्यकता है while

एक काम करने वाला स्निपेट कुछ इस तरह दिखता है:

#!/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
"==" मेरे लिए काम नहीं करता है। एकल "=" के साथ मेरे लिए अच्छा काम करता है।
रे

1
एक पुराने धागे को लाने के लिए क्षमा करें, लेकिन अगर मैं बयान में त्रुटि पा रहा हूं। घातक: दूरस्थ अंत अप्रत्याशित रूप से लटका हुआ है। त्रुटि: साइडबैंड demultiplexer में त्रुटि। यह इफ स्टेटमेंट के बाहर $ ब्रांच को इको करेगा।
गिन्ह 93

5
@ रे, तुम्हारे #!/bin/shबजाय है #!/bin/bash?
शटल87

2
एक जोखिम जिसके बारे में मैं सोच सकता हूं, वे टैग होंगे, क्योंकि उनके नाम शाखा नामों के साथ ओवरलैप हो सकते हैं। यदि आप के refs/heads/masterबजाय आप के लिए देखो refs/tags/masterठीक होना चाहिए। इस तरह के अन्य मामले हो सकते हैं, हालांकि मैं इसके बारे में सोच भी नहीं सकता। यह अपने आप में एक अच्छा StackOverflow प्रश्न हो सकता है।
पॉलजज़

1
@pauljz मैं उपयोग if branch=$(git rev-parse --symbolic --abbrev-ref $refname 2>/dev/null); thenकरता हूं ताकि जब मैं शाखा हटाता हूं तो शिकायत न हो।
Jérôme

8

अंतिम पैरामीटर जो एक पोस्ट-प्राप्त हुक स्टड पर मिलता है, जिसे रेफ को बदल दिया गया था, इसलिए हम इसका उपयोग कर सकते हैं कि यह जांचने के लिए कि क्या मान "रेफ्स / हेड / मास्टर है।" माणिक का थोड़ा सा जो मैं पोस्ट-प्राप्त हुक में उपयोग करता हूं:

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

ध्यान दें कि इसे प्रत्येक रेफ के लिए एक पंक्ति मिलती है जिसे धक्का दिया गया था, इसलिए यदि आपने केवल मास्टर से अधिक धक्का दिया, तो यह अभी भी काम करेगा।


रूबी उदाहरण के लिए धन्यवाद। मैं ऐसा ही कुछ करने जा रहा हूं।
लीफ

6

स्टीफन का जवाब मेरे काम नहीं आया, लेकिन यह किया:

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

मेरे लिए एक साधारण नाम (मास्टर, परीक्षण, आदि) वाली शाखाओं के लिए काम किया, लेकिन जब मेरे पास शाखा का नाम है जैसे: prod12 / proj250 / ropesPatch12। यह अच्छी तरह से काम नहीं करता है। क्या आपके पास कोई समाधान है जो उन विशेष पात्रों के साथ काम कर सकता है?
शचर हमुज़िम राजुआन

3

ऊपर दिए गए समाधानों में से किसी ने भी मेरे लिए काम नहीं किया। बहुत, बहुत डिबगिंग के बाद, यह पता चलता है कि 'रीड' कमांड का उपयोग करने से काम नहीं होता है - इसके बजाय, कमांड लाइन तर्क को सामान्य तरीके से ठीक करने का तर्क देता है।

यहाँ सटीक पोस्ट-अपडेट हुक है जिसे मैंने अभी अभी CentOS 6.3 पर सफलतापूर्वक परीक्षण किया है।

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

अद्यतन: एक भी अजनबी नोट पर, पूर्व प्राप्त हुक स्टड के माध्यम से अपना इनपुट लेता है, इसलिए 'रीड' के साथ पढ़ें (वाह, कभी नहीं सोचा था कि मैं ऐसा कहूंगा)। अपडेट-पोस्ट हुक अभी भी मेरे लिए $ 1 के साथ काम करता है।


2
इसके लायक होने के लिए, उपरोक्त समाधानों ने काम नहीं किया हो सकता है क्योंकि वे विशेष रूप से post-receiveहुक के लिए हैं, न कि post-updateहुक के लिए। वे अपने इनपुट को अलग-अलग तरीकों से लेते हैं।
पाउलज

post-receiveजैसा कि यहाँ उल्लेख किया गया है: स्टीन
h4xnoodle

1

@Pauljz से जवाब कुछ निश्चित हुक के लिए ठीक काम करता है pre-push, लेकिन pre-commitउन चर तक पहुंच नहीं हैoldrev newrev refname

इसलिए मैंने इस वैकल्पिक संस्करण का निर्माण किया जो प्री-कमिट, या वास्तव में और हुक के लिए काम करता है। यह एक pre-commitहुक है जो एक huskyस्क्रिप्ट चलाएगा यदि हम 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

मुझे उम्मीद है कि किसी की मदद करता है। आप आसानी से अपनी जरूरतों के लिए, ifऔर fiबयानों के बीच कुछ भी संशोधित कर सकते हैं ।


0

मैंने इस कार्यक्षमता को करने के लिए अपने लिए एक PHP स्क्रिप्ट लिखी थी।

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

इस फ़ाइल को अपने सर्वर पर होस्ट करें, अधिमानतः रेपो रूट और github webhooks में url को परिभाषित करें। अपने शाखा नाम के साथ लाइन 8 पर 'allcommits' बदलें और लाइन 18 पर अपना कोड / फ़ंक्शन जोड़ें।

जैसे

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.