11 पॉइंट द्वारा GN⁺ 4 시간 전 | 3 टिप्पणियां | WhatsApp पर शेयर करें
  • Git की फ़ाइल ignore rules साझा दायरे के आधार पर तीन स्तरों में बँटी होती हैं: .gitignore, .git/info/exclude, ~/.config/git/ignore
  • .gitignore repository code के साथ commit होती है, इसलिए यह उन shared rules के लिए सही जगह है जिन्हें टीम या प्रोजेक्ट में सभी पर लागू होना चाहिए
  • personal files या local work files जैसी चीज़ें, जो repository में ज़रूरी तो हैं लेकिन उन्हें टीम rule बनाना उपयुक्त नहीं है, उन्हें .git/info/exclude में रखना बेहतर है
  • macOS की .DS_Store जैसी फ़ाइलें जिन्हें हर repository में बार-बार exclude करना हो, उन्हें machine-wide ignore file ~/.config/git/ignore में रखा जा सकता है
  • git check-ignore -v <फ़ाइलनाम> यह पता लगाने में उपयोगी है कि कौन-सा rule किसी फ़ाइल को ignore कर रहा है, और अगर कोई matching rule नहीं है तो कोई output नहीं आता

Git ignore rules कहाँ लागू होती हैं

  • Git फ़ाइल ignore rules को तीन जगहों से process कर सकता है
    • .gitignore
    • .git/info/exclude
    • ~/.config/git/ignore

.gitignore: repository में commit होने वाले shared rules

  • .gitignore ignore की जाने वाली filenames लिखने की सामान्य फ़ाइल है
  • यह बाकी code के साथ Git में check in होती है
  • .gitignore rules से match होने वाली फ़ाइलें git commands चलाते समय consider नहीं की जातीं

.git/info/exclude: repository-विशिष्ट personal rules

  • exclude फ़ाइल हर Git repository की .git directory के अंदर होती है
  • इस फ़ाइल में किए गए बदलाव Git में check in नहीं होते
  • नई Git repository में इसमें आमतौर पर कुछ lines of comments होती हैं
  • यह उन फ़ाइलों के लिए उपयुक्त है जिन्हें आप सिर्फ़ उसी repository में ignore करना चाहते हैं, लेकिन .gitignore में नहीं जोड़ना चाहते
    • उदाहरण: अगर आप अपने personal workflow के लिए ज़रूरी notes.txt को repository में commit नहीं करना चाहते, और उसे प्रोजेक्ट की .gitignore में भी नहीं जोड़ना चाहते, तो .git/info/exclude में notes.txt जोड़ सकते हैं

~/.config/git/ignore: machine-wide rules

  • global ignore फ़ाइल home directory के ~/.config/git/ignore में होती है
  • यहाँ जो filenames जोड़ी जाती हैं, वे machine level पर globally ignore होती हैं
  • यह Git में check in नहीं होती और किसी specific repository से जुड़ी नहीं होती
  • यह उन फ़ाइलों के लिए अच्छी जगह है जिन्हें आप अपने कंप्यूटर की सभी Git repositories में ignore करना चाहते हैं
    • उदाहरण: macOS में .DS_Store को यहाँ जोड़ना उपयुक्त है

global ignore फ़ाइल का path बदलना

  • global ignore फ़ाइल को किसी दूसरी फ़ाइल पर set किया जा सकता है
  • अगर आप global Git ignore फ़ाइल के रूप में .gitignore_global इस्तेमाल करना चाहते हैं, तो यह command चलाएँ
git config --global core.excludesFile ~/.gitignore_global
  • default setting पर वापस जाने के लिए यह command चलाएँ
git config --global --unset core.excludesFile

कौन-सा rule किसी फ़ाइल को ignore कर रहा है, यह जाँचें

  • git check-ignore -v <फ़ाइलनाम> से आप देख सकते हैं कि कोई specific फ़ाइल किस rule की वजह से ignore हो रही है
  • .DS_Store कैसे ignore हो रही है, यह देखने के लिए Git repository के अंदर यह command चलाएँ
git check-ignore -v .DS_Store
  • अगर repository की .gitignore .DS_Store को ignore कर रही है, तो output उदाहरण इस तरह होगा
