Git में "हमारा" और "उनका" का सटीक अर्थ क्या है?


323

यह एक प्रश्न के बहुत मूल की तरह लग सकता है, लेकिन मैंने उत्तरों की खोज की है और मैं पहले की तुलना में अब अधिक भ्रमित हूं।

मेरी शाखा को मेरी दूसरी शाखा में विलय करने पर "हमारा" और "उनका" क्या अर्थ है? दोनों शाखाएं "हमारी" हैं।

एक मर्ज संघर्ष में "हमारा" हमेशा प्रदर्शित किए गए दो संस्करणों के ऊपरी भाग है?

क्या "हमारा" हमेशा उस शाखा को संदर्भित करता है जो मर्ज शुरू होने पर इशारा कर रहा था? यदि ऐसा है, तो क्यों नहीं "वर्तमान शाखा" जैसे स्पष्ट उच्चारण का उपयोग करने के बजाय "हमारे" जैसे संदर्भात्मक अस्पष्ट (जैसे दोनों शाखाएं तकनीकी रूप से हमारी हैं) का उपयोग करते हैं?

या बस शाखा नाम का उपयोग करें ("हमारे" कहने के बजाय "स्थानीय मास्टर" या ऐसे कहें)?

मेरे लिए सबसे भ्रामक हिस्सा यह है कि अगर मैं एक विशिष्ट शाखा की .gitattributes फ़ाइल में निर्दिष्ट करता हूं। आइए हम परीक्षण शाखा में कहते हैं कि मेरे पास .gitattributes फ़ाइल है:

config.xml merge=ours

अब मैं चेकआउट करता हूं और HEAD को मास्टर करने के लिए इंगित करता हूं फिर टेस्ट में विलीन हो जाता हूं । चूँकि मास्टर हमारा है, और परीक्षण का .gitattributes की जाँच नहीं की जाती है, तो क्या इसका प्रभाव भी होगा? यदि इसका प्रभाव पड़ता है, क्योंकि मास्टर अब "हमारा" है, तो क्या होगा?

जवाबों:


374

मुझे संदेह है कि आप यहां भ्रमित हैं क्योंकि यह मौलिक रूप से भ्रमित है। चीजों को बदतर बनाने के लिए, जब आप रिबास कर रहे होते हैं, तो हमारा पूरा / उनका सामान स्विच रोल्स (पीछे की ओर हो जाता है) होता है।

अंत में, एक के दौरान git merge, "हमारा" शाखा शाखा आप विलय कर रहे हैं को संदर्भित करता है में :

git checkout merge-into-ours

और "उनकी" शाखा से तात्पर्य उस एकल (एकल) शाखा से है जिसका आप विलय कर रहे हैं:

git merge from-theirs

और यहाँ "हमारा" और "उनकी" कुछ समझ में आता है, के रूप में भले ही "उनकी" शायद तुम्हारा वैसे भी है, "उनकी" एक तुम थे नहीं है पर जब आप भाग गया git merge

वास्तविक शाखा नाम का उपयोग करते समय यह बहुत अच्छा हो सकता है, यह अधिक जटिल मामलों में गिर जाता है। उदाहरण के लिए, ऊपर के बजाय, आप ऐसा कर सकते हैं:

git checkout ours
git merge 1234567

जहां आप कच्चे कमिट-आईडी द्वारा विलय कर रहे हैं। इससे भी बदतर, आप यह भी कर सकते हैं:

git checkout 7777777    # detach HEAD
git merge 1234567       # do a test merge

जिस स्थिति में कोई शाखा के नाम शामिल नहीं हैं!

मुझे लगता है कि यह यहाँ थोड़ी मदद है, लेकिन वास्तव में, gitrevisionsवाक्यविन्यास में , आप एक द्वंद्व में विलय के दौरान सूचकांक में एक व्यक्तिगत पथ का उल्लेख कर सकते हैं।

git show :1:README
git show :2:README
git show :3:README

स्टेज # 1 फाइलों का सामान्य पूर्वज है, स्टेज # 2 लक्ष्य-शाखा संस्करण है, और चरण # 3 वह संस्करण है जिसे आप विलय कर रहे हैं।


