Git - 'ग्रहण-अपरिवर्तित' और 'स्किप-वर्कट्री' के बीच अंतर


450

मेरे पास एक फ़ाइल में स्थानीय परिवर्तन हैं जिन्हें मैं अपने भंडार के लिए प्रतिबद्ध नहीं करना चाहता। यह सर्वर पर एप्लिकेशन के निर्माण के लिए एक कॉन्फ़िगरेशन फ़ाइल है, लेकिन मैं विभिन्न सेटिंग्स के साथ स्थानीय रूप से निर्माण करना चाहता हूं। स्वाभाविक रूप से, फ़ाइल हमेशा दिखाई देती है जब मैं 'git स्टेटस' करता हूं कि कुछ का मंचन किया जाए। मैं इस विशेष परिवर्तन को छिपाना चाहूंगा और इसे कमिट नहीं करूंगा। मैं फ़ाइल में कोई अन्य परिवर्तन नहीं करूँगा।

आसपास कुछ खोदने के बाद, मुझे 2 विकल्प दिखाई देते हैं: 'ग्रहण-अपरिवर्तित' और 'स्किप-वर्कट्री'। एक पिछले प्रश्न यहाँ उनके बारे में बात करती है, लेकिन वास्तव में अपने मतभेदों की व्याख्या नहीं करता। मेरा प्रश्न यह है: दोनों आज्ञाएँ कैसे भिन्न हैं? कोई एक या दूसरे का उपयोग क्यों करेगा?


1
आमतौर पर मैं .gitignoreइसी तरह के उद्देश्यों के लिए उपयोग कर रहा हूं । क्या यह समाधान आपके लिए काम करेगा?
samuil

45
samuil, .gitignore जोड़ने, न बदलने पर ध्यान नहीं देता। जब फ़ाइल पहले से ही git में है तो इसे ईवेंट में ट्रैक किया जाएगा यदि इसे .gitignore में सूचीबद्ध किया गया है
Grigory

लेकिन कोई भी सभी को हटा नहीं सकता है और यहां बताए अनुसार "ताज़ा" करने के लिए सभी को जोड़ सकता है? stackoverflow.com/questions/7075923/… @Grigory
डैनियल स्प्रिंगर

2
अगर मुझे ओपी की मंशा सही लगती है, तो फाइल को नजरअंदाज नहीं किया जाना चाहिए। फ़ाइल रिपॉजिटरी में होनी चाहिए, लेकिन उसके द्वारा किए गए ये बहुत विशिष्ट परिवर्तन प्रतिबद्ध नहीं होने चाहिए - अभी नहीं, कम से कम।
सिमोन

जवाबों:


666

आप चाहते हैं skip-worktree

assume-unchangedउन मामलों के लिए डिज़ाइन किया गया है जहाँ यह जाँचना महंगा है कि क्या फाइलों के एक समूह को संशोधित किया गया है; जब आप बिट git(निश्चित रूप से) सेट करते हैं, तो अनुक्रमणिका के उस हिस्से के अनुरूप फाइलों को काम की प्रतिलिपि में संशोधित नहीं किया गया है। तो यह statकॉल की गड़बड़ी से बचा जाता है । जब भी सूचकांक में फ़ाइल की प्रविष्टि बदलती है (तो, जब फ़ाइल को ऊपर की ओर बदल दिया जाता है) तो यह बिट खो जाता है।

skip-worktreeइससे अधिक है: यहां तक ​​कि जहां git यह भी पता है कि फ़ाइल को संशोधित किया गया है (या इसे एक reset --hardतरह से संशोधित करने की आवश्यकता है ), यह दिखावा करेगा कि यह नहीं किया गया है, बल्कि सूचकांक से संस्करण का उपयोग कर रहा है। यह तब तक बनी रहती है जब तक कि सूचकांक को छोड़ नहीं दिया जाता।

इस अंतर और यहां उपयोग के विशिष्ट मामलों के प्रभाव का एक अच्छा सारांश है: http://fallengamer.livejournal.com/93321.html

