6 पॉइंट द्वारा GN⁺ 2024-05-27 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • 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 $FILE
    • git 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 $NAME
    • git switch $NAME
  • branch बनाएँ:
    • git checkout -b $NAME
    • git 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 --stat
    • git 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 BRANCHNAME
    • git reset --hard $COMMIT_ID
  • पिछली 5 commits को एक में मिलाएँ:
    • git rebase -i HEAD^^^^^^
    • जिन commits को मिलाना है, उनमें pick को fixup में बदलें
  • दूसरी branch या commit से file का version लाएँ:
    • git checkout $COMMIT_ID $FILE
    • git restore $FILE --source $COMMIT_ID
  • commit message बदलें या छूटी हुई file जोड़ें:
    • git commit --amend

branches को मिलाना

  • दूसरी branch में current branch को latest करने के लिए fast-forward merge:
    • git switch main
    • git merge banana
  • एक commit को दूसरी branch में कॉपी करें:
    • git cherry-pick $COMMIT_ID
  • अलग हो चुकी branch को rebase से मिलाएँ:
    • git switch banana
    • git rebase main
  • अलग हो चुकी branch को merge से मिलाएँ:
    • git switch main
    • git merge banana
    • git commit
  • अलग हो चुकी branch को squash merge से मिलाएँ:
    • git switch main
    • git merge --squash banana
    • git commit

