Git की मैजिक फ़ाइलें
(nesbitt.io)- Git repository के भीतर मौजूद कुछ खास फ़ाइलों के जरिए अपने काम करने का तरीका नियंत्रित करता है, और ये
.git/के अंदर की settings नहीं बल्कि commit होकर code के साथ चलने वाली फ़ाइलें होती हैं .gitignore,.gitattributes,.lfsconfig,.gitmodules,.mailmapआदि क्रमशः फ़ाइल tracking से बाहर रखना, attributes तय करना, LFS settings, submodule management, author mapping का काम करते हैं.git-blame-ignore-revsऔर.gitmessagecode formatting commits को ignore करने और commit message template देने के जरिए collaboration की quality बेहतर बनाते हैं- GitHub, GitLab, Gitea आदि
.github/,.gitlab/,.gitea/जैसी platform-specific config folders के जरिए CI/CD, reviewer assignment जैसी सुविधाओं का विस्तार करते हैं - यही संरचना Git से आगे बढ़कर EditorConfig, Docker, language version management tools आदि में भी लागू होती है, जिससे dotfile-आधारित automatic configuration ecosystem बनता है
Git की प्रमुख मैजिक फ़ाइलें
- Git
.gitignore,.gitattributes,.lfsconfig,.gitmodules,.mailmapजैसी कई special files को पहचानकर repository के behavior को नियंत्रित करता है- ये फ़ाइलें
.git/के अंदर की settings नहीं बल्कि commit होकर साझा की जाने वाली configuration हैं, जो collaboration के दौरान consistent behavior सुनिश्चित करती हैं
- ये फ़ाइलें
.gitignore
- उन file patterns को परिभाषित करता है जिन्हें Git को track नहीं करना चाहिए
- wildcard(
*.log), directory(dist/), negation(!important.log) आदि को support करता है .gitignore,.git/info/exclude, global settings(~/.config/git/ignore) के क्रम में लागू होता है
- wildcard(
- जो फ़ाइलें पहले से tracked हैं, वे
.gitignoreजोड़ने के बाद भी tracked रहती हैं, औरgit rm --cachedसे हटाई जा सकती हैं - GitHub, GitLab, Gitea आदि ignored patterns वाली फ़ाइलों को भी बिना warning के commit करने देते हैं
- GitHub language-specific
.gitignoretemplates official repository में उपलब्ध कराता है
.gitattributes
- हर फ़ाइल के लिए filter, diff, merge, line endings, language detection आदि नियंत्रित करता है
- उदाहरण:
*.psd filter=lfs,*.png binary,*.sh text eol=lf
- उदाहरण:
textline ending normalization करता है,binarydiff/merge को disable करता है, औरmerge=oursconflict की स्थिति में local version बनाए रखता है- GitHub Linguist
.gitattributesपढ़कर language statistics से exclusion, generated code folding, documentation exclusion आदि करता है - हर directory के
.gitattributesऔर.git/info/attributesदोनों को पहचानता है
.lfsconfig
- Git LFS settings को repository के साथ साझा करता है
- LFS server URL, transfer retry count जैसी settings की जा सकती हैं
- उदाहरण:
[lfs] url = https://lfs.example.com/repo [lfs "transfer"] maxretries = 3
.gitattributesमें LFS से process होने वाली फ़ाइलें तय होती हैं, और.lfsconfigserver location जैसी detailed settings संभालता है- मौजूदा committed फ़ाइलों को LFS में ले जाने के लिए
git lfs migratecommand चाहिए
.gitmodules
- submodule configuration information को स्टोर करता है
- इसमें हर module का path, URL, branch information शामिल होती है
- उदाहरण:
[submodule "vendor/lib"] path = vendor/lib url = https://github.com/example/lib.git branch = main
git submodule addपर बनता है औरgit submodule updateके समय संदर्भित होता हैgit cloneकरते समय submodules अपने-आप नहीं आते;--recurse-submodulesoption चाहिए- version range tracking का समर्थन नहीं करता, और nested
.gitdirectories बनने जैसी कमियाँ हैं
.mailmap
- author name और email को एकीकृत रूप से प्रबंधित करता है
- उदाहरण:
Jane Developer <[email protected]> <[email protected]>
- उदाहरण:
git log,git shortlog,git blameआदि में unified नाम से दिखाता है- GitHub का contributors graph mailmap को reflect नहीं करता
- location को
.mailmapयाmailmap.filesetting से तय किया जा सकता है
.git-blame-ignore-revs
git blameमें ignore किए जाने वाले commits की सूची निर्दिष्ट करता है- formatter चलाना, lint लागू करना जैसी अर्थहीन changes को बाहर रखता है
- उदाहरण:
# Ran prettier on entire codebase a1b2c3d4e5f6g7h8i9j0...
git config blame.ignoreRevsFile .git-blame-ignore-revsसे enable किया जाता है- GitHub, GitLab(15.4+), Gitea इसे अपने-आप पहचानते हैं
- फ़ाइल न होने पर error आ सकता है, इसलिए empty file बनाए रखना recommended है
.gitmessage
- commit message template को परिभाषित करता है
- उदाहरण:
# <type>: <subject> # # Types: feat, fix, docs, style, refactor, test, chore
- उदाहरण:
git config commit.template .gitmessageसे setting करनी होती है- clone के बाद manual setup चाहिए होता है, और कुछ teams husky आदि से इसे automate करती हैं
- विकल्प के तौर पर
commit-msghook याprepare-commit-msghook इस्तेमाल किए जा सकते हैं
Platform-specific extension folders
- GitHub, GitLab, Gitea, Forgejo, Bitbucket आदि अपने अलग configuration folders इस्तेमाल करते हैं
.github/,.gitlab/,.gitea/,.forgejo/,.bitbucket/
- इनमें CI/CD workflows, issue·PR templates, CODEOWNERS files आदि शामिल होते हैं
- Forgejo
.forgejo/ → .gitea/ → .github/, और Gitea.gitea/ → .github/क्रम में fallback करता है - SourceHut
.build.ymlया.builds/*.ymlइस्तेमाल करता है
अन्य प्रचलित फ़ाइलें
- .gitkeep: Git empty directories को track नहीं करता, इसलिए directory बनाए रखने के लिए dummy file के रूप में इस्तेमाल होती है
- .gitconfig: project-specific Git settings का उदाहरण दे सकती है, लेकिन अपने-आप load नहीं होती
- .gitsigners: GPG/SSH signing keys की सूची प्रबंधित करती है,
gpg.ssh.allowedSignersFileसे specify किया जा सकता है - .gitreview: Gerrit code review server की settings file
- उदाहरण:
[gerrit] host=review.opendev.org port=29418 project=openstack/nova.git defaultbranch=master
- उदाहरण:
- .gitlint: commit message linting rules को परिभाषित करता है
- उदाहरण:
[general] ignore=body-is-missing [title-max-length] line-length=72
- उदाहरण:
- .jj/: Git-compatible VCS Jujutsu की state directory, जो
.git/के साथ मौजूद रह सकती है
Git से आगे का dotfile ecosystem
- .editorconfig: अलग-अलग editors के बीच consistent code style बनाए रखता है
- indentation, line endings, encoding, trailing whitespace removal आदि को परिभाषित करता है
- VS Code, Vim, Emacs जैसे प्रमुख editors इसका support करते हैं
- .ruby-version, .node-version, .python-version: language version management tools(rbenv, nodenv, pyenv आदि) इन्हें पढ़कर अपने-आप switch करते हैं
- .tool-versions: asdf की multi-language version management file
- .dockerignore: Docker build के दौरान exclude की जाने वाली फ़ाइलों की सूची तय करता है
.gitignoreजैसा ही pattern syntax इस्तेमाल करता है, build speed बढ़ाता है और secrets को बाहर रखता है
Git integration tools बनाते समय ध्यान देने योग्य बातें
- Git repositories को संभालने वाले tools को इन फ़ाइलों को ज़रूर पहचानना चाहिए
.gitignore: file traversal के दौरान ignore patterns लागू करना.gitattributes: binary और generated files में अंतर करना.mailmap: author information को unified रूप में दिखाना.gitmodules: submodule handling
- Git config file format
[section "subsection"] key = valueसंरचना का होता है, और इसेgit configcommand से पढ़ा-लिखा जा सकता है - ज़्यादातर languages की Git libraries इस format को parse करने की क्षमता देती हैं
2 टिप्पणियां
gitmessageके बारे में नहीं पता था, इसे इस्तेमाल करके देखना पड़ेगाHacker News की टिप्पणियाँ
.gitignoreका सम्मान करते हैं और web UI में ignored files नहीं दिखाते, लेकिन यह गलत व्याख्या लगती हैअसल में वे इसलिए नहीं दिखते क्योंकि वे repository में शामिल ही नहीं होते। अगर कोई फ़ाइल पहले से commit हो चुकी है, तो मेरा मानना है कि उसे दिखना चाहिए
.gitignoreमें जोड़ने पर भी वह UI में दिखती रहती है। क्योंकि वह अब भी repo का हिस्सा हैइसके उलट, शुरू से ignored फ़ाइल को ज़बरदस्ती commit करना भी संभव है, लेकिन उसके लिए थोड़ा ट्रिक चाहिए
.gitignoreसिर्फ यह तय करता है कि untracked files को छिपाना है या नहीं। चाहें तो ignored files को भी commit किया जा सकता हैshowinwebui=(true|false)जैसा कोई option होना अच्छा रहेगा 😄.git/info/excludeपर ज़ोर देना चाहूँगा। यह एक local-only gitignore है, यानी सिर्फ मेरे लिए सेटिंगउदाहरण के लिए, जब bug जाँचते समय कोई temporary file बनानी हो और branch बदलने पर भी उसे वहीं छोड़ना हो, तब यह उपयोगी है
मैं नीचे जैसा shell alias बनाकर इस्तेमाल करता हूँ इससे
git-ignore-local myfile.extचलाकर आसानी से जोड़ सकते हैंMacOS में सिर्फ
readlinkवाला हिस्सा बदलना होगा अगर इस function को PATH मेंgit-ignore-localके रूप में register कर दें, तो इसेgit ignore-localकी तरह इस्तेमाल किया जा सकता है.git/info/excludeका ज़िक्र.gitignoreके description के पहले हिस्से में भी है.gitattributesमें/test export-ignoreजोड़ दें, तो production server पर deploy करते समय test files को बाहर रखा जा सकता हैCapistrano जैसे deployment tools जब
git exportइस्तेमाल करते हैं, तो यह अपने-आप लागू हो जाता है और test files server पर नहीं जातींdevelopment के दौरान असर डाले बिना disk space भी बचता है
git archiveको ही ठीक से नहीं जानतेमैंने basic CI tools में भी इसे लगभग इस्तेमाल होते नहीं देखा। Capistrano इसका उपयोग करता है, यह पहला उदाहरण मैंने यहीं जाना
वैसे
export-substoption इस्तेमाल करें तोgit describeजैसी जानकारी सीधे file के अंदर भी डाली जा सकती हैjjइस्तेमाल करते समय मैं.jjfolder को repo और सभी git operations से पूरी तरह बाहर रखना चाहता थायहाँ तक कि
git clean -xdfसे भी वह delete न हो। अभी के लिए मैंने अस्थायी रूप सेgit clean -e .jjalias से काम चलाया है.git/info/excludeइस्तेमाल कर सकते हैं.mailmapको support नहीं करताइससे जुड़ी चर्चा GitHub Community Discussion में है
package-lock.json merge=ourssetting खतरनाक लगती हैक्योंकि merge या rebase के समय ours/theirs का मतलब अस्पष्ट हो सकता है
ऐसी setting का मतलब सिर्फ automated merge tools (जैसे git-annex branch) में बनता है
संदर्भ: ours/theirs का अर्थ, git-annex की आंतरिक संरचना
.git-blame-ignore-revsअच्छा feature है, लेकिन इसे “अन्य conventions” section में होना चाहिएअगर git client में इसे configure न किया जाए, तो जिस repository में यह file नहीं है वहाँ git blame fail हो जाता है
(:optional)option इस्तेमाल करके file न होने पर भी error से बचा जा सकता हैइसकी जानकारी Stack Overflow उत्तर में है
लेकिन यह अफ़सोस की बात है कि सभी tools
.mailmapको support नहीं करते। उदाहरण के लिए IntelliJ में इससे जुड़ा feature अभी भी bug/feature request की स्थिति में हैऔर
.git-blame-ignore-revsसिर्फ एक convention है, यह अपने-आप काम नहीं करता; इसे अलग से set करना पड़ता है.ignorefile को भी पहचानता हैमुझे लगता था कि सिर्फ
.gitignoreही लागू होता है, लेकिन.ignoreमें ripgrep setting बदलने पर search results बदल गए। बाद में समझ आया कि यह काफ़ी तर्कसंगत behavior थालिंक: nesbitt.io लेख