मैं git में मर्ज का पूर्वावलोकन कैसे कर सकता हूं?


397

मेरे पास एक गिट शाखा है (उदाहरण के लिए मेनलाइन), और मैं एक और विकास शाखा में विलय करना चाहता हूं। या करूँ?

यह तय करने के लिए कि क्या मैं वास्तव में इस शाखा का विलय करना चाहता हूं, मैं यह देखना चाहता हूं कि मर्ज क्या करेगा। अधिमानतः लागू होने वाले कमिट की सूची देखने की क्षमता के साथ।

अब तक, सबसे अच्छा मैं साथ आ सकता हूं merge --no-ff --no-commitऔर फिर diff HEAD


17
मैं सिर्फ git mergeऔर git reset --keep HEAD@{1}अगर मुझे परिणाम पसंद नहीं है।
Jan Hudec

3
ध्यान दें कि उनके अंतर के साथ आने की सूची को देखना पूरी कहानी जरूरी नहीं है - यदि मर्ज गैर-तुच्छ है, और विशेष रूप से यदि संघर्ष हैं, तो मर्ज का वास्तविक परिणाम थोड़ा दिलचस्प हो सकता है।
Cascabel

2
आपकी मूल विधि ठीक यही करती है। मेरी टिप्पणी की बात यह है कि यद्यपि व्यक्तिगत भिन्नताओं को देखना सभी अच्छी तरह से और अच्छा है, यदि आपके पास एक जटिल मर्ज है, तो आप आश्चर्यजनक परिणाम के साथ समाप्त हो सकते हैं, भले ही सभी मर्ज किए गए स्वतंत्र रूप से अच्छे हों।
Cascabel

2
@ जान: कुछ कारणों से, मदद git reset --keep HEAD@{1}लौटा दी fatal: Cannot do a keep reset in the middle of a merge.?
मूए

3
--previewGit-merge में कोई विकल्प क्यों नहीं है ?
गौई

जवाबों:


283

मैंने पाया है कि समाधान मेरे लिए सबसे अच्छा काम करता है बस मर्ज करना और इसे समाप्त करना अगर संघर्ष है । यह विशेष वाक्यविन्यास मुझे साफ और सरल लगता है। यह नीचे 2 रणनीति है

हालाँकि, यदि आप यह सुनिश्चित करना चाहते हैं कि आप अपनी वर्तमान शाखा में गड़बड़ी न करें, या आप संघर्षों के अस्तित्व की परवाह किए बिना विलय के लिए तैयार नहीं हैं, तो बस एक नई उप-शाखा बनाएं और उसमें विलय करें:

रणनीति 1: सुरक्षित तरीका - एक अस्थायी शाखा को मर्ज करें:

git checkout mybranch
git checkout -b mynew-temporary-branch
git merge some-other-branch

इस तरह आप केवल अस्थायी शाखा को फेंक सकते हैं यदि आप केवल यह देखना चाहते हैं कि संघर्ष क्या हैं। आपको मर्ज को "गर्भपात" से परेशान करने की आवश्यकता नहीं है, और आप अपने काम पर वापस जा सकते हैं - बस फिर से 'mybranch' चेकआउट करें और आपके शाखा में कोई मर्ज किए गए कोड या मर्ज का विरोध नहीं होगा।

यह मूल रूप से एक ड्राई-रन है।

रणनीति 2: जब आप निश्चित रूप से विलय करना चाहते हैं, लेकिन केवल अगर संघर्ष नहीं हैं

git checkout mybranch
git merge some-other-branch

यदि जीआईटी संघर्षों की रिपोर्ट करता है (और केवल अगर वहां संघर्ष हैं) तो आप कर सकते हैं:

git merge --abort

यदि मर्ज सफल है, तो आप इसे निरस्त नहीं कर सकते (केवल रीसेट)।

यदि आप विलय करने के लिए तैयार नहीं हैं, तो ऊपर सुरक्षित तरीके का उपयोग करें।

[संपादित करें: २०१६-नवंबर - मैंने २ के लिए रणनीति १ की अदला-बदली की, क्योंकि ऐसा लगता है कि ज्यादातर लोग "सुरक्षित तरीका" ढूंढ रहे हैं। रणनीति 2 अब एक नोट के अधिक है कि आप केवल मर्ज को समाप्त कर सकते हैं यदि मर्ज में संघर्ष है जो आप से निपटने के लिए तैयार नहीं हैं। टिप्पणी पढ़ते समय ध्यान रखें!]


2
+1 रणनीति के लिए 2. अस्थायी शाखा जो यह बताती है कि विलय के समय क्या होगा। रणनीति 1 वह है जो मैं इस विशेष मामले से बचने की कोशिश कर रहा हूं।
गॉर्डोलियो

