"हमारा" और "उनका" का अर्थ git-svn से उलट क्यों है


90

मैं git-svn का उपयोग करता हूं और मैंने देखा कि जब मुझे प्रदर्शन करने के बाद मर्ज संघर्ष को ठीक करना होता है git svn rebase, तो उदा का विकल्प --oursऔर --theirsविकल्प git checkoutउलट जाता है। यही है, अगर कोई संघर्ष है और मैं SVN सर्वर से आए संस्करण को रखना चाहता हूं और स्थानीय रूप से किए गए परिवर्तनों को दूर कर दूंगा, तो मुझे इसका उपयोग oursकरना होगा, जब मुझे इसकी उम्मीद होगी theirs

ऐसा क्यों है?

उदाहरण:

mkdir test
cd test
svnadmin create svnrepo
svn co file://$PWD/svnrepo svnwc
cd svnwc
echo foo > test.txt
svn add test.txt
svn ci -m 'svn commit 1'
cd ..
git svn clone file://$PWD/svnrepo gitwc
cd svnwc
echo bar > test.txt 
svn ci -m 'svn commit 2'
cd ..
cd gitwc
echo baz > test.txt 
git commit -a -m 'git commit 1'
git svn rebase

git checkout --ours test.txt
cat test.txt 
# shows "bar" but I expect "baz"

git checkout --theirs test.txt
cat test.txt 
# shows "baz" but I expect "bar"

जूट ने "हमारा" और "उनके" पक्षों को बेहतर ढंग से चित्रित करने के लिए बहुत सारे आरेखों के साथ मेरे उत्तर को अपडेट किया।
वॉन

1
यह भी देखें github.com/git/git/commit/…
VonC

जवाबों:


230

ऐसा लगता है कि एक रिबेस क्या करता है।

  • git svn rebase वर्तमान HEAD के SVN माता-पिता से संशोधन प्राप्त करेगा और वर्तमान (SVN को अनधिकृत) इसके विरुद्ध कार्य करता है।

  • git rebaseउल्लेख करता है:
    ध्यान दें कि एक रिबेस मर्ज शाखा के शीर्ष पर काम करने वाली शाखा से प्रत्येक कमिट को पुन : जोड़कर काम करता है <upstream>
    इस वजह से, जब एक मर्ज संघर्ष होता है:

    • हमारी ओर से रिपोर्ट की गई, अब तक की शुरू की गई श्रृंखला है<upstream> ,
    • और उनकी काम करने वाली शाखा है
      दूसरे शब्दों में, पक्षों की अदला-बदली की जाती है

git rebase प्रत्येक शाखा के शीर्ष पर कार्यरत शाखा से पुनरीक्षण करता है <upstream>

यदि आप दोनों परिभाषाओं को समेटते हैं:

  • एसवीएन से आने वाले कमिट्स ऊपर हैं, जिनमें से स्थानीय गिट कमिट्स फिर से शुरू होते हैं। वे "अब तक की विद्रोही श्रृंखला" का हिस्सा हैं, और "हमारे" (आपके मामले में, test.txtफ़ाइल के साथ bar) के रूप में संदर्भित हैं
  • काम करने वाली शाखा (Git युक्त, SVN के लिए अज्ञात है, आपके मामले में, सामग्री के test.txtसाथ फ़ाइल baz) "उनका" है, और उन स्थानीय Git कमिट में से प्रत्येक को फिर से दोहराया जा रहा है।