"हमारा" और "उनकी" धारणाओं के दौरान चारों ओर स्वैप हो जाने का rebaseकारण यह है कि रीबेज चेरी-पिक्स की एक श्रृंखला को एक अनाम शाखा (अलग किए गए हेड मोड) में काम करता है। लक्ष्य शाखा अनाम शाखा है, और मर्ज से शाखा आपकी मूल (पूर्व-रीबेस) शाखा है: इसलिए "--ours" का अर्थ है अनाम एक रिबास का निर्माण हो रहा है जबकि "- उनकी" का अर्थ है "हमारी शाखा का विद्रोह किया जा रहा है" ।


Gitattributes प्रविष्टि के लिए: इसका प्रभाव हो सकता है: "हमारा" वास्तव में "आंतरिक रूप से चरण 2" का उपयोग करता है। लेकिन जैसा कि आप ध्यान दें, यह वास्तव में उस समय नहीं है, इसलिए इसका प्रभाव यहां नहीं होना चाहिए ... ठीक है, तब तक नहीं जब तक कि आप इसे शुरू करने से पहले काम के पेड़ में कॉपी न करें।

इसके अलावा, वैसे, यह हमारे और उनके सभी उपयोगों पर लागू होता है, लेकिन कुछ एक संपूर्ण फ़ाइल स्तर पर हैं ( -s oursएक मर्ज रणनीति के लिए, git checkout --oursएक मर्ज संघर्ष के दौरान) और कुछ एक टुकड़ा-दर-टुकड़ा आधार पर हैं ( -X oursया -X theirsएक दौरान; -s recursiveमर्ज)। जो शायद किसी भी उलझन में मदद नहीं करता है।

मैं इन के लिए एक बेहतर नाम के साथ कभी नहीं आया, हालांकि। और: VonC के एक अन्य प्रश्न के उत्तर को देखें , जहां git mergetoolइन के लिए और अधिक नामों का परिचय दिया गया है, उन्हें "स्थानीय" और "रिमोट" कहा जाता है!


28
+1। रिबेश के दौरान हमारे और उनके उलट होने के बारे में, यह भी देखें: stackoverflow.com/a/2960751/6309 और stackoverflow.com/a/3052118/6309
VonC

1
दो चीजें "एक दूसरे के साथ" विलीन हो जाती हैं। जब एक मर्ज होता है तो दोनों पक्ष "एक-दूसरे" में विलीन हो जाते हैं। मुझे लगता है कि यह कहना गलत होगा कि दोनों पक्षों में से एक "किसी भी चीज में विलय नहीं है" है। यदि कोई शाखा नाम शामिल नहीं हैं (जैसा कि आप बताते हैं) तो प्रतिबद्ध नाम शामिल हैं (आप "7777777 के" और "1234567 के" "हमारे" और "उनके" के बजाय) कह सकते हैं। मैं समझता हूं कि एक रिबेस के दौरान क्या होता है और मुझे यह बिल्कुल भी भ्रामक नहीं लगता। मुझे लगता है कि "HEAD" और "इनकमिंग" "हमारे" और "उनके" की तुलना में बेहतर काम करेंगे क्योंकि हमेशा एक "HEAD" होता है (चाहे वह अलग हो या नहीं)।
CommaToast

15
मुझे लगता है कि चूंकि सिर मन की सीट है, जो पहचान का स्रोत है, जो स्वयं का स्रोत है, यह हेड के रूप में "मेरा" ("हमारा" होने के लिए जो कुछ भी इंगित करता है, उसके बारे में सोचने के लिए थोड़ा अधिक समझ में आता है) मुझे लगता है कि और हेड दो बनाता है)। अगर इससे ज्यादा कुछ नहीं है, तो वह सिर्फ एक अच्छा मेमेनिक डिवाइस होगा।
CommaToast

1
कहा जा रहा है, मैं अभी भी कुछ भी करने से पहले पूरी रेपो की एक फिजिकल कॉपी बनाना पसंद करता हूं ...: D
CommaToast

3
"जिस स्थिति में कोई शाखा के नाम शामिल नहीं हैं!" ... इसलिए उसे इसके बजाय प्रतिबद्ध टिप्पणी / हैश का उपयोग करना चाहिए। जो भी मिल जाए अपने हाथों पर। व्यावहारिक रूप से कुछ भी "हमारे" और "उनके" से बेहतर होगा। मुझे आश्चर्य है कि कितने हजारों देव घंटों इस भ्रम को वाष्पित कर चुके हैं। G ++ का जवाब C ++ के "सबसे डरावने तोते";)
जारोद स्मिथ

49

Git में ' हमारा ' उस मूल कार्य शाखा की बात कर रहा है, जिसमें git इतिहास का आधिकारिक / विहित भाग है।

