Git चीट शीट [PDF]
(wizardzines.com)- Git में अक्सर अटकने वाले कामों को commit बनाना, branch बदलना, changes compare करना, remote sync, और changes undo करने वाले commands के हिसाब से जल्दी देखने के लिए व्यवस्थित किया गया PDF है
- लोकल workflow में
git status,git add,git commit,git diffके आधार पर staging से पहले और बाद की स्थिति देखकर commit बनाने का तरीका बताया गया है - branch workflow में
git switch,git checkout,git branch,git merge,git rebase,git cherry-pickसे बनाना·बदलना·merge करना·rebase करना संभाला जाता है - history देखने और recovery के लिए
git log,git blame,git show,git reflog,git reset,git restoreशामिल हैं, और branch·tag·HEAD·remote branch भी commit reference के रूप में इस्तेमाल किए जा सकते हैं - remote repository workflow में
git remote add,git fetch,git pull,git push,git push --force-with-lease,git push --tagsके जरिए changes लाने और भेजने की प्रक्रिया दी गई है
रिपॉजिटरी शुरू करना और वर्तमान स्थिति देखना
- नई रिपॉजिटरी शुरू करें:
git init
- मौजूदा रिपॉजिटरी clone करें:
git clone $URL
- वर्तमान स्थान और स्थिति देखें:
git status
commit की तैयारी और बनाना
- untracked file जोड़ें:
git add $FILE
- सभी untracked files और unstaged changes जोड़ें:
git add .
- file के केवल कुछ changes चुनकर stage करें:
git add -p
- file delete या move करें:
git rm $FILEgit mv $OLD $NEW
- file delete किए बिना Git tracking से हटाएँ:
git rm --cached $FILE
- सभी staged changes unstage करें:
git reset HEAD
- commit बनाएँ:
git commit- message लिखने के लिए text editor खुलेगा
- message सीधे देकर commit करें:
git commit -m 'message'
- unstaged changes सहित message के साथ commit करें:
git commit -am 'message'
branch बदलना और प्रबंधन
- branch बदलें:
git checkout $NAMEgit switch $NAME
- branch बनाएँ:
git checkout -b $NAMEgit switch -c $NAME
- branch सूची देखें:
git branch
- हाल की commit के आधार पर branches sort करें:
git branch --sort=-committerdate
- branch delete करें:
git branch -d $NAME
- branch force delete करें:
git branch -D $NAME
history देखना और code track करना
- branch history देखें:
git log main
- दो branches का संबंध graph में देखें:
git log --graph a b
- one-line log देखें:
git log --oneline
- file की हर line को आखिरी बार किसने बदला, देखें:
git blame $FILENAME
- file को modify करने वाली सभी commits देखें:
git log $FILENAME
- किसी खास text को जोड़ने या हटाने वाली commit खोजें:
git log -S banana
changes compare करना
- commit और उसकी parent commit का अंतर देखें:
git show $COMMIT_ID
- merge commit और उसके merged parents का अंतर देखें:
git show --remerge-diff $COMMIT_ID
- diff summary देखें:
git diff $COMMIT_ID --statgit show $COMMIT_ID --stat
- दो commits compare करें:
git diff $COMMIT_ID $COMMIT_ID
- केवल किसी खास file को commit से compare करें:
git diff $COMMIT_ID $FILENAME
- staged changes और unstaged changes दोनों का पूरा compare करें:
git diff HEAD
- केवल staged changes compare करें:
git diff --staged
- केवल unstaged changes compare करें:
git diff
config files और options
- लोकल Git config file:
.git/config
- global Git config file:
~/.gitconfig
- ignore की जाने वाली files की सूची:
.gitignore
- config option सेट करें:
git config user.name 'Julia'
- global option सेट करें:
git config --global ...
- alias जोड़ें:
git config alias.st status
- उपलब्ध config options देखें:
man git-config
history बदलना और files restore करना
- सबसे हाल की commit वापस लें, working directory वैसी ही रखें:
git reset HEAD^
- असफल rebase वापस लें:
git reflog BRANCHNAMEgit reset --hard $COMMIT_ID
- पिछली 5 commits को एक में मिलाएँ:
git rebase -i HEAD^^^^^^- जिन commits को मिलाना है, उनमें
pickकोfixupमें बदलें
- दूसरी branch या commit से file का version लाएँ:
git checkout $COMMIT_ID $FILEgit restore $FILE --source $COMMIT_ID
- commit message बदलें या छूटी हुई file जोड़ें:
git commit --amend
branches को मिलाना
- दूसरी branch में current branch को latest करने के लिए fast-forward merge:
git switch maingit merge banana
- एक commit को दूसरी branch में कॉपी करें:
git cherry-pick $COMMIT_ID
- अलग हो चुकी branch को rebase से मिलाएँ:
git switch bananagit rebase main
- अलग हो चुकी branch को merge से मिलाएँ:
git switch maingit merge bananagit commit
- अलग हो चुकी branch को squash merge से मिलाएँ:
git switch maingit merge --squash bananagit commit
remote repository और sync
- remote repository जोड़ें:
git remote add $NAME $URL
mainbranch कोoriginremote पर push करें:git push origin main
- पहली बार push की जा रही branch को
originपर भेजें और tracking branch सेट करें:git push -u origin $NAME
- current branch को remote tracking branch पर push करें:
git push
- force push:
git push --force-with-lease
- tags push करें:
git push --tags
- changes लाएँ, लोकल branch को न बदलें:
git fetch origin main
- सभी branches fetch करें:
git fetch --all
- fetch के बाद current branch पर rebase करें:
git pull --rebase
- fetch के बाद current branch पर merge करें:
git pull origin maingit pull
commit को refer करने के तरीके
$COMMIT_IDकी जगह कई तरह के references इस्तेमाल किए जा सकते हैं:- branch:
main - tag:
v0.1 - commit ID:
3e887ab - remote branch:
origin/main - current commit:
HEAD - 3 commits पहले:
HEAD^^^ - 3 commits पहले:
HEAD~3
- branch:
changes फेंकना
- एक file के staged और unstaged दोनों changes delete करें:
git checkout HEAD $FILE
- एक file के unstaged changes delete करें:
git checkout $FILE
- सभी staged और unstaged changes delete करें:
git reset --hard
- staged और unstaged changes को stash करें:
git stash
- untracked files delete करें:
git clean
1 टिप्पणियां
Hacker News की राय
कुछ commands छिपे हुए gems जैसी हैं:
git diff --stagedआखिरी commit और अभी staged किए गए content के बीच का फर्क दिखाता है, इसलिए files या hunks को बारीकी से stage करते समय यह जाँचने के लिए अच्छा है कि सिर्फ वही चीज़ें शामिल हुई हैं जो आप चाहते थेgit log <file>सिर्फ वे commits दिखाता है जिनमें उस file में बदलाव हुआ है, इसलिए पूरेgit logमें खोजने की ज़रूरत कम हो जाती है, और यह खासकर उन files में उपयोगी है जो अक्सर नहीं बदलतींgit add --patchइस्तेमाल करते समय अगर Git द्वारा बाँटे गए hunks से भी ज़्यादा बारीकी से चुनना हो, तोeoption आज़माएँ। अलग-अलग lines को शामिल/बाहर करने का तरीका बताया जाता है, इसलिए याद रखने की ज़रूरत नहीं पड़तीgit diff --staged,git diff --cachedका alias है। मैं कई सालों सेcachedइस्तेमाल कर रहा था, लेकिनstagedकहीं ज़्यादा सहज है। बस पता नहीं कि यह muscle memory मिटा पाऊँगा या नहींरुचि हो तो देख सकते हैं या aliases सुझा सकते हैं: https://gitlab.com/Falimonda/gitrc
git config --global commit.verbose trueसेट करने पर Git commit message editor के comment area में staged diff अपने-आप डाल देता हैसूची में नहीं है, लेकिन मेरी पसंदीदा commands में से एक
git log -LstartLine,endLine:fileNameहैयह expanded
git blameकी तरह दिखाता है कि बताई गई lines समय के साथ कैसे बदलीं और किसने बदलीं। line numbers बदल जाएँ या file move हो जाए, तब भी यह track करता हैयह “किसने, कब, क्यों ऐसा किया?” या “यह कब से ऐसा है?” जैसे सवालों का जवाब देता है
Phil Karlton की बात याद आती है: “Computer science में सिर्फ दो मुश्किल चीज़ें हैं: cache invalidation और naming.”
उस नज़रिए से Git command का नाम
blameहोना काफी अजीब लगा, और ऐसा सोचने वाला मैं अकेला नहीं थाWhat does 'git blame' do? https://stackoverflow.com/questions/31203001/what-does-git-blame-do
Blame someone else for your bad code https://news.ycombinator.com/item?id=27963868
Git blame should be called git credit https://dev.to/damcosset/git-blame-should-be-called-git-credit-27h5
Does Git Blame sound too negative? https://www.reddit.com/r/ProgrammerHumor/comments/r5lzyo/does_git_blame_sound_too_negative_just_look_up/
gittool के नाम को देखते हुएblamebrand के हिसाब से सही नाम जैसा लगता हैblameकोwhoमें बदल दिया है। सच कहूँ तो मैं Vim का कट्टर user हूँ, इसलिए बसwइस्तेमाल करता हूँमुझे Git सीखने का अपना तरीका पसंद आया। शुरुआत में मैंने third-party Git GUI Sourcetree से शुरू किया था, जिसे इस्तेमाल करना और समझना बहुत आसान था
उसके बाद
git guiपर गया, लेकिन यह step skip किया जा सकता है। फिर UI खोलना झंझट लगने लगा, इसलिए terminal commands सीखींGit beginners को इसकी सलाह दूँगा, लेकिन यह सिर्फ मेरा n=1 अनुभव है
clone,pull,commit,pushजितना जानता हूँ, और अब तक वही काफी रहा है। Git इतना simple भी हो सकता है। बेशक ज़रूरत पड़े तो ज्यादा complex usage भी सीखी जा सकती हैMagit इस्तेमाल करना शुरू करते ही Git समझ में आने लगा
Sublime Merge के बारे में कहने को सिर्फ तारीफ ही है
सोच रहा हूँ कि Git के बेवजह जटिल होने के पीछे कोई ऐतिहासिक वजह है क्या
यह चीट शीट देखकर उसकी जटिलता और भी महसूस होती है
इसका इतना व्यापक इस्तेमाल होना “happy accident” भी हो सकता है, या दुर्भाग्य भी। GitHub ने “free Git hosting” के जरिए Git को लोकप्रिय बनाने में बड़ी भूमिका निभाई, लेकिन मुझे नहीं लगता कि Git कई projects के लिए आदर्श version control system है
क्योंकि यह Linus और Linux के लिए बनाया गया था, इसकी terminology और workflow कभी-कभी सामान्य version control systems के उलट लगते हैं।
Pull Requestनाम भी इसलिए है कि Linux development में Linus या maintainer बदलावों को kernel tree में खींचकर लाते हैं। दूसरे systems में इसे आम तौर परMerge Requestकहा जाता है, और बदलाव कहीं से भी आए हों, उन्हें tree में merge करने के लिहाज से वह नाम कहीं ज़्यादा logical हैGit उन लगभग इकलौते open source distributed version control systems में था जो बहुत बड़े codebase को तेज़ी से संभाल सकता था, इसलिए बड़ी कंपनियों में भी इसकी inertia बढ़ गई
निजी projects के लिए मैं Mercurial को कहीं ज़्यादा पसंद करता हूँ और सच में इस्तेमाल भी करता हूँ, लेकिन Android AOSP जैसे बड़े codebase में Hg इस्तेमाल करके देखें तो यह बुरी तरह अटकता है। Mercurial का user interface और command structure बेहतर है, और changes tree देखने के लिए तुरंत web server चलाने की सुविधा भी है, लेकिन यह Python में लिखा गया है, इसलिए performance और scalability आदर्श नहीं हैं
git checkoutजैसे मौजूदा subcommands में features लगातार जुड़ते गए और user experience और उलझ गयानए Git में नया subcommand जोड़ने की लागत कम हुई है, और
git switchजैसे अधिक specific commands जोड़ना शुरू किया गया हैlog,add,commit,pull,pushजैसे कुछ Git commands जानना ही काफी है, ऐसा मुझे लगता है। GUI tools भी हैंसच कहूँ तो सामान्य कामों में Git मुझे इतना जटिल नहीं लगता। बस इसमें ज़रूरत पड़ने पर इस्तेमाल की जा सकने वाली कई powerful features हैं
kernel developers को decentralized तरीके से एक-दूसरे से communicate करना था, और एक-दूसरे के काम के ऊपर फिर से काम करना था। जिस project में 15,000 लोग code लिख रहे हों, उसमें काम कैसे करेंगे? Git इसी मकसद के लिए बनाया गया था
जिस design-target workflow को support करना था, उसके लिए जितनी complexity चाहिए थी उतना ही यह जटिल है। ज़्यादा सरल tool बनाना आसान है, लेकिन तब वह Linux kernel development जैसे complex workflows को support नहीं कर पाएगा। इसलिए यह बेवजह जटिल नहीं है, लेकिन simple use cases के लिए ज़रूरत से ज़्यादा complex ज़रूर है
अगर कम complex frontend चाहिए तो Git को आसान बनाने वाले बहुत tools हैं। अगर आप full-time software developer नहीं हैं, तो मैं Git को सीधे इस्तेमाल करने की सलाह नहीं दूँगा। लेकिन अगर आप full-time developer हैं, तो इसके internal concepts समझने में समय लगाना worthwhile है, और एक बार समझ आने पर Git अपने काम के मुकाबले काफ़ी elegant है
Git जानने या न जानने से मैं किसी को software developer होने के योग्य/अयोग्य नहीं ठहराऊँगा, लेकिन अगर ऐसे basic systems कैसे काम करते हैं यह खुद समझने में आपको dopamine नहीं मिलता, तो शायद यह field आपके स्वाद की न हो। वह भी ठीक है; हर किसी के लिए कुछ चीज़ें सही होती हैं और कुछ नहीं
Git में movement सीखने के लिए https://learngitbranching.js.org की सलाह दूँगा। बेशक https://xkcd.com/1597/ भी लागू होता है
मुझे
git add -pके बारे में पता नहीं था, लेकिन यह सच में उपयोगी है-p,--patchआपको index और working tree के बीच patch hunks को interactive तरीके से चुनकर index में जोड़ने देता है। यह बदलावों को index में जोड़ने से पहले diff review करने का मौका देता हैइसमें मैं
git commit --fixup $COMMIT_IDऔरgit rebase -i upstream/master --autosquashका combo जोड़ना चाहूँगाहाल के workflow में यह essential बन गया है। Julia का example पिछले 5 commits को rebase करने के लिए
HEAD^^^^^इस्तेमाल करता है, लेकिन मैं हाल तकHEAD~5इस्तेमाल करता था। अब पता चला कि upstreamHEADतक के सभी commits को बस rebase किया जा सकता हैgit commit --fixup $COMMIT_IDतो तुरंत अपनाना पड़ेगा। मैं हमेशा “oops GET users/me” जैसे छोटे fixup commits बनाता था, और अगले interactive rebase में manually ले जाकर fixup करता था; यह तरीका कहीं बेहतर है“आखिरी 5 commits को एक में जोड़ना:
git rebase -i HEAD^^^^^^” के लिएgit rebase -i HEAD~5सही नहीं होगा क्या?यह मानकर कि आप सिर्फ linear history को rebase करना चाहते हैं
https://stackoverflow.com/questions/2221658/whats-the-difference-between-head-and-head-in-git
सबसे बड़ा अहसास उस पल हुआ जब समझ आया कि सभी commits अभी भी अंदर मौजूद रहते हैं। Tags और branches बस commits की ओर इशारा करते हैं, और कोई branch पहले जिस commit की ओर इशारा करती थी, वह भी गायब नहीं हुआ होता
कई commands—शायद लगभग सभी—non-destructive होते हैं, इसलिए branch की पुरानी state को आसानी से refer किया जा सकता है
git reflogदेखा तो था, लेकिन मुख्य रूप से “वह branch कौन-सी थी जिस पर मैंने पहले काम किया था?” याद करने के लिए ही इस्तेमाल करता थाउन operations को लेकर एक आधा-स्वस्थ डर बन गया था जो आपको अनचाहे conflict resolution के बीच में ले जा सकते हैं। आम तौर पर गलत commit या branch को refer करने से conflicts हो जाते थे
वह डर पूरी तरह खत्म तो नहीं हुआ, लेकिन कम-से-कम rebase जैसे operations के बीच पुराना काम recover करने में अब काफी सहज हो गया हूँ
अगर पता नहीं कि किसी operation के बाद conflict होगा या नहीं, तो बस उसे चला कर देख लेता हूँ। Conflict हो तो उसे resolve करता हूँ, या जिस operation ने conflict बनाया उसे undo कर देता हूँ, या कहीं और नया commit बनाकर conflict को बाद में निपटाने के लिए छोड़ देता हूँ
अगर पहले से पता हो कि conflict होगा, तो संबंधित branch को duplicate करके पहले से match कर देखता हूँ, या conflicting operation चलाकर resolution process से गुजरता हूँ। अगर resolution messy हो जाए, तो कुछ resolutions ही undo करके कोशिश जारी रखता हूँ, या थोड़ी देर के लिए छोड़कर दूसरा काम करता हूँ, या पूरा tree ही फेंक सकता हूँ
साफ कहूँ तो, Git को छोड़कर JJ को देखना चाहिए
https://martinvonz.github.io/jj/v0.17.1/
शायद Linus भी सोचते होंगे कि Git का UI खराब है। JJ का workflow शानदार है
हालांकि थोड़ा-बहुत आज़माने के अलावा मैंने इसे असली काम में गहराई से इस्तेमाल नहीं किया है, इसलिए पक्का कहना मुश्किल है