उस लेख से:

  • --assume-unchangedमानता है कि एक डेवलपर को फ़ाइल नहीं बदलनी चाहिए । यह ध्वज SDKs जैसे बदलते फ़ोल्डर के लिए प्रदर्शन में सुधार के लिए है।
  • --skip-worktreeजब आप किसी विशिष्ट फ़ाइल को कभी नहीं छूने का निर्देश देते हैं तो उपयोगी होता है क्योंकि डेवलपर्स को इसे बदलना चाहिए । उदाहरण के लिए, यदि मुख्य भंडार नदी के ऊपर मेजबान कुछ उत्पादन के लिए तैयार विन्यास फाइल और अगर आप गलती से उन फ़ाइलों में परिवर्तन के लिए प्रतिबद्ध नहीं करना चाहते, --skip-worktreeवास्तव में आप क्या चाहते है।

3
यह समझ आता है। स्किप-वर्कट्री वास्तव में जाने का रास्ता प्रतीत होता है। धन्यवाद!
17:20 बजे ckb

100
खोज और पढ़ने के लिए कुछ सेकंड बचाने के लिए एक छोटा सा नोट। --skip-worktreeप्रभावों को रद्द करने और झंडे को उतारने का --no-skip-worktreeविकल्प है। ठीक उसी तरह काम करता है। यह उस स्थिति में उपयोगी है जब एक हाथ फिसल गया था और गलत फाइलें झंडी दे दी गई थीं, या यदि परिस्थितियां बदल गई थीं और पहले से छोड़ी गई फ़ाइलों को अब अनदेखा नहीं किया जाना चाहिए।
ड्रगमैन

18
ऊपर मेरे अपने प्रश्न का उत्तर देने के लिए, उपयोग करने --skip-worktreeऔर .git/info/excludeफ़ाइल के बीच का अंतर यह है कि पूर्व उन फ़ाइलों के लिए भी काम करेगा जो वर्तमान में ट्रैक हैं। .git/info/exclude, जैसे .gitignore, केवल अनजाने फ़ाइलों को अनुक्रमणिका में गलती से जोड़ने से रोकेंगे, लेकिन पहले से ट्रैक की गई फ़ाइलों में परिवर्तन नहीं कर रहे हैं।
लिनसआर

13
क्या इसे रिमोट में धकेला जा सकता है और सभी क्लोन द्वारा संरक्षित किया जा सकता है?
CMCDragonkai

4
बस उपयोग , मैम:git update-index --skip-worktree <file_name>
ruffin

108

नोट: फ़ेलेंगैमेर ने 2011 में कुछ परीक्षण किए थे (इसलिए वे पुराने हो सकते हैं), और यहाँ उनके निष्कर्ष हैं :

संचालन

  • फ़ाइल को स्थानीय रिपॉजिटरी और अपस्ट्रीम दोनों में बदल दिया जाता है
    git pull:
    Git वैसे भी स्थानीय परिवर्तनों को संरक्षित करता है।
    इस प्रकार आप गलती से किसी भी डेटा को नहीं खोएंगे जिसे आपने किसी भी झंडे के साथ चिह्नित किया है।
    • assume-unchangedध्वज के साथ फ़ाइल : Git स्थानीय फ़ाइल को अधिलेखित नहीं करेगा। इसके बजाय यह संघर्ष और सलाह देता है कि उन्हें कैसे हल किया जाए
    • skip-worktreeध्वज के साथ फ़ाइल : Git स्थानीय फ़ाइल को अधिलेखित नहीं करेगा। इसके बजाय यह संघर्ष और सलाह देता है कि उन्हें कैसे हल किया जाए

  • फ़ाइल को स्थानीय रिपॉजिटरी और अपस्ट्रीम दोनों में बदल दिया जाता है, वैसे भी कुछ अतिरिक्त मैनुअल काम में परिणाम का उपयोग करने की कोशिश कर रहा है, लेकिन यदि आपके पास कोई स्थानीय परिवर्तन है तो कम से कम आप किसी भी डेटा को नहीं खोएंगे।
    git stash
    git pull
    skip-worktree
    • assume-unchangedध्वज के साथ फ़ाइल : उन्हें पुनर्स्थापित करने के लिए किसी भी संभावना के बिना सभी स्थानीय परिवर्तनों को त्यागता है। प्रभाव ' git reset --hard’ जैसा है । ' git pull' कॉल सफल होगा
    • skip-worktreeझंडे के साथ फाइल : skip-worktreeफाइलों पर काम नहीं करेगा । ' git pull' ऊपर के रूप में एक ही त्रुटि के साथ विफल हो जाएगा। डेवलपर को मैन्युअल रूप से skip-worktreeध्वज को रीसेट करने और असफल होने को पूरा करने में सक्षम होने के लिए मजबूर किया जाता है pull

  • कोई स्थानीय परिवर्तन, अपस्ट्रीम फ़ाइल नहीं बदली, दोनों झंडे आपको अपस्ट्रीम परिवर्तन प्राप्त करने से नहीं रोकेंगे। गिट पता लगाता है कि आपने ध्वज को रीसेट करके वास्तविकता को प्रतिबिंबित करने के लिए वादा और धोखा दिया ।
    git pull
    assume-unchanged
    • assume-unchangedध्वज के साथ फ़ाइल : सामग्री अपडेट की गई है, ध्वज खो गया है।
      ' git ls-files -v' यह दर्शाता है कि ध्वज को H(से h) संशोधित किया गया है ।
    • skip-worktreeध्वज के साथ फ़ाइल : सामग्री अपडेट की गई है, ध्वज संरक्षित है।
      ' git ls-files -v' Sपहले जैसा ही झंडा दिखाएगा pull

  • स्थानीय फ़ाइल परिवर्तित के साथ Git फ़ाइल को स्पर्श नहीं करता है और वास्तविकता को दर्शाता है (फ़ाइल के अपरिवर्तित होने का वादा किया गया फ़ाइल के लिए) ।
    git reset --hard
    skip-worktreeassume-unchanged
    • assume-unchangedझंडे के साथ फ़ाइल : फ़ाइल की सामग्री वापस आ गई है। ध्वज को H(से h) पर रीसेट कर दिया गया है ।
    • skip-worktreeध्वज के साथ फ़ाइल : फ़ाइल सामग्री बरकरार है। झंडा वही रहता है।