$ git check-ignore -v .DS_Store
.gitignore:1:.DS_Store	.DS_Store
  • अगर repository की .git/info/exclude .DS_Store को ignore कर रही है, तो output उदाहरण इस तरह होगा
$ git check-ignore -v .DS_Store
.git/info/exclude:7:.DS_Store	.DS_Store
  • अगर global ~/.config/git/ignore फ़ाइल .DS_Store को ignore कर रही है, तो output उदाहरण इस तरह होगा
$ git check-ignore -v .DS_Store
/Users/nelson/.config/git/ignore:2:.DS_Store	.DS_Store
  • अगर custom global ignore फ़ाइल .gitignore_global .DS_Store को ignore कर रही है, तो output उदाहरण इस तरह होगा
$ git check-ignore -v .DS_Store
/Users/nelson/.gitignore_global:1:.DS_Store	.DS_Store
  • अगर किसी specific फ़ाइल को ignore करने वाला कोई rule नहीं है, तो git check-ignore -v command कोई output नहीं देती

3 टिप्पणियां

 
sudoeng 1 시간 전

लगता है कि work Spec या plan.md जैसी फ़ाइलों को .git/info/exclude में डालना भी उपयोगी होगा

 
yangeok 2 시간 전

अच्छा, इसे root में भी सेट किया जा सकता है haha

 
GN⁺ 4 시간 전
Hacker News की राय
  • दिलचस्प लेख है, लेकिन Git में मेरी पसंदीदा लगभग-ignore सुविधा .gitattributes छूट गई है
    इस फ़ाइल से आप Git को कुछ फ़ाइलों के differences "ignore" करने के लिए कह सकते हैं। उदाहरण के लिए, Node प्रोजेक्ट में package-lock.json Git के नज़रिए से लगभग शुद्ध noise जैसा होता है। इसमें लाइब्रेरी के exact versions वाले बहुत बड़े differences दिखते हैं, जबकि इंसानों के पढ़ने लायक असली version जानकारी अलग package.json में होती है
    अगर प्रोजेक्ट रूट के .gitattributes में package-lock.json -diff की एक लाइन जोड़ दें, तो फ़ाइल stage/commit होती रहेगी लेकिन git diff में बेकार के विशाल differences नहीं दिखेंगे

    • package-lock.json को noise नहीं होना चाहिए। अगर आप उसे जानबूझकर update नहीं कर रहे हैं, तो उसे बदलना ही नहीं चाहिए, नहीं तो आप बिना वजह supply chain risk के सामने आ जाते हैं
      अगर package-lock.json में बदलाव बार-बार अनपेक्षित रूप से हो रहे हैं, तो आप कुछ गलत कर रहे हैं
    • package-lock.json सभी transitive dependencies दिखाता है, जबकि package.json सिर्फ direct dependencies दिखाता है। इसलिए यह कहना कि बाद वाला ही "इंसानों के पढ़ने लायक असली version" है, सही नहीं है
      दोनों के उद्देश्य अलग हैं, और यह कहना खतरनाक है कि lock file के differences हमेशा ignore किए जा सकते हैं
    • dependency upgrade और bug root-cause tracking करने वाले की नज़र से देखें तो, अगर git diff lock file के differences न दिखाए तो यह सच में बहुत खीझ दिलाने वाला होगा
      मैं समझ सकता हूँ कि यह line-by-line noise जैसा लग सकता है, लेकिन ज़रूरत पड़ने पर यह बहुत ज़रूरी होता है
  • global/user-level exclude settings एक ऐसी सुविधा है जिसे और ज़्यादा लोगों को जानना चाहिए। मुझे अक्सर ऐसे बदलाव मिलते हैं जिनमें IDE/OS/AI से जुड़ी फ़ाइलें हर प्रोजेक्ट की .gitignore में जोड़ने की कोशिश की जाती है, और जब आप बताते हैं कि इन्हें standard settings में डालने से वे हर जगह ignore हो जाएँगी, हर प्रोजेक्ट को छूना नहीं पड़ेगा, और .gitignore update न किए गए प्रोजेक्ट्स में गलती से commit होने का जोखिम भी घटेगा, तो ज़्यादातर लोग खुश होते हैं
    मेरा निजी सिद्धांत है कि repository के अंदर की .gitignore सिर्फ repository-specific items जैसे build outputs, dependency folders वगैरह के लिए होनी चाहिए, और ज़्यादातर user tools की चीज़ें हर व्यक्ति की अपनी user settings में रहनी चाहिए

    • global .gitignore setting के बारे में बार-बार बताना, repository के अंदर की .gitignore को सिर्फ repository-specific items तक सीमित रखने के सिद्धांत का स्वाभाविक नतीजा है
      अगर सबका समय बचाना है, तो बेहतर है कि ऐसे files को बस हर project की .gitignore में डाल दिया जाए
    • मैं हमेशा ऐसी files को project की .gitignore में डालता आया हूँ ताकि लोग अज्ञानता में उन्हें project में जोड़ न दें
      आखिरकार बाद में उन्हें Git से हटाना ही पड़ेगा, और उस व्यक्ति को तकलीफ़ होगी, तो मैंने शिष्टाचारवश पहले से रोक लगा दी। आगे से शायद मैं इतना शिष्ट न रहूँ
    • मैं gitignore वाला तरीका पसंद करता हूँ क्योंकि dev container को rebuild करने पर भी यह बचा रहता है
      अगर gitignore से बचना हो, तो generated scripts या volumes से settings restore/maintain की जा सकती हैं, लेकिन तब .gitignore की एक लाइन की जगह अतिरिक्त scripts या devcontainer mount settings चाहिए होंगी
    • क्या यह विरोधाभासी नहीं है कि आप एक ही गलत व्यवहार को बार-बार देखते रहें, और फिर उसे ठीक करने के सबसे आसान तरीके को स्पष्ट रूप से मना करने वाला सख्त नियम बना दें?
  • global Git config और ignore files के लिए मेरा मानना है कि ~/.gitignore_global बनाकर config बदलने से बेहतर है ~/.config/git/ignore और ~/.config/git/config का इस्तेमाल करना
    अगर आप ~/.config/ को कई कामों के लिए इस्तेमाल करें, तो root-level dotfiles काफ़ी छोटे हो जाते हैं
    Git exclude कम इस्तेमाल होने की वजह यह है कि वह repository में commit नहीं होता, इसलिए जब भी आप उसे इस्तेमाल करना चाहें, उसे फिर से बनाना पड़ता है। इसका मतलब यह नहीं कि वह बुरा है, बस कम इस्तेमाल होने की वजह यही है

    • और हाँ, अगर आप ~/.config directory को version control में रखें तो बाद के edits और sharing आसान हो जाते हैं
    • उसी file का इस्तेमाल करने वाले दूसरे tools के लिए आप ~/.cvsignore भी इस्तेमाल कर सकते हैं
  • पता नहीं मैंने यह कहाँ सीखा, लेकिन मैंने global Git ignore में attic जोड़ रखा है
    इससे मैं किसी भी project में attic directory बना सकता हूँ, जहाँ ऐसी तरह-तरह की चीज़ें रख सकूँ जिन्हें कभी commit नहीं करना चाहिए। अभी तक मैंने कोई repository नहीं देखी जो सच में ऐसी directory की जाँच करती हो

    • इसे थोड़ा उल्टा भी किया जा सकता है, लेकिन हर case में अलग से करना पड़ता है
      अगर attic जैसी directory हो, तो उसके अंदर attic/.gitignore बनाकर /** डाल दें; तब वह directory और उसके अंदर की हर चीज़ ignore हो जाएगी, और ignore file खुद भी ignore हो जाएगी
      मैं आमतौर पर अपने version में directory का नाम एक U+1F4A9 character रखता हूँ, लेकिन HN उसे comment में डालने नहीं देता
    • मेरे यहाँ मैं aux इस्तेमाल करता हूँ
      उसके अंदर सिर्फ एक asterisk * वाली .gitignore रखकर मैं उसे छिपा देता हूँ; इससे वह खुद और उसके अंदर की हर चीज़ ignore हो जाती है
    • मैं भी ऐसा ही करता हूँ। बस नाम .local रखता हूँ
    • मेरा scratch/ है
      अभी तक इसने मुझे फँसाया नहीं है
  • per-user ignores के बारे में, अगर आप macOS पर हैं तो वहाँ .DS_Store जोड़ना आदर्श माना जाता है, लेकिन तब project के हर Mac user को ऐसा करना पड़ेगा
    अगर दो या उससे ज़्यादा लोग हों, तो शायद इसे हर व्यक्ति पर छोड़ना सही न हो

    • यह कहाँ से आया, मैं पक्का नहीं कह सकता, लेकिन मेरे दोनों Mac (एक Ventura, एक Sequoia) में ~/.gitignore_global file में .DS_Store entry है, और global Git config में भी उस file की entries को ignore करने वाली setting मौजूद है
      नए Mac में इस file की तारीख़ order देने से दो दिन पहले की है, और मुझे याद नहीं कि मैंने यह खुद सेट किया हो, इसलिए लगता है यह default में आया था। पुराने Mac में भी शायद ऐसा ही रहा होगा, और macOS versions को देखकर लगता है कि यह default काफ़ी समय से ऐसा हो सकता है
      इसलिए शायद अब वह दौर खत्म हो गया है जब .DS_Store/ को .gitignore में जोड़ना पड़ता था
    • अल्पसंख्यक और बहुसंख्यक को देखने का यह काफ़ी अजीब तरीका है। अगर एक macOS user दस projects पर काम करता है, तो क्या उन दसों projects में वह line जोड़नी चाहिए, या उस एक user की तरफ़ से इसे संभालना बेहतर है?
  • वाह, मुझे यह पहले कैसे नहीं पता था? मैं 20 साल के अनुभव वाला professional software developer हूँ, और अब तक सिर्फ .gitignore ही इस्तेमाल करता रहा हूँ
    मुझे यह भी कभी सूझा नहीं कि .gitignore को सिर्फ अपनी ज़रूरत के exclude items से भरने से बेहतर कोई तरीका हो सकता है। मैंने बस दुनिया को जैसा दिखा, वैसा मान लिया
    आज दुनिया थोड़ी बेहतर लग रही है

  • मैं .git/info/exclude का बहुत ज़्यादा इस्तेमाल करता हूँ। यह उन scripts/Makefile के लिए बहुत अच्छा है जो सिर्फ local use के लिए हों और collaborators को न चाहिएँ, या वे उन्हें इस्तेमाल ही न कर सकें

    • जानना चाहूँगा कि ऐसे कौन-से scripts होते हैं जिन्हें दूसरे collaborators इस्तेमाल नहीं कर सकते। क्या यह PR workflow scripts जैसी चीज़ें हैं?
    • काफ़ी समय से मैं एक shell function इस्तेमाल करता आया हूँ जो git status में दिखने वाली सभी untracked files को .git/info/exclude में ठेल देती है
      आमतौर पर मैं इसे repository में डालनी वाली चीज़ों को add और commit करने के बाद चलाता हूँ
  • कई repositories वाले project directory में project-level Git settings अलग तरह से लागू करने के लिए मैं excludes file का ऐसे इस्तेमाल करता हूँ
    https://laszlo.nu/blog/project-level-git-config.html

  • इस विषय पर कुछ aliases हैं जिन्हें मैं इस्तेमाल करता हूँ
    assume = update-index --assume-unchanged
    unassume = update-index --no-assume-unchanged
    assumed = "!git ls-files -v | grep ^h | cut -c 3-"
    unassumeall = "!git assumed | xargs git update-index --no-assume-unchanged"
    assumeall = "!git st -s | awk {'print $2'} | xargs git assume"

  • पहले से tracked files के लिए git update-index --[no]-skip-worktree भी है
    यह local experiments में काम आ सकता है, लेकिन Git इसे कहीं बहुत स्पष्ट रूप से दिखाता नहीं, इसलिए इस्तेमाल थोड़ा झंझट वाला है। आपको याद रखना पड़ता है कि आपने इसे सेट किया है, और अगर भूल जाएँ तो checkout जैसी दूसरी operations रुक सकती हैं