' उनका ' उस संस्करण को संदर्भित करता है जो कार्य को पुन: व्यवस्थित करने के लिए रखता है (वर्तमान शाखा पर पुनरावृत्त होने के लिए परिवर्तन)।

यह उन लोगों को बदली हुई दिखाई दे सकती है जिन्हें इस बात की जानकारी नहीं है कि रिबासिंग करना (जैसे git rebase) वास्तव में आपके काम को होल्ड पर ले जा रहा है (जो उनका है ) जो कि कैनोनिकल / मेन हिस्ट्री पर रीप्ले करने के लिए है जो हमारा है , क्योंकि हम अपना रिबास कर रहे हैं तृतीय-पक्ष कार्य के रूप में परिवर्तन।

के लिए दस्तावेज़ git-checkoutआगे Git में स्पष्ट किया गया> = 2.5.1 के अनुसार f303016प्रतिबद्ध :

--ours --theirs

अनुक्रमणिका से पथों की जाँच करते समय, अनर्जित पथों के लिए चरण # 2 ('हमारा') या # 3 ('उनका') देखें।

ध्यान दें कि दौरान git rebaseऔर git pull --rebase'हमारा' और 'उनका' की अदला-बदली हो सकती है; --oursजिस संस्करण में परिवर्तन किए गए हैं, --theirsउस शाखा से संस्करण देता है , जबकि उस शाखा से संस्करण देता है जो आपके काम को रोकती है।

इसका कारण यह है है rebaseएक कार्यप्रवाह कि व्यवहार करता है साझा विहित एक है, और व्यवहार करता है काम शाखा आप तृतीय-पक्ष के रूप में काम कर रहे हैं रिबेसिंग पर किया के रूप में दूरदराज में इतिहास एकीकृत किया जा करने के लिए प्रयोग किया जाता है, और आप अस्थायी रूप से की भूमिका मानते हैं विद्रोह के दौरान विहित इतिहास के रक्षक। विहित इतिहास के रक्षक के रूप में, आपको इतिहास को रिमोट से देखने की आवश्यकता है ours(जैसे कि "हमारा साझा विहित इतिहास"), जबकि आपने अपनी साइड ब्रांच पर क्या किया था theirs(यानी "इसके ऊपर एक योगदानकर्ता का काम")।

इसके git-mergeलिए निम्नलिखित तरीके से व्याख्या करें:

हमारा

यह विकल्प हमारे संस्करण के पक्ष में सफाई से स्वतः हल होने के लिए विरोधी हॉक को रोकता है। दूसरे पेड़ से परिवर्तन जो हमारे पक्ष के साथ संघर्ष नहीं करते हैं, मर्ज के परिणाम परिलक्षित होते हैं। एक बाइनरी फ़ाइल के लिए, पूरी सामग्री हमारी तरफ से ली गई है।

यह हमारी विलय की रणनीति के साथ भ्रमित नहीं होना चाहिए, जो यह भी नहीं देखता है कि दूसरे पेड़ में क्या है। यह सब कुछ करता है जो दूसरे पेड़ ने किया था, हमारे इतिहास को घोषित करने में वह सब शामिल है जो इसमें हुआ था।

उन लोगों के

यह हमारे विपरीत है।

इसके अलावा, यहां बताया गया है कि उनका उपयोग कैसे करें:

मर्ज मैकेनिज्म ( git mergeऔर git pullकमांड्स) बैकएंड मर्ज की रणनीतियों को -sविकल्प के साथ चुनने की अनुमति देता है । कुछ रणनीतियाँ अपने स्वयं के विकल्प भी ले सकती हैं, जिन्हें / और / या -X<option>तर्क देकर पारित किया जा सकता है ।git mergegit pull


इसलिए कभी-कभी यह भ्रामक हो सकता है, उदाहरण के लिए:

  • git pull origin masterजहां -Xoursहमारा स्थानीय है, -Xtheirsउनकी (दूरस्थ) शाखा है
  • git pull origin master -rजहां -Xoursउनकी (रिमोट) है, -Xtheirsहमारा है

तो दूसरा उदाहरण 1 के विपरीत है, क्योंकि हम अपनी शाखा को रिमोट के शीर्ष पर रिबास कर रहे हैं, इसलिए हमारा प्रारंभिक बिंदु दूरस्थ है, और हमारे परिवर्तनों को बाहरी माना जाता है।

