जब मैं Git में एक पूर्वज प्रतिबद्ध वस्तु निर्दिष्ट करता हूं, तो मैं HEAD^
और के बीच भ्रमित हूं HEAD~
।
दोनों का एक "क्रमांकित" संस्करण है जैसे HEAD^3
और HEAD~2
।
वे मुझे बहुत समान या समान लगते हैं, लेकिन क्या टिल्ड और कैरट के बीच कोई अंतर हैं?
जब मैं Git में एक पूर्वज प्रतिबद्ध वस्तु निर्दिष्ट करता हूं, तो मैं HEAD^
और के बीच भ्रमित हूं HEAD~
।
दोनों का एक "क्रमांकित" संस्करण है जैसे HEAD^3
और HEAD~2
।
वे मुझे बहुत समान या समान लगते हैं, लेकिन क्या टिल्ड और कैरट के बीच कोई अंतर हैं?
जवाबों:
~
ज्यादातर समय का उपयोग करें - कई पीढ़ियों तक वापस जाने के लिए, आमतौर पर आप क्या चाहते हैं^
मर्ज कमिट पर उपयोग करें - क्योंकि उनके दो या अधिक (तत्काल) माता-पिता हैंस्मृति सहायकों:
~
दिखने में लगभग रैखिक है और एक सीधी रेखा में पीछे जाना चाहता है^
सड़क में एक पेड़ या कांटा के एक दिलचस्प खंड का सुझाव देता है"निर्दिष्ट संशोधन" की धारा git rev-parse
प्रलेखन परिभाषित करता है ~
के रूप में
<rev>~<n>
, जैसेmaster~3
प्रत्यय~<n>
एक संशोधन पैरामीटर का मतलब वस्तु है कि प्रतिबद्ध n वें नामित की पीढ़ी पूर्वज वस्तु के लिए प्रतिबद्ध हैं, केवल पहले माता-पिता के बाद। उदाहरण के लिए,<rev>~3
के बराबर है<rev>^^^
जो के बराबर है<rev>^1^1^1
...
आप किसी भी प्रतिबद्ध के माता-पिता से मिल सकते हैं, न कि सिर्फ HEAD
। आप पीढ़ियों के माध्यम से भी वापस जा सकते हैं: उदाहरण के लिए, master~2
मतलब है कि मास्टर ब्रांच की नोक पर मर्ज होने वाले पहले माता-पिता के पक्ष में।
गिट इतिहास अरेखीय है: एक निर्देशित एसाइक्लिक ग्राफ (डीएजी) या वृक्ष। केवल एक माता-पिता के साथ एक प्रतिबद्ध के लिए, rev~
और rev^
एक ही बात का मतलब है। कैरेट चयनकर्ता मर्ज कमिट के साथ उपयोगी हो जाता है क्योंकि प्रत्येक व्यक्ति दो या दो से अधिक माता-पिता की संतान है - और जीव विज्ञान के साथ उधार ली गई भाषा।
HEAD^
वर्तमान शाखा की नोक के पहले तत्काल माता पिता का मतलब है । HEAD^
के लिए छोटा है HEAD^1
, और आप HEAD^2
उचित रूप में भी संबोधित कर सकते हैं और इसी तरह। प्रलेखन का एक ही खंडgit rev-parse
इसे परिभाषित करता है
<rev>^
, उदाहरण के लिएHEAD^
,v1.5.1^0
एक संशोधन पैरामीटर के लिए एक
प्रत्यय^
का अर्थ है उस प्रतिबद्ध वस्तु का पहला अभिभावक।^<n>
इसका मतलब n वें माता-पिता ([ जैसे ]<rev>^
के बराबर है<rev>^1
)। एक विशेष नियम के रूप में,<rev>^0
कमिट का मतलब है और इसका उपयोग तब किया जाता है जब<rev>
किसी ऑब्जेक्ट ऑब्जेक्ट का ऑब्जेक्ट नाम होता है जो एक कमिट ऑब्जेक्ट को संदर्भित करता है।
इन बारीकियों या चयनकर्ताओं को मनमाने ढंग से जंजीर किया जा सकता है, उदाहरण के लिए , topic~3^2
अंग्रेजी में मर्ज कमिट का दूसरा माता-पिता है जो शाखा के वर्तमान टिप के महान-दादा-दादी (तीन पीढ़ी पीछे) है topic
।
प्रलेखन का उपर्युक्त खंडgit rev-parse
एक संकलित गिट इतिहास के माध्यम से कई रास्तों का पता लगाता है। समय सामान्य रूप से नीचे की ओर बहता है। कमिट डी, एफ, बी और ए मर्ज कमिट हैं।
यहाँ एक चित्रण है, जॉन लेलीगर द्वारा। दोनों प्रतिबद्ध नोड्स बी और सी, प्रतिबद्ध नोड ए के माता-पिता हैं। माता-पिता के आवागमन को बाएं-से-दाएं करने का आदेश दिया गया है।
G H I J \ / \ / D E F \ | / \ \ | / | \|/ | B C \ / \ / A A = = A^0 B = A^ = A^1 = A~1 C = A^2 D = A^^ = A^1^1 = A~2 E = B^2 = A^^2 F = B^3 = A^^3 G = A^^^ = A^1^1^1 = A~3 H = D^2 = B^^2 = A^^^2 = A~2^2 I = F^ = B^3^ = A^^3^ J = F^2 = B^3^2 = A^^3^2
जीआईटी रिपॉजिटरी बनाने के लिए नीचे दिए गए कोड को चलाएं जिसका इतिहास उद्धृत चित्रण से मेल खाता है।
#! /usr/bin/env perl
use strict;
use warnings;
use subs qw/ postorder /;
use File::Temp qw/ mkdtemp /;
my %sha1;
my %parents = (
A => [ qw/ B C / ],
B => [ qw/ D E F / ],
C => [ qw/ F / ],
D => [ qw/ G H / ],
F => [ qw/ I J / ],
);
sub postorder {
my($root,$hash) = @_;
my @parents = @{ $parents{$root} || [] };
postorder($_, $hash) for @parents;
return if $sha1{$root};
@parents = map "-p $sha1{$_}", @parents;
chomp($sha1{$root} = `git commit-tree @parents -m "$root" $hash`);
die "$0: git commit-tree failed" if $?;
system("git tag -a -m '$sha1{$root}' '$root' '$sha1{$root}'") == 0 or die "$0: git tag failed";
}
$0 =~ s!^.*/!!; # / fix Stack Overflow highlighting
my $repo = mkdtemp "repoXXXXXXXX";
chdir $repo or die "$0: chdir: $!";
system("git init") == 0 or die "$0: git init failed";
chomp(my $tree = `git write-tree`); die "$0: git write-tree failed" if $?;
postorder 'A', $tree;
system "git update-ref HEAD $sha1{A}"; die "$0: git update-ref failed" if $?;
system "git update-ref master $sha1{A}"; die "$0: git update-ref failed" if $?;
# for browsing history - http://blog.kfish.org/2010/04/git-lola.html
system "git config alias.lol 'log --graph --decorate --pretty=oneline --abbrev-commit'";
system "git config alias.lola 'log --graph --decorate --pretty=oneline --abbrev-commit --all'";
यह नए फेंकने वाले रेपो में केवल उपनाम जोड़ता है git lol
औरgit lola
इसलिए आप इतिहास को इस रूप में देख सकते हैं
$ git lol
* 29392c8 (HEAD -> master, tag: A) A
|\
| * a1ef6fd (tag: C) C
| |
| \
*-. \ 8ae20e9 (tag: B) B
|\ \ \
| | |/
| | * 03160db (tag: F) F
| | |\
| | | * 9df28cb (tag: J) J
| | * 2afd329 (tag: I) I
| * a77cb1f (tag: E) E
* cd75703 (tag: D) D
|\
| * 3043d25 (tag: H) H
* 4ab0473 (tag: G) G
ध्यान दें कि आपकी मशीन पर SHA-1 ऑब्जेक्ट नाम उपरोक्त लोगों से भिन्न होंगे, लेकिन टैग आपको नाम से कमिट्स को संबोधित करने और उनकी समझ की जांच करने की अनुमति देते हैं।
$ git log -1 --format=%f $(git rev-parse A^)
B
$ git log -1 --format=%f $(git rev-parse A~^3~)
I
$ git log -1 --format=%f $(git rev-parse A^2~)
F
"निर्दिष्ट संशोधन" में git rev-parse
प्रलेखन महान जानकारी से भरा हुआ है और लायक बारे में गहराई से पढ़ा है। Git Tools भी देखें - प्रो Git पुस्तक से संशोधन चयन ।
Git के अपने इतिहास से 89e4fcb0dd प्रतिबद्ध एक मर्ज कमिटमेंट है, जैसा git show 89e4fcb0dd
कि मर्ज हेडर लाइन के साथ इंगित करता है जो तत्काल पूर्वजों के ऑब्जेक्ट नामों को प्रदर्शित करता है।
commit 89e4fcb0dd01b42e82b8f27f9a575111a26844df Merge: c670b1f876 649bf3a42f b67d40adbb Author: Junio C Hamano <gitster@pobox.com> Date: Mon Oct 29 10:15:31 2018 +0900 Merge branches 'bp/reset-quiet' and 'js/mingw-http-ssl' into nd/config-split […]
हम क्रम में git rev-parse
89e4fcb0dd के तत्काल माता-पिता को दिखाने के लिए कहकर आदेश की पुष्टि कर सकते हैं ।
$ git rev-parse 89e4fcb0dd^1 89e4fcb0dd^2 89e4fcb0dd^3
c670b1f876521c9f7cd40184bf7ed05aad843433
649bf3a42f344e71b1b5a7f562576f911a1f7423
b67d40adbbaf4f5c4898001bf062a9fd67e43368
गैर-मौजूद चौथे माता-पिता के परिणाम को त्रुटि में छोड़ देना।
$ git rev-parse 89e4fcb0dd^4
89e4fcb0dd^4
fatal: ambiguous argument '89e4fcb0dd^4': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
यदि आप केवल माता-पिता को निकालना चाहते हैं, तो पूर्ण हैश के लिए सुंदर प्रारूप का उपयोग करें%P
$ git log -1 --pretty=%P 89e4fcb0dd
c670b1f876521c9f7cd40184bf7ed05aad843433 649bf3a42f344e71b1b5a7f562576f911a1f7423 b67d40adbbaf4f5c4898001bf062a9fd67e43368
या %p
संक्षिप्त माता-पिता के लिए।
$ git log -1 --pretty=%p 89e4fcb0dd
c670b1f876 649bf3a42f b67d40adbb
^^^^^^^
करने के लिए बहुत सुविधाजनक नहीं है ~7
, क्या यह है? इसीलिए ~
यह उपयोगी है
Http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html पर पाए गए चित्रण (जॉन लॉलीगर द्वारा) के बीच का अंतर HEAD^
और HEAD~
अच्छी तरह वर्णित है ।
यह दस्तावेज़ीकरण शुरुआती लोगों के लिए थोड़ा अस्पष्ट हो सकता है, इसलिए मैंने उस चित्रण को पुन: प्रस्तुत किया है:
G H I J
\ / \ /
D E F
\ | / \
\ | / |
\|/ |
B C
\ /
\ /
A
A = = A^0
B = A^ = A^1 = A~1
C = A^2
D = A^^ = A^1^1 = A~2
E = B^2 = A^^2
F = B^3 = A^^3
G = A^^^ = A^1^1^1 = A~3
H = D^2 = B^^2 = A^^^2 = A~2^2
I = F^ = B^3^ = A^^3^
J = F^2 = B^3^2 = A^^3^2
F = A^2^
।
^ == ^1 == LEFTMOST PARENT
, ^2 == SECOND LEFTMOST PARENT
और आगे तो। और ~ == ~1 == LEFTMOST PARENT
, ~2 == LEFTMOST PARENTS LEFTMOST PARENT == LEFTMOST GRANDPARENT
। विस्तार से,~2^2 == LEFTMOST GRANDPARENTS SECOND LEFTMOST PARENT
दोनों ~
और ^
अपने स्वयं के संदर्भ के माता-पिता के संदर्भ में ( ~~
और ^^
दोनों दादा-दादी प्रतिबद्ध, आदि का उल्लेख करते हैं) लेकिन वे संख्याओं के साथ उपयोग किए जाने पर अर्थ में भिन्न होते हैं:
~2
अगर पितृपक्ष में एक से अधिक माता-पिता हैं, तो पहले अभिभावक के माध्यम से पदानुक्रम में दो स्तरों का मतलब है
^2
दूसरे माता-पिता का अर्थ है जहां एक वचन में एक से अधिक माता-पिता होते हैं (अर्थात यह एक मर्ज है)
इन्हें संयुक्त किया जा सकता है, इसलिए HEAD~2^3
इसका मतलब है HEAD
दादा-दादी की तीसरी माता-पिता की प्रतिबद्धता।
^^
जैसा था, वैसा ही है, ^2
लेकिन ऐसा नहीं है।
मेरे दो सेंट...
H=A~2^2
नहीं H=A~2^1
?
A
, B
, D
, G
उसी शाखा पर हैं और प्रतिबद्ध D
के एक मर्ज है G
और H
, इसलिए दो माता-पिता होने के। तो H
अन्य शाखा से प्रतिबद्ध ( ) संदर्भ द्वारा है ^2
।
यहाँ http://www.paulboxley.com/blog/2011/06/git-caret-and-bild/ से बहुत अच्छी व्याख्या ली गई है :
ref~
के लिए आशुलिपि हैref~1
और इसका मतलब है कि पहला माता-पिता।ref~2
का मतलब है कमिटमेंट का पहला पैरेंट का पहला पैरेंट।ref~3
का अर्थ है कमेटी का पहला अभिभावक का पहला अभिभावक का पहला अभिभावक। और इसी तरह।
ref^
के लिए आशुलिपि हैref^1
और इसका मतलब है कि पहला माता-पिता। लेकिन जहां दोनों में अंतर होता है,ref^2
मतलब है कि कमिट का दूसरा पैरेंट (याद रखें, कमिट होने पर दो पेरेंट्स हो सकते हैं जब वे मर्ज होते हैं)।
^
और~
ऑपरेटरों जोड़ा जा सकता है।
^<n>
प्रारूप आप प्रतिबद्ध के n वें माता पिता (मर्ज किए गए भाग में प्रासंगिक) का चयन करने के लिए अनुमति देता है। ~<n>
प्रारूप आप वें चयन पूर्वज प्रतिबद्ध, हमेशा पहले माता-पिता के पास निम्न की अनुमति देता है। कुछ उदाहरणों के लिए git-Rev-parse के प्रलेखन देखें ।
यह ध्यान देने योग्य है कि git में "from-where-you-आए" / "want-to-go-back-now" पर नज़र रखने के लिए एक सिंटैक्स भी है - उदाहरण के लिए, HEAD@{1}
उस जगह का संदर्भ देगा जहाँ से आप नए प्रतिबद्ध स्थान पर गए थे।
मूल रूप से HEAD@{}
चर HEAD आंदोलन के इतिहास पर कब्जा कर लेते हैं, और आप कमांड का उपयोग करके गिट के रिफ्लेक्स को देखकर एक विशेष सिर का उपयोग करने का निर्णय ले सकते हैं git reflog
।
उदाहरण:
0aee51f HEAD@{0}: reset: moving to HEAD@{5}
290e035 HEAD@{1}: reset: moving to HEAD@{7}
0aee51f HEAD@{2}: reset: moving to HEAD@{3}
290e035 HEAD@{3}: reset: moving to HEAD@{3}
9e77426 HEAD@{4}: reset: moving to HEAD@{3}
290e035 HEAD@{5}: reset: moving to HEAD@{3}
0aee51f HEAD@{6}: reset: moving to HEAD@{3}
290e035 HEAD@{7}: reset: moving to HEAD@{3}
9e77426 HEAD@{8}: reset: moving to HEAD@{3}
290e035 HEAD@{9}: reset: moving to HEAD@{1}
0aee51f HEAD@{10}: reset: moving to HEAD@{4}
290e035 HEAD@{11}: reset: moving to HEAD^
9e77426 HEAD@{12}: reset: moving to HEAD^
eb48179 HEAD@{13}: reset: moving to HEAD~
f916d93 HEAD@{14}: reset: moving to HEAD~
0aee51f HEAD@{15}: reset: moving to HEAD@{5}
f19fd9b HEAD@{16}: reset: moving to HEAD~1
290e035 HEAD@{17}: reset: moving to HEAD~2
eb48179 HEAD@{18}: reset: moving to HEAD~2
0aee51f HEAD@{19}: reset: moving to HEAD@{5}
eb48179 HEAD@{20}: reset: moving to HEAD~2
0aee51f HEAD@{21}: reset: moving to HEAD@{1}
f916d93 HEAD@{22}: reset: moving to HEAD@{1}
0aee51f HEAD@{23}: reset: moving to HEAD@{1}
f916d93 HEAD@{24}: reset: moving to HEAD^
0aee51f HEAD@{25}: commit (amend): 3rd commmit
35a7332 HEAD@{26}: checkout: moving from temp2_new_br to temp2_new_br
35a7332 HEAD@{27}: commit (amend): 3rd commmit
72c0be8 HEAD@{28}: commit (amend): 3rd commmit
एक उदाहरण यह हो सकता है कि मैंने लोकल-कमिट किया- a-> b-> c-> d और फिर मैं अपना कोड चेक करने के लिए 2 कमिट करने से पीछे हट गया git reset HEAD~2
- और फिर उसके बाद मैं अपना HEAD वापस d - में ले जाना चाहता हूं git reset HEAD@{1}
।
सरलता से :
~
पूर्वजों को निर्दिष्ट करता है^
माता-पिता को निर्दिष्ट करता हैविलय के समय आप एक या अधिक शाखाएँ निर्दिष्ट कर सकते हैं। फिर एक प्रतिबद्ध में दो या अधिक माता-पिता होते हैं और फिर ^
माता-पिता को इंगित करने के लिए उपयोगी होता है।
मान लीजिए आप शाखा पर हैं एक और आप दो और शाखाएं हैं: बी और सी ।
प्रत्येक शाखा में तीन अंतिम आवागमन होते हैं:
यदि अब शाखा A पर आप कमांड निष्पादित करते हैं:
git merge B C
फिर आप तीन शाखाओं को एक साथ जोड़ रहे हैं (यहां आपके मर्ज कमिट में तीन माता-पिता हैं)
तथा
~
पहली शाखा में n'th पूर्वज को इंगित करता है, इसलिए
HEAD~
संकेत करता है A3HEAD~2
संकेत करता है A2HEAD~3
संकेत करता है A1^
n'th माता-पिता को इंगित करता है, इसलिए
HEAD^
संकेत करता है A3HEAD^2
B3 इंगित करता हैHEAD^3
C3 इंगित करता हैपिछले पात्रों द्वारा नामित कमिट के संदर्भ में ~
या ^
एक-दूसरे के लिए अगला उपयोग है ।
सूचना 1 :
HEAD~3
हमेशा के बराबर है: HEAD~~~
और: HEAD^^^
(प्रत्येक इंगित करता है A1 ),और आम तौर पर :
HEAD~n
हमेशा के बराबर है: HEAD~...~
( n बार ~
) और to: HEAD^...^
( n times ^
)।सूचना 2 :
HEAD^3
के रूप में ही नहीं है HEAD^^^
(पहले इंगित करता है C3 और दूसरा इंगित करता है A1 ),और आम तौर पर :
HEAD^1
के रूप में ही है HEAD^
,HEAD^n
हमेशा ( n बार ) के समान नहीं होता है ।HEAD^...^
~
TLDR
~ जो आप ज्यादातर समय चाहते हैं, वह अतीत को वर्तमान शाखा के संदर्भ में बताता है
^ संदर्भ माता-पिता (git-merge एक दूसरा माता-पिता या अधिक बनाता है)
A ~ हमेशा A ^
A के समान ही होता है A ~~ हमेशा A ^^ की तरह ही होता है, और इसलिए
A ~ 2 हालांकि A ^ 2 के समान नहीं है,
क्योंकि ~ 2 ~~ के लिए आशुलिपि है,
जबकि ^ 2 नहीं है कुछ के लिए आशुलिपि, यह 2 माता पिता का मतलब है
हेड ~ एक "शाखा" पर पहला अभिभावक निर्दिष्ट करता है
HEAD ^ आपको कमिटमेंट के एक विशिष्ट अभिभावक का चयन करने की अनुमति देता है
एक उदाहरण:
यदि आप साइड ब्रांच का पालन करना चाहते हैं, तो आपको कुछ निर्दिष्ट करना होगा
master~209^2~15
सीधे शब्दों में कहें, तो पेरेंटेज के पहले स्तर (वंश, वंश, वंश, आदि) के लिए HEAD ^ और HEAD ~ दोनों एक ही कमिट की ओर इशारा करते हैं, जो HEAD (कमिट) के ऊपर एक पेरेंट है।
इसके अलावा, HEAD ^ = HEAD ^ 1 = HEAD ~ = HEAD ~ 1। लेकिन HEAD ^^! = HEAD ^ 2! = HEAD ~ 2। फिर भी सिर ^ ^ = सिर ~ 2। पढ़ते रहिये।
पेरेंटेज के पहले स्तर से परे, चीजें पेचीदा हो जाती हैं, खासकर अगर वर्किंग ब्रांच / मास्टर ब्रांच में मर्ज (दूसरी ब्रांचों से) हुई हों। कैरेट के साथ वाक्य रचना की भी बात है, HEAD ^^ = HEAD ~ 2 (वे समतुल्य हैं) BUTAD ^ ^! = HEAD ^ 2 (वे पूरी तरह से दो अलग चीजें हैं)।
प्रत्येक / कैरेट HEAD के पहले माता-पिता को संदर्भित करता है, यही वजह है कि एक साथ देखभाल की गई स्ट्रिंग टिल्ड एक्सप्रेशन के बराबर हैं, क्योंकि वे पहले माता-पिता (पहले माता-पिता के पहले माता-पिता, आदि) से संबंधित हैं, जो कनेक्टेड सेंट्स पर संख्या के आधार पर कड़ाई से आधारित हैं। या टिल्ड के बाद की संख्या पर (किसी भी तरह से, वे दोनों एक ही बात करते हैं), अर्थात पहले माता-पिता के साथ रहें और एक्स पीढ़ियों तक जाएं।
HEAD ~ 2 (या HEAD ^^) उस प्रतिबद्ध को संदर्भित करता है जो पदानुक्रम में वर्तमान प्रतिबद्ध (HEAD) से ऊपर / वंश के दो स्तर है, जिसका अर्थ है HEAD का दादा-दादी प्रतिबद्ध।
दूसरी ओर, HEAD ^ 2, पहले माता-पिता की दूसरी माता-पिता की प्रतिबद्धता को नहीं, बल्कि बस दूसरे माता-पिता की प्रतिबद्धता को दर्शाता है। ऐसा इसलिए है क्योंकि देखभाल का अर्थ है, माता-पिता का वचन, और निम्नलिखित संख्या बताती है कि कौन सा / क्या माता-पिता प्रतिबद्ध है, इस मामले में (पहले माता-पिता को संदर्भित किया जाता है, जब कैरेट का एक नंबर द्वारा पालन नहीं किया जाता है] क्योंकि यह संख्या के लिए आशुलिपि है। 1 होने के नाते, पहले माता-पिता का अर्थ है])। कैरेट के विपरीत, बाद में आने वाली संख्या, पदानुक्रम के एक और स्तर को ऊपर की ओर नहीं ले जाती है, बल्कि इसका अर्थ है कि कितने स्तर बग़ल में हैं, पदानुक्रम में, एक को सही माता-पिता (कमिट) को खोजने की आवश्यकता है। एक टिल्ड अभिव्यक्ति में संख्या के विपरीत, यह पदानुक्रम में केवल एक माता-पिता है, भले ही संख्या (तुरंत) कैरेट को आगे बढ़ा रही हो। ऊपर की बजाय, कैरेट '
तो HEAD ^ 3 HEAD प्रतिबद्ध के तीसरे माता-पिता के बराबर है (महान-दादा-दादी नहीं है, जो HEAD ^^ ^ और HEAD ~ 3 होगा ...)।