वह निम्नलिखित विश्लेषण जोड़ता है:

  • ऐसा लगता है कि skip-worktreeहै आपके स्थानीय डेटा को बचाने के लिये बहुत मेहनत की कोशिश कर रहा । लेकिन अगर यह सुरक्षित है तो यह आपको अपस्ट्रीम में बदलाव करने से नहीं रोकता है। प्लस git ध्वज को रीसेट नहीं करता है pull
    लेकिन ' reset --hard' कमांड को नजरअंदाज करना एक डेवलपर के लिए एक आश्चर्यजनक आश्चर्य बन सकता है।

  • Assume-unchangedफ्लैग को pullऑपरेशन में खो दिया जा सकता है और ऐसी फाइलों के अंदर स्थानीय परिवर्तन महत्वपूर्ण नहीं लगता है।

देख:

वह निष्कर्ष निकालता है:

वास्तव में दोनों में से कोई भी ध्वज पर्याप्त सहज नहीं है

  • assume-unchangedमानता है कि एक डेवलपर को फ़ाइल नहीं बदलनी चाहिए। यदि कोई फ़ाइल बदली गई थी - तो वह परिवर्तन महत्वपूर्ण नहीं है। यह ध्वज SDKs जैसे बदलते फ़ोल्डर के लिए प्रदर्शन में सुधार के लिए है।
    लेकिन अगर वादा टूट गया है और एक फाइल वास्तव में बदल गई है, तो वास्तविकता को प्रतिबिंबित करने के लिए git ध्वज को बदल देता है। संभवतः आमतौर पर नहीं बदले जाने वाले फ़ोल्डरों में कुछ असंगत झंडे होना ठीक है।

  • skip-worktreeजब आप गिट को एक विशिष्ट फ़ाइल को कभी नहीं छूने का निर्देश देते हैं तो दूसरी ओर उपयोगी होता है। यह पहले से ट्रैक की गई कॉन्फिग फ़ाइल के लिए उपयोगी है।
    अपस्ट्रीम मुख्य रिपॉजिटरी कुछ उत्पादन-तैयार कॉन्फ़िगरेशन को होस्ट करती है, लेकिन आप कुछ स्थानीय परीक्षण करने में सक्षम होने के लिए कॉन्फ़िगरेशन में कुछ सेटिंग्स बदलना चाहेंगे। और आप गलती से उत्पादन विन्यास को प्रभावित करने के लिए ऐसी फ़ाइल में परिवर्तनों की जांच नहीं करना चाहते हैं। उस मामले में skip-worktreeसही दृश्य बनाता है।


Git 2.25.1 (फरवरी 2020) के साथ, "वास्तव में न तो झंडे बहुत सहज हैं" जैसा कि ऊपर वर्णित है, आगे स्पष्ट किया गया है:

