2010-11-16 17 views
77

मैं प्रत्येक गिट पुश से पहले यूनिट-टेस्ट चलाने की इच्छा करता हूं और यदि परीक्षण विफल हो जाता है, तो पुश रद्द करें, लेकिन मुझे प्री-पुश हुक भी नहीं मिल रहा है, पूर्व-प्रतिबद्धता और प्री- केवल rebase।गिट प्री-पुश हुक

उत्तर

20

मैं प्री-प्रतिबद्ध-हुक में परीक्षण चलाऊंगा। क्योंकि परिवर्तन करते समय परिवर्तन पहले से ही दर्ज किया गया है। पहले से रिकॉर्ड किए गए परिवर्तन के बारे में केवल विनिमय जानकारी को पुश करें और खींचें। यदि कोई परीक्षण विफल रहता है तो आपके पास पहले से ही आपके भंडार में "टूटा" संशोधन होगा। चाहे आप इसे दबा रहे हों या नहीं।

+112

मैं आम तौर पर सहमत हूं, हालांकि यदि आप बाद में स्क्वैश करने के लिए बहुत बढ़िया काम करने की आदत में हैं, और परीक्षण सूट बड़ा है, तो यह अव्यवहारिक हो सकता है। – Cascabel

+0

मैं देखता हूं। तो मैं मुख्य शाखा के साथ विलय करने से पहले परीक्षणों का सुझाव दूंगा लेकिन कोई प्री-मर्ज हुक नहीं है। हालांकि रिमोट रिपोजिटरी में रेफरी को अपडेट करने से रोकने के लिए "अपडेट" हुक विच का उपयोग किया जा सकता है: "रिमोट रिपोजिटरी पर रेफरी अपडेट करने से ठीक पहले, अपडेट हुक लगाया जाता है। इसकी निकास स्थिति रेफरी की सफलता या विफलता को निर्धारित करती है। । अद्यतन हुक प्रत्येक रेफरी अद्यतन किया जा करने के लिए एक बार कार्यान्वित करता है, और तीन पैरामीटर लेता है: रेफरी के नाम अपडेट किया जा रहा, वर्ष ऑब्जेक्ट नाम रेफरी, और नए objectname में संग्रहीत में संग्रहीत करने के लिए रेफरी। " – ordnungswidrig

+0

मैंने @ordnungswidrig संस्करण बनाने का निर्णय लिया - बस "टूटा" संशोधन के कारण प्री-प्रतिबद्ध हुक का उपयोग करें। यहां मेरा संस्करण (php + phpUntit परीक्षण) है:

#!/bin/sh /usr/bin/php /srv/www/wf/tests/run.php /srv/www/wf/tests > /tmp/result if grep 'OK' /tmp/result then exit 0 else echo 'Your tests is failed, you cannot commit' exit 1 fi 
sheepwalker

13

यदि आप कमांड लाइन का उपयोग कर रहे हैं, तो ऐसा करने का सबसे आसान तरीका एक पुश स्क्रिप्ट लिखना है जो आपके यूनिट परीक्षण चलाता है और यदि वे सफल होते हैं, तो पुश पूरा करता है।

संपादित

Git 1.8.2 के रूप में इस उत्तर पुरानी हो चुकी है। ऊपर Manojlds का जवाब देखें।

+0

उपयोग करने के लिए आपको कम से हुक का उपयोग नहीं कर मतलब है ($1 दूरदराज के नाम, $2 URL होता है) सब? बस "गिट पुल" को प्रतिस्थापित करें, उदाहरण के लिए, "git uinttestspull"? यह बिल्कुल ठीक नहीं है कि मुझे – sheepwalker

+1

@sheepwalker: s/pull/push /, और इसे अच्छा और छोटा बनाने के लिए उपनाम का उपयोग करें। – Cascabel

+0

@sheepwalker हाँ, यह वही नहीं है जो आपने पूछा था, लेकिन @calmh की तरह, कोई प्री-पुश हुक नहीं है। – kubi

7

इसके लिए कोई हुक नहीं है, क्योंकि पुश एक ऐसा ऑपरेशन नहीं है जो आपके भंडार को संशोधित करता है।

आप post-receive हुक में प्राप्तकर्ता पक्ष पर चेक कर सकते हैं। यही वह जगह है जहां आप आमतौर पर आने वाले धक्का को अस्वीकार कर देंगे। रनिंग यूनिट परीक्षण एक हुक में करने के लिए थोड़ा गहन हो सकता है, लेकिन यह आपके ऊपर है।

5

रिकॉर्ड के लिए, patch to Git 1.6 that adds a pre-push hook है। मुझे नहीं पता कि यह 1.7 के खिलाफ काम करता है या नहीं।

इसके साथ गड़बड़ की बजाय, आप पुश स्क्रिप्ट जैसे @ कुबी की सिफारिश कर सकते हैं। आप इसके बजाय इसे एक रेक कार्य भी कर सकते हैं ताकि यह आपके रेपो में हो। ruby-git इससे मदद कर सकता है। यदि आप लक्ष्य रेपो की जांच करते हैं, तो आप उत्पादन रेपो को दबाते समय केवल परीक्षण चला सकते हैं।