2
मेरा सुझाव है कि आसपास की रणनीतियों को बदलना सबसे सुरक्षित है (मेरी मानसिक प्रशिक्षण के माध्यम से आ रहा है - ज्यादातर लोग मानेंगे कि सबसे अच्छा विकल्प "सुरक्षित" शब्द के स्पष्ट उपयोग के बावजूद पहला होगा), लेकिन इसके अलावा, उत्कृष्ट काम।
पाक्सिडाब्लो

6
तुम एक कर सकता है git merge --no-ff --no-commitअगर आप सीधे परिवर्तन प्रतिबद्ध करने के लिए नहीं करना चाहती। यह एक अलग शाखा के लिए "आवश्यकता" को समाप्त करता है यह परिवर्तनों की समीक्षा करने के लिए एक छोटा सा आसान बनाता है, इमो।
जेरार्ड वैन हेल्डेन

और अगर आप तय करते हैं कि आप बिलकुल भी विलय नहीं करना चाहते हैं और वास्तव में कुछ और कोड लिखना चाहते हैं और फिर अपनी शाखा के लिए प्रतिबद्ध हैं, तो आप एक टेस्ट सर्वर पर बस अपनी शाखा को तैनात कर सकते हैं, क्या आपको अभी भी वापस नहीं लौटना होगा git merge --no-ff --no-commit? मुझे लगता है कि आप git merge --abortउसके बाद भी कर सकते हैं यदि आपको वह नहीं पसंद है जो आप देखते हैं? भले ही मर्ज संघर्ष का उत्पादन नहीं करता है?
कासापो

ज्यादातर लोग कॉपी और पेस्ट करना पसंद करते हैं और बहुत ज्यादा नहीं सोचते हैं। इसलिए, रणनीति 1 के लिए, शायद यह भी जोड़ें कि अस्थायी स्थानीय शाखा में विलय को कैसे रद्द करें git reset --hard HEADऔर फिर एक अलग शाखा की जांच करें git checkout <different branch name>और अस्थायी शाखा को हटा दें git delete -b <name of temporary branch>
user3613932

400
  • git log ..otherbranch
    • उन परिवर्तनों की सूची जिन्हें वर्तमान शाखा में मिला दिया जाएगा।
  • git diff ...otherbranch
    • आम पूर्वज (मर्ज बेस) से अलग करें जो विलय हो जाएगा। तीन डॉट्स पर ध्यान दें , जिसमें दो डॉट्स की तुलना में एक विशेष अर्थ है (नीचे देखें)।
  • gitk ...otherbranch
    • पिछली बार विलय होने के बाद से शाखाओं का चित्रमय प्रतिनिधित्व।

खाली स्ट्रिंग का अर्थ है HEAD, इसीलिए सिर्फ ..otherbranchइसके बजाय HEAD..otherbranch

दो बनाम तीन बिंदु सूची संशोधन (लॉग, गिटक इत्यादि) की तुलना में भिन्न के लिए थोड़ा अलग अर्थ रखते हैं। लॉग और अन्य के लिए दो डॉट्स ( a..b) का अर्थ है वह सब कुछ जो bनहीं है aऔर तीन डॉट्स ( a...b) का अर्थ है वह सब कुछ जो केवल एक में है aया b। लेकिन दो संशोधनों और वहाँ सरल मामले दो डॉट्स द्वारा प्रतिनिधित्व (साथ diff काम करता है a..b) से सरल अंतर नहीं है aकरने के लिए bऔर तीन बिंदु ( a...b) सामान्य पूर्वज और के बीच मतलब अंतर b( git diff $(git merge-base a b)..b)।


7
तीसरी बिंदी वह हिस्सा था जो मुझे याद आ रहा था, धन्यवाद! लॉग दृष्टिकोण भी अच्छी तरह से काम करता है, लॉग -p --reverse ..otherbranch यह देखने के लिए एक अच्छा तरीका है कि विलय में क्या होगा।
ग्लेनजामिन

1
git checkout masterइससे पहले कि मैं यह कोशिश कर रहा था मैं गायब था । मैं सोच रहा था कि ऐसा क्यों कहा जा रहा है कि मेरे सारे बदलाव अति-लिखित होने जा रहे थे ...
दरोगाओं

5
git show ..otherbranchपरिवर्तनों की एक सूची दिखाएंगे और अलग-अलग होंगे जो वर्तमान शाखा में विलय हो जाएंगे।
गौई

4
यह पूरी तरह से सही नहीं है, खासकर चेरी पिक्स के लिए।
void.pointer

