2010-10-21 11 views
16

मैं अपने रिमोट रिपोजिटरी को किसी भी धक्का को अस्वीकार करने के लिए चाहता हूं जिसमें एक टैब है जिसमें फ़ाइल है, लेकिन केवल तभी फ़ाइल एक निश्चित वर्ग (फ़ाइल नाम के आधार पर) में संबंधित है। क्या यह संभव है?
मैंने गिटूक में update hook पर थोड़ा सा देखा है, और मुझे लगता है कि यह सही है।कुछ फ़ाइलों में टैब युक्त गिट को रोकें (उदाहरण के लिए * .cpp, * .h, CMakeLists.txt)

  1. वहाँ सूचीबद्ध प्रकार (*.cpp, *.h, CMakeLists.txt)
  2. जो एक या अधिक टैब वर्ण हैं की एक फ़ाइल है:

    तो संक्षेप में, एक धक्का है, तो अस्वीकार कर दिया जाना चाहिए।

+0

क्या आप हुक लिखने में मदद मांग रहे हैं, या इस उद्देश्य के लिए एक अद्यतन हुक काम करेगा या नहीं? – Cascabel

+0

वास्तव में दोनों :) मैं बहुत हैरान था कि यह आसानी से खोजने योग्य और डाउनलोड करने योग्य नहीं था, इसलिए मुझे लगता है कि यह गैर-तुच्छ है। इस तरह का एक हुक कैसे दिख सकता है इसका एक उदाहरण बहुत मदद करेगा। –

उत्तर

15

ओह ओह, यह प्रश्न दरारों के माध्यम से फिसल गया प्रतीत होता है। आशा है कि आप अभी भी वहां हैं, एस्बेन!

आप update hook की तलाश में हैं, जो प्रत्येक रेफरी अपडेट के लिए एक बार चलाया जाता है। तर्क रेफरी का नाम है, पुराना ऑब्जेक्ट नाम (SHA1 प्रतिबद्ध करें), और नया ऑब्जेक्ट नाम।

तो, आपको बस इतना करना है कि पुराने और नए के बीच अंतर की जांच करें और सुनिश्चित करें कि यह आपके मानकों को पूरा करता है। यह बिल्कुल पूरी तरह से सरल नहीं है, लेकिन यह पूरी तरह से प्रबंधनीय है। यहां मैं क्या करूँगा:

निम्न स्क्रिप्ट को .git/hooks/update पर सहेजें।

old=$2 
new=$3 

# that's a literal tab, because (ba)sh turns \t into t, not a tab 
# make sure your editor doesn't expand it to spaces 
git diff --name-only $old $new | egrep '(\.(cpp|h)$)|^CMakeLists.txt$' | xargs -d'\n' git diff -U0 $old $new -- | grep -q '^+.* ' && exit 1 

सभी फाइलों को जो पुराने और नए, सभी वांछित लोगों के लिए greps के बीच भिन्न सूचीबद्ध करता है यही कारण है, (, संदर्भ से शून्य लाइनों के साथ के बाद से हम परवाह नहीं है) उनके लिए diff हो जाता है, और के लिए greps एक जोड़ा लाइन (+ से शुरू) जिसमें एक टैब है। Grep सफलता प्राप्त करता है अगर इसे एक पाता है, जो && रन exit 1 चलाएगा, जिससे हुक विफलता से बाहर निकलने और अपडेट को रद्द कर देगा!

ध्यान दें कि यह आपकी आवश्यकताओं से थोड़ा अलग है - यह जांचता है कि diff कोई टैब वर्ण जोड़ता है या नहीं। यह लंबे समय तक शायद बेहतर है; एक बार जब आप सुनिश्चित कर लें कि आपका मौजूदा कोड ठीक है, तो यह वही बात है, जो बहुत तेज़ी से छोड़कर है क्योंकि इसे सभी सामग्री को खोजना नहीं है।

+0

यह सही है। मैं वास्तव में अपना समाधान अपलोड करने के लिए यहां वापस आ रहा था, और यह बहुत करीब है ... सिवाय इसके कि मैं फ़ाइल प्रकारों को फ़िल्टर करने के लिए - $ (git ls-files ....) का उपयोग करता हूं। यह देखने के लिए एक बहुत ही आराम है कि मेरा समाधान विशेषज्ञों से मेल खाता है :) –

+0