remote repository और sync

  • remote repository जोड़ें:
    • git remote add $NAME $URL
  • main branch को origin remote पर 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 main
    • git 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

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 टिप्पणियां

 
GN⁺ 2024-05-27
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 से भी ज़्यादा बारीकी से चुनना हो, तो e option आज़माएँ। अलग-अलग lines को शामिल/बाहर करने का तरीका बताया जाता है, इसलिए याद रखने की ज़रूरत नहीं पड़ती

    • मुझे अभी पता चला कि git diff --staged, git diff --cached का alias है। मैं कई सालों से cached इस्तेमाल कर रहा था, लेकिन staged कहीं ज़्यादा सहज है। बस पता नहीं कि यह muscle memory मिटा पाऊँगा या नहीं
    • ऐसी commands के कई aliases बना लेने से काफी समय बचता है, और काम को बेहतर तरीके से व्यवस्थित करने की बाधा भी कम होती है
      रुचि हो तो देख सकते हैं या 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/

    • git tool के नाम को देखते हुए blame brand के हिसाब से सही नाम जैसा लगता है
    • सहमत। मैंने अपनी config में blame को who में बदल दिया है। सच कहूँ तो मैं Vim का कट्टर user हूँ, इसलिए बस w इस्तेमाल करता हूँ
  • मुझे Git सीखने का अपना तरीका पसंद आया। शुरुआत में मैंने third-party Git GUI Sourcetree से शुरू किया था, जिसे इस्तेमाल करना और समझना बहुत आसान था
    उसके बाद git gui पर गया, लेकिन यह step skip किया जा सकता है। फिर UI खोलना झंझट लगने लगा, इसलिए terminal commands सीखीं
    Git beginners को इसकी सलाह दूँगा, लेकिन यह सिर्फ मेरा n=1 अनुभव है

    • Git के बारे में मैं बस clone, pull, commit, push जितना जानता हूँ, और अब तक वही काफी रहा है। Git इतना simple भी हो सकता है। बेशक ज़रूरत पड़े तो ज्यादा complex usage भी सीखी जा सकती है
    • मैं terminal commands पर वापस नहीं जाना चाहता। Git repositories और workflows visualization में कहीं बेहतर समझ आते हैं, इसलिए Git असल में लगभग ऐसा tool है जो GUI से इस्तेमाल किए जाने की माँग करता है
      Magit इस्तेमाल करना शुरू करते ही Git समझ में आने लगा
    • मैं Sourcetree से Fork पर चला गया। दोनों काफी मिलते-जुलते हैं, लेकिन इसकी performance बहुत बेहतर है और UI smooth है—अगर हाल के वर्षों में Sourcetree बेहतर नहीं हुआ हो तो
    • मेरा रास्ता भी मिलता-जुलता था, लेकिन मैंने GitKraken और Sublime Merge इस्तेमाल किए, और complex कामों को भी आसान बनाने की वजह से Sublime Merge को बनाए रखा
      Sublime Merge के बारे में कहने को सिर्फ तारीफ ही है
  • सोच रहा हूँ कि Git के बेवजह जटिल होने के पीछे कोई ऐतिहासिक वजह है क्या
    यह चीट शीट देखकर उसकी जटिलता और भी महसूस होती है

    • सही है। क्योंकि Git को Linus Torvalds ने Linux kernel development को संभव बनाने और आगे बढ़ाने के लिए बनाया था
      इसका इतना व्यापक इस्तेमाल होना “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 आदर्श नहीं हैं
    • जटिलता का एक हिस्सा इसलिए है कि शुरुआती versions में नए subcommand जोड़ने की लागत काफ़ी ज़्यादा थी। नतीजतन git checkout जैसे मौजूदा subcommands में features लगातार जुड़ते गए और user experience और उलझ गया
      नए Git में नया subcommand जोड़ने की लागत कम हुई है, और git switch जैसे अधिक specific commands जोड़ना शुरू किया गया है
    • ज़्यादातर workflows में log, add, commit, pull, push जैसे कुछ Git commands जानना ही काफी है, ऐसा मुझे लगता है। GUI tools भी हैं
      सच कहूँ तो सामान्य कामों में Git मुझे इतना जटिल नहीं लगता। बस इसमें ज़रूरत पड़ने पर इस्तेमाल की जा सकने वाली कई powerful features हैं
    • Git बेवजह जटिल नहीं है। जिस workflow को support करने के लिए Git बनाया गया था, वह खुद असाधारण रूप से जटिल था, और target users यानी kernel developers बहुत technical थे, इसलिए जटिलता कोई बड़ी समस्या नहीं थी
      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/ भी लागू होता है
    • क्योंकि अच्छा UI design एक अलग skill है और extra effort मांगता है, इसलिए अक्सर उसे बस ignore कर दिया जाता है
  • मुझे git add -p के बारे में पता नहीं था, लेकिन यह सच में उपयोगी है
    -p, --patch आपको index और working tree के बीच patch hunks को interactive तरीके से चुनकर index में जोड़ने देता है। यह बदलावों को index में जोड़ने से पहले diff review करने का मौका देता है

    • संभव हो तो मौजूदा काम के hunks खुद चुनकर consistent commit के रूप में assemble करता हूँ। इससे मैंने जो किया है उसे दिमाग में फिर से व्यवस्थित करने में मदद मिलती है, और जब किसी को समझाना हो तो commit flow के हिसाब से समझा सकता हूँ
  • इसमें मैं git commit --fixup $COMMIT_ID और git rebase -i upstream/master --autosquash का combo जोड़ना चाहूँगा
    हाल के workflow में यह essential बन गया है। Julia का example पिछले 5 commits को rebase करने के लिए HEAD^^^^^ इस्तेमाल करता है, लेकिन मैं हाल तक HEAD~5 इस्तेमाल करता था। अब पता चला कि upstream HEAD तक के सभी commits को बस rebase किया जा सकता है

    • git commit --fixup $COMMIT_ID तो तुरंत अपनाना पड़ेगा। मैं हमेशा “oops GET users/me” जैसे छोटे fixup commits बनाता था, और अगले interactive rebase में manually ले जाकर fixup करता था; यह तरीका कहीं बेहतर है
    • यह मैंने हाल ही में सीखा, और Gerrit में stacked patches के साथ काम करते समय यह बहुत अच्छा है
  • “आखिरी 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 करने में अब काफी सहज हो गया हूँ

    • Jujutsu ने वह डर पूरी तरह खत्म कर दिया
      अगर पता नहीं कि किसी 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 शानदार है

    • index न होने वाली बात से सहमत होना मुश्किल है। इससे कुछ workflows ज़्यादा simple हो सकते हैं, लेकिन मैं अच्छा हो या बुरा, Git के index का इतना आदी हो चुका हूँ कि मेरे काम करने का तरीका काफी बदल जाएगा
      हालांकि थोड़ा-बहुत आज़माने के अलावा मैंने इसे असली काम में गहराई से इस्तेमाल नहीं किया है, इसलिए पक्का कहना मुश्किल है