2
@ void.pointer, git चेरी-पिक्स का विशेष रूप से सामान्य मर्ज में इलाज नहीं करता है इसलिए यह यहां भी नहीं है। एक मर्ज की रणनीति लिखी जा सकती है, लेकिन जहां तक ​​मुझे पता है, यह कभी नहीं था।
Jan Hudec

19

यदि आप मेरे जैसे हैं, तो आप इसके समकक्ष हैं svn update -n। निम्नलिखित चाल करने के लिए प्रकट होता है। ध्यान दें कि git fetchपहले ऐसा करना सुनिश्चित करें ताकि आपके स्थानीय रेपो के पास तुलना करने के लिए उपयुक्त अपडेट हो।

$ git fetch origin
$ git diff --name-status origin/master
D       TableAudit/Step0_DeleteOldFiles.sh
D       TableAudit/Step1_PopulateRawTableList.sh
A       manbuild/staff_companies.sql
M       update-all-slave-dbs.sh

या यदि आप अपने सिर से रिमोट तक एक अंतर चाहते हैं:

$ git fetch origin
$ git diff origin/master

IMO यह समाधान बहुत आसान है और कम त्रुटि वाला (और इसलिए बहुत कम जोखिम वाला) शीर्ष समाधान की तुलना में जो "मर्ज तो गर्भपात" प्रस्तावित करता है।


1
होना चाहिए $ git checkout target-branchऔर फिर $ git diff --name-status ...branch-to-be-merged(तीन बिंदु आवश्यक हैं इसलिए उन्हें लिखें)
Lu55

एक बात यह याद आ रही है: यह आपको नहीं दिखाती है कि किन फ़ाइलों में कोई विरोध होगा - उनके पास "एम" मार्कर समान हैं, जो कि शाखा पर संशोधित किए गए हैं, लेकिन बिना किसी संघर्ष के विलय किया जा सकता है।
पेट्रिग्नन

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

8

यहां ज्यादातर जवाबों के लिए या तो एक साफ-सुथरी वर्किंग डायरेक्टरी और कई इंटरएक्टिव स्टेप्स (स्क्रिप्टिंग के लिए खराब) की आवश्यकता होती है, या सभी मामलों के लिए काम नहीं करते हैं, जैसे पिछले मर्ज जो पहले से ही आपके टारगेट ब्रांच में कुछ उत्कृष्ट बदलाव लाते हैं, या चेरी-पिक्स कर रहे हैं वही।

सही मायने में यह देखने के लिए कि masterयदि आप developइसे अभी मिलाते हैं तो शाखा में क्या बदलाव होगा :

git merge-tree $(git merge-base master develop) master develop

जैसा कि यह प्लंबिंग कमांड है, यह अनुमान नहीं लगाता है कि आपका क्या मतलब है, आपको स्पष्ट होना चाहिए। यह आउटपुट को रंगीन नहीं करता है या आपके पेजर का उपयोग नहीं करता है, इसलिए पूरी कमांड होगी:

git merge-tree $(git merge-base master develop) master develop | colordiff | less -R

- https://git.seveas.net/previewing-a-merge-result.html

(लिंक के लिए डेविड नॉर्मिंगटन का धन्यवाद)

पुनश्च:

यदि आप मर्ज संघर्ष प्राप्त करेंगे, तो वे आउटपुट में सामान्य संघर्ष मार्करों के साथ दिखाई देंगे, उदाहरण के लिए:

$ git merge-tree $(git merge-base a b ) a b 
added in both
  our    100644 78981922613b2afb6025042ff6bd878ac1994e85 a
  their  100644 61780798228d17af2d34fce4cfbdf35556832472 a
@@ -1 +1,5 @@
+<<<<<<< .our
 a
+=======
+b
+>>>>>>> .their

उपयोगकर्ता @dreftymac एक अच्छा बिंदु बनाता है: यह इसे स्क्रिप्टिंग के लिए अनुपयुक्त बनाता है, क्योंकि आप इसे आसानी से स्टेटस कोड से नहीं पकड़ सकते हैं। संघर्ष मार्कर परिस्थितियों (हटाए गए बनाम संशोधित, आदि) के आधार पर काफी भिन्न हो सकते हैं, जिससे यह कठिन भी हो सकता है। खबरदार।