मैंने अभी इस प्रतिबद्धता के साथ प्रयास किया है जिसमें कोई * .cpp, * .h या CMakeLists.txt नहीं है (केवल कुछ यादृच्छिक .txt किसी अन्य नाम के साथ)। xargs फिर 'git diff -U0 $ पुराना $ नया -' निष्पादित करता है जो पूरी प्रतिबद्धता को अलग करता है। Xargs कमांड को खाली इनपुट पर निष्पादित करने से रोकने के लिए: 'xargs -r -d' \ n 'git diff -U0 $ पुराना $ नया -' होना चाहिए। – ancow

3

आप pre-push hook सेट कर सकते हैं, लेकिन यह वास्तव में गिट प्रकाशन तंत्र की भावना में नहीं है।

मैं नहीं बल्कि साथ जाना होगा:,

  • एक pre-commit hook रोकने किसी भी गलत सामग्री
  • या एक filter driver कि आप आसानी से फ़ाइल सही प्रकार के साथ संबद्ध कर सकते हैं के साथ प्रतिबद्ध है, और जो ठीक करने या रिपोर्ट कर सकते हैं कोई अनुचित सामग्री।
+0

इस मामले में, ऐसा लगता है कि ओपी प्री-पुश हुक की तुलना में अपडेट हुक चाहता है; यदि यह सार्वजनिक रिपो से खराब सामग्री को रखने के बारे में है, तो संभवतया आप सही तरीके से स्थापित करने वाले डेवलपर्स पर भरोसा करने के बजाय केंद्रीय रेपो पर एक रोडब्लॉक डालना चाहते हैं। हालांकि, मैं पूर्व-प्रतिबद्ध हुक पर आपके साथ हूं। जब मैं प्रकाशित करता हूं, तब से मैं अपने कोड के साथ कोई समस्या महसूस करता हूं। – Cascabel

+0

@ जेफ्रोमी: सहमत हुए। मुझे विकास जीवन चक्र में पहले समस्याओं का पता लगाना बेहतर लगता है;) – VonC

+0

मैंने पहले ही प्री-प्रतिबद्ध हुक लिखा है। लेकिन वह अपेक्षाकृत आसान था; अद्यतन हुक अधिक जटिल लगता है। सही दिशा क्या हो सकती है इसका एक उदाहरण बहुत सराहना की जाएगी। और हाँ, मैं दोनों का इरादा रखना चाहता हूं: देवताओं की मदद करने के लिए पूर्व-प्रतिबद्धता स्वयं को एक दूसरे के खिलाफ मदद करने के लिए अद्यतन करें। देव चाहता था कि टैब में पहले से ही एक स्क्रिप्ट है जिसे वह चेकआउट/प्रतिबद्धता पर आगे और आगे बदलने के लिए उपयोग करता है। –

1

benprew's काम के आधार पर, यहां एक प्री-स्क्रिप्ट हुक है जो किसी भी टैब वर्ण जोड़े जाने पर एक त्रुटि प्रदर्शित करता है, साथ ही संबंधित पंक्ति संख्या भी। निम्नलिखित को .git/hooks/pre-commit पर सहेजें।

(नोट: pre-commit फ़ाइल नाम है।कोई . विस्तार नहीं होना चाहिए)

#!/bin/sh 

if git rev-parse --verify HEAD 2>/dev/null 
then 
    git diff-index -p -M --cached HEAD 
else 
    : 
fi | 
perl -e ' 
    my $found_bad = 0; 
    my $filename; 
    my $reported_filename = ""; 
    my $lineno; 
    sub bad_line { 
     my ($why, $line) = @_; 
     if (!$found_bad) { 
      print STDERR "*\n"; 
      print STDERR "* You have some suspicious patch lines:\n"; 
      print STDERR "*\n"; 
      $found_bad = 1; 
     } 
     if ($reported_filename ne $filename) { 
      print STDERR "* In $filename\n"; 
      $reported_filename = $filename; 
     } 
     print STDERR "* $why (line $lineno)\n"; 
     print STDERR "$filename:$lineno:$line\n"; 
    } 
    while (<>) { 
     if (m|^diff --git a/(.*) b/\1$|) { 
      $filename = $1; 
      next; 
     } 
     if (/^@@ -\S+ \+(\d+)/) { 
      $lineno = $1 - 1; 
      next; 
     } 
     if (/^ /) { 
      $lineno++; 
      next; 
     } 
     if (s/^\+//) { 
      $lineno++; 
      chomp; 
      if (/ /) { 
       bad_line("TAB character", $_); 
      } 
     } 
    } 
    exit($found_bad); 
' 

यह बिल्कुल आप के बाद से यह किसी भी फ़ाइल नाम की जाँच नहीं करता है के लिए क्या नहीं कहा है, लेकिन उम्मीद है कि यह परवाह किए बिना मदद करता है।

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