2014-05-09 10 views
6

लगभग सभी परियोजनाओं जिन पर मैंने काम किया है, उनमें कुछ प्रकार की "जमे हुए सामग्री" है जो हमेशा क्लोन होने पर आनी चाहिए, फिर भी शायद ही कभी बदला जाए (उदाहरण के लिए नीचे देखें)। मैंने गिट का उपयोग करके विभिन्न दृष्टिकोणों का प्रयास किया है, लेकिन वे सभी त्रुटि-प्रवण हैं: लोग अकसर गलती से बदलाव करते हैं।गिट - जमे हुए सामग्री को संभालना

यह सुनिश्चित करने के लिए एक सूक्ष्म मामला है: फ़ाइलें/फ़ोल्डर संस्करणीकृत किया जाना चाहिए, लेकिन बदलाव की विशाल बहुमत नहीं धकेल दिया जाना चाहिए।

मैं चारों ओर देख रहे हैं है कुछ विकल्प:

  • git update-index --assume-unchanged <file>: समस्या - इस would appear to be a local setting, तो यह केवल एक दिया मशीन पर समस्या का हल। नए क्लोन भूल जाते हैं और अभी भी दुर्घटना से बदलाव करते हैं।
  • git update-index --skip-worktree <file>: समस्या - के बाद से मैं नहीं लगता सूचकांक को परिवर्तन कभी propogated रहे हैं एक ही मुद्दा है प्रकट होता है,।
  • git rm --cached <file>: समस्या - वास्तव में कोई समाधान नहीं है क्योंकि इस टोस्ट को धक्का देने पर हर किसी की प्रतिलिपि होती है!
  • echo <file> >> .gitignore: समस्या - नहीं वास्तव में एक समाधान है, क्योंकि यह केवल नियंत्रण एक वस्तु है कि क्या रेपो को गयी।
  • काम से फ़ाइल परिवर्तनों को बाहर करने के लिए धुंध/साफ फ़िल्टर का उपयोग करें (देखें jthill's answer): समस्या - जटिल, त्रुटि प्रवण: अभी भी प्रत्येक डेवलपर को स्थानीय रूप से कॉन्फ़िगर करने की आवश्यकता है।

इस प्रश्न का एक स्वीकार्य उत्तर प्रत्येक नए डेवलपर द्वारा विशेष कार्यों की आवश्यकता नहीं है।

क्यों? चूंकि यह उपरोक्त समाधानों के साथ बिल्कुल समस्या है, जो मेरे अनुभव में ऐसी परिस्थितियों की ओर जाता है जहां "किसी ने फिर से वह फ़ाइल की है"।

खोज आसानी से कई प्रश्नों को चालू करती है। हमें अंतिम जवाब चाहिए!

उदाहरण:

+०१२३५१६४१०

यहां मामला है कि मैं एटीएम से निपट रहा हूं। मेरी परियोजना एक ऐसी वेबसाइट है जो विकी सॉफ़्टवेयर को एम्बेड करती है (जिसे मैंने नहीं लिखा था)। विकी घटक को एक गैर-तुच्छ फ़ोल्डर संरचना की आवश्यकता होती है जिसका उपयोग डेटाबेस की तरह किया जाता है (शायद एक होना चाहिए)। इसे काम करने के लिए पहले से मौजूद फ़ोल्डर और फ़ाइलों को खोजने की जरूरत है। थोड़ी देर के बाद ये फ़ाइलें बड़ी हो जाती हैं - हम उन परिवर्तनों को ट्रैक नहीं करना चाहते हैं! इस फ़ोल्डर संरचना में कुछ कॉन्फ़िगरेशन भी शामिल हैं (मुझे पता है)।अगर मैं रेपो में नंगे प्रतिलिपि शामिल कर सकता हूं, और किसी भी तरह (लगभग) कभी भी अपने परिवर्तनों को ट्रैक नहीं करता है, तो यह सही होगा।

+1

क्या आप "जमे हुए सामग्री" के बारे में कुछ और जानकारी दे सकते हैं? क्या आप विन्यास फाइलों के बारे में बात कर रहे हैं? डाटाबेस फिक्स्चर? कुछ और? – Chris

+1

महान प्रश्न (और अच्छे शोध प्रयास)। यह वास्तव में एक गिट अकसर किये गए सवाल है, और एक कैनोलिक जवाब के हकदार है। – sleske

+0

@Chris - फ़ोल्डर/फ़ाइलों का कुछ विवरण जोड़ा गया। –

उत्तर

3

यह वास्तव में स्पष्ट नहीं है कि आप किस प्रकार की फाइलों के बारे में बात कर रहे हैं।

  1. समझदार चूक, उदा के साथ एक नमूना विन्यास फाइल प्रतिबद्ध:

    विन्यास फाइल के मामले में, मैं हमेशा निम्नलिखित दृष्टिकोण की सिफारिश config.sample.ini

  2. गैर-नमूना फ़ाइल को अनदेखा करें, उदा। config.ini
  3. नई मशीनों पर "स्टार्ट अप" प्रक्रिया के हिस्से के रूप में, config.sample.ini फ़ाइल को config.ini पर कॉपी किया जाना चाहिए और अनुकूलित किया जाना चाहिए। इस प्रक्रिया को अपने रीडमे, या विकी, या कहीं भी दस्तावेज करें।
  4. सुनिश्चित करें कि आपका कोड "ठीक से विफल हो जाता है" अगर कॉन्फ़िगरेशन फ़ाइल गुम है, उदा। जब सॉफ़्टवेयर शुरू होता है तो यह तुरंत त्रुटि हो जाएगा "config.ini नहीं मिला। क्या आपने नमूना फ़ाइल कॉपी की है?"

यह सुनिश्चित करता है कि नमूना फ़ाइल को आसानी से अपडेट किया जा सके। यह सुनिश्चित करता है कि कॉन्फ़िगरेशन फ़ाइल प्रतिबद्ध नहीं है। यदि यह गलत हो जाता है तो यह जल्दी से विफल हो जाता है। और यह लागू करने के लिए अपेक्षाकृत सरल है।

तेज़ तरीका होता नजरअंदाज कर दिया config.ini को एक प्रतिबद्ध config.ini से प्राप्त करने के लिए और एक प्रतिबद्ध config.sample.ini तरह

git mv config.ini config.sample.ini 
echo config.ini >> .gitignore 
git commit -a -m "Replace config file with sample config file" 

अद्यतन कुछ करने की संभावना है:

आपका विकी उदाहरण एक दिलचस्प एक है।

आप सही है कि .sample फ़ाइलों की एक गहरी पेड़ प्रबंधन करने के लिए मुश्किल होगा रहे हैं, लेकिन आप एक ज़िप फ़ाइल या टारबॉल के साथ एक ही प्रभाव प्राप्त कर सकते हैं:

  1. एक संग्रह है कि करने के लिए प्रतिबद्ध हो जाएगा बनाएं भंडार जिसमें आपकी मूल विकी सामग्री है, उदाहरण के लिए wiki.zip
  2. निर्देशिका को अनदेखा करें जहां विकी निकाली जाएगी, उदा। path/to/wiki-root
  3. अपने दस्तावेज़ में "unzip -d path/to/wiki-root के साथ विकी निकालें" जोड़ें। यह अब आपके इंस्टॉल/तैनाती प्रक्रिया का हिस्सा है।

अब आप आवश्यकतानुसार ज़िप फ़ाइल को अपडेट कर सकते हैं और उन परिवर्तनों को कर सकते हैं, जबकि निकाली गई फ़ाइलों में परिवर्तनों को अनदेखा करते समय।

+0

हां, इस तरह मैंने इसे हमेशा भी देखा है। ओपी की समस्या वास्तव में यह है कि एक फ़ाइल दो भूमिकाओं की सेवा कर रही है: कॉन्फ़िगरेशन टेम्पलेट, और कॉन्फ़िगरेशन फ़ाइल। अलग फाइलें रखना सबसे साफ समाधान है। – sleske

+0

मुझे वह दृष्टिकोण पसंद है। मेरे प्रश्न के निचले भाग में जो उदाहरण जोड़ा गया है उसे देखें (यह वही है जो मैं वास्तव में सामना कर रहा हूं)। शायद मैं पूरे फ़ोल्डर संरचना को टेम्पलेट के रूप में डुप्लिकेट कर सकता हूं, लेकिन यह अत्यधिक लगता है। –

+0

@EdwardNewell कृपया मेरे अपडेट किए गए उत्तर को देखें। – Chris

3

AFAIK, रेपो के प्रत्येक क्लोन में स्वैच्छिक कार्रवाई के बिना "इसे न बदलें" नीति को लागू करने का एकमात्र तरीका है उनके लिए server-side hook इंस्टॉल करना। एक पूर्व-प्राप्त हुक एक जमे हुए फ़ाइल में परिवर्तन के लिए आने वाली प्रतिबद्धताओं का निरीक्षण कर सकता है और उन्हें अस्वीकार कर सकता है (जब तक कि प्रतिबद्ध संदेश कुछ जादू पैटर्न से मेल नहीं खाता है)।

सर्वर-साइड हुक केवल केंद्रीय रिपो को नियंत्रित करते समय काम करते हैं, यानी यह गिटहब या ऐसी कुछ सेवा पर नहीं हो सकता है।

+0

आह, एक करीबी याद आती है। यह बहुत बुरा है कि हम इसका उपयोग जिथूब के लिए नहीं कर सकते। फिर भी, यह कई लोगों की मदद करेगा। –

1

रूप <proj-root>/.git/hooks/pre-commit

#!/bin/sh 

numFilesToVerify=0 
IFS=$'\n' 

for l in `git diff --name-only --cached`; do 
    while read m; do 
     [[ $l == $m ]] && verify="$verify"`echo " * $l"`$'\n' && ((numFilesToVerify++)) 
    done < .gitverify 
done 

if [ $numFilesToVerify -gt 0 ]; then 
    echo "\nYou're changing $numFilesToVerify frozen files:"; 
    echo "$verify" 
    read -p "Do you know what you're doing? (yes/no): " reply < /dev/tty 
    if [ "$reply" != "yes" ]; then 
     echo 'commit aborted.' 
     exit 1; 
    fi 
fi 

unset IFS 

अपनी परियोजना में निम्न फ़ाइल रखो तो फाइल या निर्देशिका आप फ़ाइल <proj-root>/.gitverify में फ्रीज करना चाहते हैं की सूची। * वाइल्डकार्ड का उपयोग अगर आप चाहते हैं:

testdir/test* 

यहाँ अगर मैं फ़ाइलों में परिवर्तन करने की कोशिश करते हैं tesdir/test और testdir/test2

$ git commit -m 'test' 
You're changing 2 frozen files: 
* testdir/test 
* testdir/test2 

Do you know what you're doing? (yes/no): no 
commit aborted. 

लाभ क्या होता है:

  • मैं आसानी से जोड़ सकते हैं/फ्रीज सूची से फ़ाइलों को हटाएं
  • यदि एक टैर का हिस्सा अपडेट करना (क्रिस का जवाब देखें) एक भाग संख्या को ओवरराइट करने का अनुमान है टी बदलने के इरादे से। यहां कोई टैर की आवश्यकता नहीं है, और यह आपको बताता है कि आप क्या कर रहे हैं।
  • सर्वर साइड हुक का उपयोग नहीं करता है, इसलिए एक्सेस के साथ कोई समस्या नहीं है या एकाधिक रिमोट नहीं हैं।
+1

यह एक दिलचस्प समाधान है, लेकिन क्या यह आपके "इस प्रश्न के स्वीकार्य उत्तर को प्रत्येक नए डेवलपर द्वारा विशेष कार्यों की आवश्यकता नहीं है" की आवश्यकता नहीं है? मैं काफी हद तक निश्चित हूं कि प्रत्येक उपयोगकर्ता को क्लोनिंग के बाद मैन्युअल रूप से इस हुक को सेट करना होगा, क्योंकि हुक रिपोजिटरी का हिस्सा नहीं हैं। – Chris

+0

@ क्रिस डारन! मुझे लगा कि वे थे। –

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