1
@ प्रभु यह सही उत्तर की तरह दिखता है, हालांकि अभी भी स्पष्ट रूप से एक लापता तत्व है। इस दृष्टिकोण के लिए उपयोगकर्ता को "आईबॉल" आउटपुट की आवश्यकता होती है ताकि यह देखा जा सके कि संघर्ष मार्कर मौजूद हैं या नहीं। क्या आपके पास एक दृष्टिकोण है जो trueसंघर्ष होने पर बस लौटता है और falseयदि कोई संघर्ष नहीं है (उदाहरण के लिए, एक बूलियन मान जिसे "नेत्रगोलक" परीक्षण या किसी भी मानव हस्तक्षेप की आवश्यकता नहीं है)।
dreftymac

1
@dreftymac उस प्रभाव के लिए कुछ भी नहीं पा सकता है। आप कुछ का उपयोग कर सकते हैं, git merge-tree ... | grep -q '^[a-z].*in both$' && echo conflict || echo safe to mergeलेकिन यह सूक्ष्म है; मैं शायद एक मामला भूल रहा हूं। हो सकता है कि आप इसके बजाय संघर्ष मार्करों की जांच करना चाहते हों? उदाहरण के लिए, यह संभवतः "उनका डिलीट नहीं हुआ, हमारा बदल गया" स्टाइल संघर्ष है। (मैंने अभी-अभी जाँच की है और यह भी संघर्ष मार्करों को नहीं दिखाता है, इसलिए आपको यहां सुरक्षित रहने के लिए एक सावधानीपूर्वक regex की आवश्यकता है)
hraban

1
less -Rअपने कॉन्फ़िगरेशन को संशोधित किए बिना रंगीन आउटपुट को संभालने के लिए उपयोग करें ।
जियाकोमो अल्जेटा

धन्यवाद @GiacomoAlzetta, मैंने इसे अपडेट किया है।
हब्रन

6

यदि आप पहले से ही बदलाव ला चुके हैं, तो मेरा पसंदीदा है:

git log ...@{u}

हालांकि मुझे विश्वास है कि 1.7.x की जरूरत है। @{u}अंकन नदी के ऊपर शाखा के लिए एक "आशुलिपि" तो यह एक छोटे से है और अधिक से अधिक बहुमुखी है git log ...origin/master

नोट: यदि आप zsh और विस्तारित glog चीज़ का उपयोग करते हैं, तो आपको कुछ ऐसा करने की संभावना है:

git log ...@\{u\}

6

मौजूदा जवाबों में जोड़कर, एक विलय से पहले अंतर और / या लॉग दिखाने के लिए एक उपनाम बनाया जा सकता है। fetchमर्ज को "प्रीव्यू" करने से पहले किए जाने वाले कई उत्तर पहले छोड़ दिए जाते हैं; इस एक उपनाम है कि एक में इन दो चरणों को जोड़ती है (कुछ अस्थिर के लिए इसी तरह की नकल hg incoming/ outgoing)

इसलिए, " git log ..otherbranch" पर निर्माण , आप निम्नलिखित को जोड़ सकते हैं ~/.gitconfig:

...
[alias]
    # fetch and show what would be merged (use option "-p" to see patch)
    incoming = "!git remote update -p; git log ..@{u}"

समरूपता के लिए, निम्न उपनाम का उपयोग यह दिखाने के लिए किया जा सकता है कि क्या प्रतिबद्ध है और धक्का देने से पहले धक्का दिया जाएगा:

    # what would be pushed (currently committed)
    outgoing = log @{u}..

और फिर आप git incomingबहुत सारे बदलाव दिखाने के लिए " " चला सकते हैं , या "" git incoming -p"पैच को दिखाने के लिए (अर्थात," भिन्न ")," git incoming --pretty=oneline", एक संक्षिप्त सारांश के लिए, आदि। तब आप (वैकल्पिक रूप से)" git pull"कर सकते हैं वास्तव में विलय। (हालांकि, जब से आप पहले से ही भ्रूण ले चुके हैं, मर्ज सीधे किया जा सकता है।)

इसी तरह, "git outgoing " दिखाता है कि अगर आपको " git push" चलाना है तो क्या धक्का दिया जाएगा ।


3

git log currentbranch..otherbranchयदि आप मर्ज करते हैं, तो आपको उन कमिटों की सूची दी जाएगी जो वर्तमान शाखा में जाएंगे। लॉग करने के सामान्य तर्क जो कमिट्स पर विवरण देते हैं, आपको अधिक जानकारी देंगे।

git diff currentbranch otherbranchआपको दो कमानों के बीच का अंतर देगा जो एक हो जाएगा। यह एक ऐसा अंतर होगा जो आपको सब कुछ देता है जो विलय हो जाएगा।

क्या ये मदद करेंगे?