अंत में, आप अपने परीक्षण pre-commit हुक में चला सकते हैं लेकिन जांचें कि किस शाखा के लिए प्रतिबद्ध किया जा रहा है। फिर आपके पास एक production शाखा हो सकती है, जिसके लिए प्रतिबद्धता स्वीकार करने से पहले सभी परीक्षणों की आवश्यकता होती है लेकिन आपकी master परवाह नहीं है। उस परिदृश्य में limerick_rake उपयोगी हो सकता है।

+0

धन्यवाद, असल में मैंने पहले से ही आखिरी संस्करण चुना है (अंत में, आप अपने प्री-प्रतिबद्ध हुक में अपने परीक्षण चला सकते हैं ..) – sheepwalker

155

गिट 1.8.2 रिलीज में pre-push हुक मिला।

नमूना pre-push स्क्रिप्ट: https://github.com/git/git/blob/87c86dd14abe8db7d00b0df5661ef8cf147a72a3/templates/hooks--pre-push.sample

1.8.2 रिलीज नया पूर्व धक्का हुक के बारे में बात नोट: https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt

+1

अरे दोस्त .. धन्यवाद .. :) –

+0

@manojlds क्या आप जानते हैं कि यह हुक क्या है के लिए इस्तेमाल किया जा सकता है? मैं एक विशिष्ट शाखा को धक्का देकर अपने बाइनरी को अपने ग्राहकों को धक्का देने के लिए इसका उपयोग करना चाहूंगा (यानी रात के संस्करण का निर्माण करें और इसे दबाकर, कर्ल से अपलोड करें)। समस्या यह है कि निर्माण और अपलोड करने में कुछ समय लगता है, और रिमोट कनेक्शन बंद कर देता है। इसलिए मैं अपने बाइनरी के साथ समाप्त हुआ और ग्राहकों को अपलोड किया लेकिन रिपो को धक्का नहीं दिया, क्योंकि रिमोट रेपो कनेक्शन बंद कर देता है। कोई विचार है कि इस के आसपास कैसे काम करें? या शायद यह जड़ में एक बुरा विचार है। – igrek

+0

@igrek क्या आपको कनेक्शन बंद करने के मुद्दे का समाधान मिला? –

17

Git 1.8.2 रिलीज में पूर्व धक्का हुक मिला है।

प्री-पुश हुक जो मुझे पूर्व-प्रतिबद्ध हुक के साथ आवश्यक था। शाखा की सुरक्षा के अलावा, वे पूर्व-प्रतिबद्ध हुक के साथ अतिरिक्त सुरक्षा भी प्रदान कर सकते हैं।

और कैसे (लिया जाता है और अपनाया और this nice entry से बढ़ाया)

सरल उदाहरण का उपयोग करने, आवारा को चलाने परीक्षण और लॉगइन करने के लिए पर एक उदाहरण के लिए तो धक्का

#!/bin/bash 
# Run the following command in the root of your project to install this pre-push hook: 
# cp git-hooks/pre-push .git/hooks/pre-push; chmod 700 .git/hooks/pre-push 

CMD="ssh [email protected] -i ~/.vagrant.d/insecure_private_key 'cd /vagrant/tests; /vagrant/vendor/bin/phpunit'" 
protected_branch='master' 

# Check if we actually have commits to push 
commits=`git log @{u}..` 
if [ -z "$commits" ]; then 
    exit 0 
fi 

current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,') 

if [[ $current_branch = $protected_branch ]]; then 
    eval $CMD 
    RESULT=$? 
    if [ $RESULT -ne 0 ]; then 
     echo "failed $CMD" 
     exit 1 
    fi 
fi 
exit 0 

आप उदाहरण देख सकते हैं प्री-पुश हुक के विषय में संरक्षित शाखा का उपयोग करता है।

0

script linked by the highly-voted answerpre-push hook के मानकों आदि भी दिखाती है कि प्रतिबद्ध (stdin से लाइनों read है संरचना <local ref> <local sha1> <remote ref> <remote sha1>)

#!/bin/sh 

# An example hook script to verify what is about to be pushed. Called by "git 
# push" after it has checked the remote status, but before anything has been 
# pushed. If this script exits with a non-zero status nothing will be pushed. 
# 
# This hook is called with the following parameters: 
# 
# $1 -- Name of the remote to which the push is being done 
# $2 -- URL to which the push is being done 
# 
# If pushing without using a named remote those arguments will be equal. 
# 
# Information about the commits which are being pushed is supplied as lines to 
# the standard input in the form: 
# 
# <local ref> <local sha1> <remote ref> <remote sha1> 
# 
# This sample shows how to prevent push of commits where the log message starts 
# with "WIP" (work in progress). 

remote="$1" 
url="$2" 

z40=0000000000000000000000000000000000000000 

while read local_ref local_sha remote_ref remote_sha 
do 
    if [ "$local_sha" = $z40 ] 
    then 
     # Handle delete 
     : 
    else 
     if [ "$remote_sha" = $z40 ] 
     then 
      # New branch, examine all commits 
      range="$local_sha" 
     else 
      # Update to existing branch, examine new commits 
      range="$remote_sha..$local_sha" 
     fi 

     # Check for WIP commit 
     commit=`git rev-list -n 1 --grep '^WIP' "$range"` 
     if [ -n "$commit" ] 
     then 
      echo >&2 "Found WIP commit in $local_ref, not pushing" 
      exit 1 
     fi 
    fi 
done 

exit 0 
संबंधित मुद्दे