git mergeरणनीतियों ( -X oursऔर -X theirs) के लिए समान ।


2
यह उत्तर तारीख से बाहर लगता है => "git merge --ours" एक वैध विकल्प नहीं है
अलेक्जेंडर मिल्स

@AlexanderMills जवाब के बारे में बात नहीं की थी git merge, लेकिन git pullऔर git checkoutउदाहरण के रूप में। यदि आप इस पैरामीटर का उपयोग करना पसंद करते हैं git merge, तो आपको उपयोग करना चाहिए -X ours। आप अभी भी के लिए --oursवाक्यविन्यास का उपयोग कर सकते हैं git checkout। मैंने उत्तर को और अधिक स्पष्ट किया है।
kenorb

46

मुझे पता है कि यह उत्तर दिया गया है, लेकिन इस मुद्दे ने मुझे बहुत बार भ्रमित किया है मुझे याद रखने में मदद करने के लिए एक छोटी सी संदर्भ वेबसाइट डाल दी है: https://nitaym.github.io/ourstheirs/

यहाँ मूल बातें हैं:

एक बनाए गए:

$ git checkout master 
$ git merge feature

यदि आप में संस्करण का चयन करना चाहते हैं master:

$ git checkout --ours codefile.js

यदि आप में संस्करण का चयन करना चाहते हैं feature:

$ git checkout --theirs codefile.js

Rebases:

$ git checkout feature 
$ git rebase master 

यदि आप में संस्करण का चयन करना चाहते हैं master:

$ git checkout --ours codefile.js

यदि आप में संस्करण का चयन करना चाहते हैं feature:

$ git checkout --theirs codefile.js

(यह पूरी फ़ाइलों के लिए है, बिल्कुल)


1
वह वेबसाइट सुपर-सहायक है। प्रवाह-चार्ट शैली और रंग-कोडित शब्द वेबसाइट को SO के उत्तरों की तुलना में समझने में बहुत आसान बनाते हैं। धन्यवाद।
रॉन

10
  • हमारा : यह वह शाखा है जिस पर आप वर्तमान में हैं।
  • उनकी : यह दूसरी शाखा है जिसका उपयोग आपकी कार्रवाई में किया जाता है।

इसलिए यदि आप शाखा विमोचन / 2.5 पर हैं और आप शाखा सुविधा / नए-बटनों को मर्ज करते हैं, तो रिलीज़ / 2.5 में मिली सामग्री वही है जो हमारा संदर्भित करता है और सामग्री जैसा कि फ़ीचर / नए-बटनों पर पाया जाता है, जो उनका संदर्भ है सेवा। एक मर्ज कार्रवाई के दौरान यह बहुत सीधे आगे है।

ज्यादातर लोगों के लिए एकमात्र समस्या रिबेस केस है । यदि आप सामान्य मर्ज के बजाय पुनः आधार करते हैं, तो भूमिकाएँ बदली जाती हैं। सो कैसे? ठीक है, यह पूरी तरह से रीबासिंग के काम करने के कारण होता है। इस तरह काम करने के लिए रिबास के बारे में सोचें:

  1. आपके अंतिम खींचतान के बाद से आपके द्वारा किए गए सभी कमेंट्स को उनकी खुद की एक शाखा में स्थानांतरित कर दिया जाता है, आइए इसे ब्रांचएक्स नाम दें
  2. आप अपनी वर्तमान शाखा के प्रमुख की जांच करते हैं, आपके द्वारा किए गए किसी भी स्थानीय परिवर्तन को छोड़ते हुए, लेकिन सभी परिवर्तनों को पुनः प्राप्त करने का तरीका दूसरों को उस शाखा के लिए धक्का देता है।
  3. अब ब्रांचएक्स पर हर कमिटमेंट चेरी से उठाया जाता है, जो आपकी वर्तमान ब्रांच के लिए पुराना है।
  4. BranchX को फिर से हटा दिया गया है और इस प्रकार यह किसी भी इतिहास में दिखाई नहीं देगा।