दूसरे शब्दों में, एसवीएन या नहीं:

  • " <upstream>" शाखा (जिसके ऊपर से कुछ भी फिर से शुरू होता है, और जो अब तक किए गए कमिट का हिस्सा है ")" हमारा "है।
  • जो रिप्ले किया जा रहा है (वर्किंग ब्रांच) " उनका " है।

CommaToast द्वारा अच्छा मेमनोनिक टिप :

जो भी HEAD की ओर इशारा करता है वह है "हमारा"

(और सबसे पहली बात git rebase upstreamयह है upstreamकि आप उस शाखा को चेकआउट करना चाहते हैं जिसके शीर्ष पर आप रिबास करना चाहते हैं: HEAD का अर्थ है upstream- oursअब।)


भ्रम की संभावना एक क्लासिक में काम करने वाली शाखा की भूमिका से आ रही है git merge
जब आप विलय कर रहे हैं:

  • "वर्किंग ब्रांच" वह है जिसमें "अभी तक मर्ज किया गया" है, और जिसे "हमारा" माना जाता है,
  • जबकि दूसरी प्रतिबद्धता यह दर्शाती है कि क्या किया जा रहा है - रिप्ले नहीं किया गया है - लेकिन वर्किंग ब्रांच के शीर्ष पर मर्ज किया गया है, और "उनका" माना जाता है।

जैसा कि git rebaseमैन पेज का उल्लेख है, एक रिबेस के दौरान मर्ज का अर्थ है कि पक्ष अदला-बदली है।


एक ही बात कहने का एक और तरीका यह है कि:

  • हमारे पास जो चेक आउट शाखा है वह ' हमारी ' है।
  • जो हमारे पास था (और विलीन हो रहा है या फिर से बनाया जा रहा है) ' उनका ' है।

एक मर्ज पर :

x--x--x--x--x(*) <- current branch B ('*'=HEAD)
    \
     \
      \--y--y--y <- other branch to merge

, हम वर्तमान शाखा 'बी' को नहीं बदलते हैं, इसलिए हमारे पास अभी भी वही है जो हम काम कर रहे थे (और हम दूसरी शाखा से विलय करते हैं)

x--x--x--x--x---------o(*)  MERGE, still on branch B
    \       ^        /
     \     ours     /
      \            /
       --y--y--y--/  
               ^
              their

लेकिन एक रिबास पर , हम पक्ष बदल देते हैं क्योंकि रिबास की पहली चीज अपस्ट्रीम शाखा को चेकआउट करना है! (वर्तमान में इसके शीर्ष पर पुनरावृत्ति करने के लिए)

x--x--x--x--x(*) <- current branch B
    \
     \
      \--y--y--y <- upstream branch

A git rebase upstreamपहले HEADB को अपस्ट्रीम ब्रांच में बदलेगा HEAD(इसलिए पिछले "वर्तमान" वर्किंग ब्रांच की तुलना में 'हमारा' और 'उनका' का स्विच।)

x--x--x--x--x <- former "current" branch, new "theirs"
    \
     \
      \--y--y--y(*) <- upstream branch with B reset on it,  
                       new "ours", to replay x's on it

, और फिर रिबास नई 'हमारी' बी शाखा पर अपने 'कमिट्स' को फिर से चलाएगा:

x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs
    \
     \
      \--y--y--y--x'--x'--x'(*) <-  branch B with HEAD updated ("ours")
               ^
               |
        upstream branch

के साथ एकमात्र अतिरिक्त कदम git svn rebaseयह है कि एसवीएन का प्रतिनिधित्व करने वाली जीआईटी रिमोट शाखा पर एक svn "लाने" का प्रदर्शन पहले किया जाता है।
आपके पास शुरू में है:

x--x--x--x--x(*) <- current branch B, "ours" for now.
    \                                   
     \
      \--y--y--y <- SVN tracking branch, "theirs for now"

, आप पहले SVN से आने वाले नए कमिट के साथ SVN ट्रैकिंग ब्रांच को अपडेट करें

x--x--x--x--x(*) <- current branch B, still "ours", not for long
    \                                   
     \
      \--y--y--y--y'--y' <- SVN tracking branch updated

, फिर आप करंट ब्रांच को SVN साइड पर स्विच करें (जो "हमारा" बन जाता है)

x--x--x--x--x <- for "B", now "their" during the rebase
    \                                   
     \
      \--y--y--y--y'--y'(*) <- SVN tracking branch updated, and branch B: 
                               now "ours" (this is "what we now have")

, उन कामों को फिर से शुरू करने से पहले (लेकिन जो उस रिबास के दौरान "उनके" हैं)

x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs
    \
     \
      \--y--y--y--y'--y'--x'--x'--x'(*) <-  branch B with HEAD updated ("ours")
                      ^
                      |
        upstream SVN tracking branch

9
वाह, क्या शानदार जवाब है, धन्यवाद! मुझे वह टिप्पणी पूरी तरह से git rebaseमैन पेज में याद आ गई होगी ...
मार्क लियानेज

@epologee: आपका स्वागत है। यह तब भी उपयोगी है जब आप केवल गिट का उपयोग कर रहे हैं, यह समझने के लिए कि रिबेस बनाम मर्ज के दौरान क्या हो रहा है। और यह अपस्ट्रीम परिभाषा में जोड़ता है: stackoverflow.com/questions/2739376/…
VONC

5
हे भगवान!!! Torvalds किस तरह की दवाएं ले रहा था? यह बहुत जटिल है! गिट एक बहुत ही खतरनाक उपकरण है। यदि आप बाहरी ज्ञान या अपने अंतर्ज्ञान का उपयोग करने की कोशिश करते हैं, तो आप अपने सभी कार्यों को आसानी से नष्ट कर सकते हैं। सोफवेयर विकास कीड़ा छेद से नीचे चला गया है!
ATL_DEV

@ user148298 इस फ़ंक्शन के लिए कुछ भी गलत नहीं है। जब तक आप गिट एक्सपर्ट नहीं होते हैं, तब तक आपको उन सभी चीजों को जानने की जरूरत नहीं है। और अगर आपको उन्नत कार्यों की आवश्यकता है, तो आपको इसे पहले सीखना होगा।
पृथ्वी इंजन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.