2
दरअसल, गलत है। currentbranchgit log otherbranch..currentbranch पर आवागमन की सूची देता है । git diff otherbranch currentbranchआप, वर्तमान टिप करने के लिए होने वाली है-मर्ज किए गए संस्करण, के बारे में के रूप में बेकार के रूप में यह हो सकता है जहाँ से diff क्योंकि जो आप चाहते हैं मर्ज सिर करने के लिए मर्ज आधार से diff है देता है।
जन हडेक

धन्यवाद। मैंने पेड़ों के नाम बदल दिए हैं।
नौफाल इब्राहिम

3

पुल अनुरोध - मैंने पहले से प्रस्तुत विचारों में से अधिकांश का उपयोग किया है, लेकिन एक जिसे मैं भी अक्सर उपयोग करता हूं (विशेषकर यदि इसके किसी अन्य देव से) एक पुल अनुरोध कर रहा है जो एक विलय से पहले सभी परिवर्तनों की समीक्षा करने का एक आसान तरीका देता है। जगह। मुझे पता है कि GitHub git नहीं है, लेकिन यह निश्चित है कि यह आसान है।


2

वास्तव में एक फेंक फैशन में मर्ज का प्रदर्शन करना (कासापो का जवाब देखें), यह देखने का एक विश्वसनीय तरीका नहीं लगता है।

कहा जा रहा है कि, यहाँ एक तरीका है जो थोड़ा करीब आता है:

git log TARGET_BRANCH...SOURCE_BRANCH --cherry

यह एक उचित संकेत देता है कि कौन सा कमीशन इसे मर्ज में बना देगा। अंतर देखने के लिए, जोड़ें -p। फ़ाइल नाम देखने के लिए, के किसी भी जोड़ने --raw, --stat, --name-only, --name-status

git diff TARGET_BRANCH...SOURCE_BRANCHदृष्टिकोण के साथ समस्या (जन हुडेक का उत्तर देखें), आप अपनी लक्ष्य शाखा में पहले से ही बदलाव के लिए अंतर देखेंगे यदि आपकी स्रोत शाखा में क्रॉस मर्ज होते हैं।


1

शायद यह आपकी मदद कर सकता है? Git-diff पेड़ - दो ट्री ऑब्जेक्ट्स के माध्यम से पाए जाने वाले ब्लॉब्स की सामग्री और मोड की तुलना करता है


1

मैं विरोधी विलय के रूप में git मर्ज कमांड का उपयोग नहीं करना चाहता हूं ताकि परस्पर विरोधी फाइलें की समीक्षा की जा सके। मैं मर्ज नहीं करना चाहता, मैं मर्ज करने से पहले संभावित समस्याओं की पहचान करना चाहता हूं - ऐसी समस्याएं जो ऑटो-मर्ज मुझसे छिपा सकती हैं। मैं जिस समाधान की खोज कर रहा हूं, वह यह है कि कैसे उन फ़ाइलों की एक सूची तैयार की जाए जो दोनों शाखाओं में बदली गई हैं जो भविष्य में एक साथ विलय हो जाएंगी, कुछ सामान्य पूर्वजों के सापेक्ष। एक बार जब मेरे पास वह सूची होगी, तो मैं चीजों को आगे बढ़ाने के लिए अन्य फ़ाइल तुलना टूल का उपयोग कर सकता हूं। मैंने कई बार खोज की है, और मुझे अभी भी वह नहीं मिला है जो मैं एक देशी git कमांड में चाहता हूं।

यहाँ मेरा वर्कअराउंड है, यदि यह किसी और को वहाँ से बाहर निकलने में मदद करता है:

इस परिदृश्य में मेरे पास QA नामक एक शाखा है जिसमें पिछले उत्पादन रिलीज के बाद से इसमें कई बदलाव हैं। हमारी आखिरी प्रोडक्शन रिलीज़ "15.20.1" के साथ टैग की गई है। मेरे पास एक और विकास शाखा है जिसे new_stuff कहा जाता है जिसे मैं QA शाखा में विलय करना चाहता हूं। QA और new_stuff दोनों यह कहते हैं कि "पालन करें" (जैसा कि gitk द्वारा रिपोर्ट किया गया है) 15.20.1 टैग।

git checkout QA
git pull
git diff 15.20.1 --name-only > QA_files
git checkout new_stuff
git pull
git diff 15.20.1 --name-only > new_stuff_files
comm -12 QA_files new_stuff_files

यहाँ कुछ चर्चाएँ हैं जो इन विशिष्ट फ़ाइलों को लक्षित करने में दिलचस्पी लेने के कारण प्रभावित हुईं:

मैं Git मर्ज पर भरोसा कैसे कर सकता हूं?

/software/199780/how-far-do-you-trust-automerge

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