बेशक, यह वास्तव में क्या हो रहा है, लेकिन यह मेरे लिए एक अच्छा दिमाग मॉडल नहीं है। और यदि आप 2 और 3 को देखते हैं, तो आप समझ जाएंगे कि अब भूमिकाओं की अदला-बदली क्यों की जाती है। 2 के रूप में, आपकी वर्तमान शाखा अब आपके किसी भी परिवर्तन के बिना सर्वर से शाखा है, इसलिए यह हमारा है (आप जिस शाखा पर हैं)। आपके द्वारा किए गए परिवर्तन अब एक अलग शाखा पर हैं जो आपका वर्तमान एक ( BranchX ) नहीं है और इस प्रकार ये परिवर्तन (आपके द्वारा किए गए परिवर्तन होने के बावजूद) उनके हैं (आपकी कार्रवाई में प्रयुक्त दूसरी शाखा)।

इसका मतलब है कि यदि आप विलय करते हैं और आप चाहते हैं कि आपके परिवर्तन हमेशा जीतें, तो आप हमेशा "हमारा" चुनने के लिए गिट को बताएंगे, लेकिन यदि आप रिबेट करते हैं और आप चाहते हैं कि आपके सभी परिवर्तन हमेशा जीतें, तो आप "हमेशा" उनका चयन करने के लिए कहेंगे।


3

मुझे पता है कि यह अर्थ नहीं समझाता है लेकिन मैंने खुद को एक छोटी सी छवि बना ली है, यह याद दिलाने के लिए कि किसका उपयोग करना है:

यहां छवि विवरण दर्ज करें

आशा है ये मदद करेगा!

PS - निते के उत्तर में लिंक पर एक चेक भी दें also


3

मैं यहां अपना ज्ञापन पोस्ट करूंगा, क्योंकि मुझे बार-बार यहां आना है।

स्कोरर 1. सामान्य डेवलपर: आप ऐसे डेवलपर हैं जो विलय नहीं कर सकते हैं masterऔर featureकेवल शाखाओं के साथ खेलना है ।

केस 1: मास्टर एक राजा है। आप अपनी featureशाखा (= रिबेस master) को रिफ्रेश करना चाहते हैं , क्योंकि masterनिर्भरता के नए अपडेट हैं और आप अपने मामूली बदलावों को अधिलेखित करना चाहते हैं।

git checkout master
git pull

git checkout feature
git rebase -X ours master

केस 2: आप एक राजा हैं। आप परिवर्तनों के featureलिए अपनी शाखा को फिर से बनाना चाहते हैं master। लेकिन आपने अपने सहयोगियों की तुलना में अधिक किया था और अपने स्वयं के परिवर्तनों को प्राथमिकता में रखना चाहते थे।

git checkout master
git pull

git checkout feature
git rebase -X theirs master

महत्वपूर्ण: जैसा कि आप देख सकते हैं कि सामान्य डेवलपर्स को rebaseहर सुबह व्यायाम और कॉफी की तरह इसे पसंद करना चाहिए ।

SCENARIO 2. विलय-संवेदी: आप एक टीम-लीड हैं और अन्य शाखाओं को मर्ज करना चाहते हैं और एक मर्ज किए गए परिणाम को सीधे एक मास्टर को धक्का देते हैं। masterएक शाखा है जिसे आप बदलेंगे।

केस 1: मास्टर एक राजा है आप तीसरे पक्ष की शाखा का विलय करना चाहते हैं, लेकिन masterएक प्राथमिकता है। featureएक शाखा है जो आपके वरिष्ठ ने की थी।

git checkout feature
git pull

git checkout master
git merge -X ours master

केस 2: नया बदलाव एक राजा है जब आपके वरिष्ठ डेवलपर ने एक कूल जारी किया featureऔर आप masterशाखा में पुराने एस ** टी को अधिलेखित करना चाहते हैं ।

git checkout feature
git pull

git checkout master
git merge -X theirs master

याद: आधी रात को एक को चुनना है, जिसमें याद करने के लिए masterहै oursहमेशा। और theirsयह है featureकि उनका किया है।


2

के git checkoutउपयोग से:

-2, --ours            checkout our version for unmerged files
-3, --theirs          checkout their version for unmerged files
-m, --merge           perform a 3-way merge with the new branch

जब मर्ज संघर्षों को हल करते हैं git checkout --theirs some_file, तो आप कर सकते हैं , और git checkout --ours some_fileफ़ाइल को वर्तमान संस्करण और आने वाले संस्करणों के लिए क्रमशः रीसेट करें।

यदि आपने किया है git checkout --ours some_fileया git checkout --theirs some_fileफ़ाइल को फ़ाइल के 3-वे मर्ज संस्करण में रीसेट करना चाहते हैं, तो आप कर सकते हैं git checkout --merge some_file

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.