देखें 7a2dc95 , 1b13e90 (22 जनवरी 2020) को brian मी। कार्लसन ( bk2204)
(द्वारा विलय Junio सी Hamano - gitster- में प्रतिबद्ध 53a8329 , 30 जनवरी 2020)
( Git मेलिंग सूची )

doc: ट्रैक की गई फ़ाइलों को अनदेखा करने का प्रयास करने से उपयोगकर्ताओं को मना करें

साइन-ऑफ-बाय: जेफ किंग
साइन-ऑफ-बाय: ब्रायन एम। कार्लसन

यह उपयोगकर्ताओं के लिए काफी सामान्य है कि वे किसी फ़ाइल के परिवर्तनों को अनदेखा करना चाहते हैं जो Git को ट्रैक करता है।

इस मामले के लिए सामान्य परिदृश्य आईडीई सेटिंग्स और कॉन्फ़िगरेशन फाइलें हैं, जिन्हें आमतौर पर ट्रैक नहीं किया जाना चाहिए और संभवतः टेम्पर्ड तंत्र का उपयोग करके ट्रैक की गई फ़ाइलों से उत्पन्न होता है।

हालांकि, उपयोगकर्ता मान-अपरिवर्तित और स्किप-वर्कट्री बिट्स के बारे में सीखते हैं और वैसे भी ऐसा करने के लिए उनका उपयोग करने का प्रयास करते हैं।

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

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

चूंकि यह एक समर्थित कॉन्फ़िगरेशन नहीं है और उपयोगकर्ता अनपेक्षित उद्देश्यों के लिए मौजूदा सुविधाओं का दुरुपयोग करने के लिए प्रवण हैं, जिससे सामान्य उदासी और भ्रम पैदा होता है , आइए दस्तावेज़ में मौजूदा व्यवहार और नुकसान का दस्तावेजीकरण करें git update-indexताकि उपयोगकर्ताओं को पता चले कि उन्हें वैकल्पिक समाधानों का पता लगाना चाहिए।

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

git update-indexआदमी पेज अब में शामिल हैं:

उपयोगकर्ता अक्सर ट्रैक की जाने वाली फ़ाइलों में परिवर्तनों को अनदेखा करने के लिए गिट को बताने के लिए बिट्स assume-unchangedऔर skip-worktreeबिट्स का उपयोग करने का प्रयास करते हैं। यह अपेक्षित रूप से काम नहीं करता है, क्योंकि Git अभी भी कुछ ऑपरेशन करते समय इंडेक्स के खिलाफ कार्यशील ट्री फ़ाइलों की जांच कर सकता है। सामान्य तौर पर, गिट ट्रैक की गई फ़ाइलों में परिवर्तन को अनदेखा करने का एक तरीका प्रदान नहीं करता है, इसलिए वैकल्पिक समाधानों की सिफारिश की जाती है।

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

वह अंतिम भाग वह है जो मैं स्मूद / क्लीन स्क्रिप्ट के आधार पर एक विशिष्ट सामग्री फिल्टर ड्राइवर का वर्णन करता हूं ।


8
यदि आपके पास फ़ाइल और अपस्ट्रीम परिवर्तनों पर स्किप-वर्कट्री है, तो जब आप खींचने की कोशिश करते हैं, तो आपको "प्लीज कमिट या स्टैश" मिलता है, भले ही गिट स्टेटस फ़ाइल को बदले जाने की सूचना न दे। आप इससे कैसे बच सकते हैं, इसलिए स्थानीय परिवर्तन जारी रह सकते हैं जबकि लोग मूल पर उत्पादन सेटिंग्स के साथ घूम रहे हैं?
ग्रीनएजजडे

3
हां, मैं पुष्टि कर सकता हूं कि आप करते हैं। इसका मतलब है कि अभी भी स्थानीय फ़ाइल रखना बहुत मुश्किल है जिसे आप मूल रूप से अलग तरह से बनाए रखना चाहते हैं।
ग्रीनएजजडे

1
@GreenAsJade प्राचीन लगता है। कोई भी मौका आप इसे 2.2.x के साथ परीक्षण कर सकते हैं?
VonC

1
@VonC, "जूनियो की टिप्पणी" का लिंक संशोधन इतिहास में नहीं है। है यह क्या आप की बात कर रहे थे?
माइकल - जहां

1
@ मिचेल अच्छा कैच, धन्यवाद। मैंने जवाब में उस लिंक को वापस डाल दिया है।
VonC
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.