2012-09-17 6 views
25

में एक रिबेस में मतभेदों की तुलना करना मान लीजिए कि मैंने foo पर master पर विवादों के साथ शाखा को अभी भी rebased किया था। मैं यह सुनिश्चित करना चाहता हूं कि मैंने अतिरिक्त परिवर्तनों को शुरू करने या परिवर्तन खोने (संघर्ष समाधान के लिए उपयुक्त है) के अलावा संघर्ष समाधान के दौरान foo की सामग्री को गलती से नुकसान नहीं पहुंचाया।गिट

diff -u <(git diff `git merge-base master [email protected]{1}` [email protected]{1}) \ 
     <(git diff `git merge-base master foo ` foo ) 

(अद्यतन:: मैं के माध्यम से यह किया है या git-diff के लिए बराबर ... वाक्य रचना जो मैं सिर्फ :)

diff -u <(git diff [email protected]{1}) <(git diff master...foo) | mate 

की याद दिला दिया है यह मैं सभी परिवर्तन को हुई है से पता चलता master..foo पैच के रूप में माना जाता है, जो कि मैं न्यूनतम होने के लिए जांचना चाहता हूं। हालांकि, आमंत्रण जटिल है और आउटपुट पूरी तरह से व्याख्या करने के लिए सरल नहीं है।

क्या यह कार्य पूरा करने का एक बेहतर तरीका है - एक ही जानकारी प्रदान करने के लिए, लेकिन एक बेहतर विधि या प्रारूप के साथ - या क्या मुझे ऊपर ले जाना चाहिए और इसे एक स्क्रिप्ट में लपेटना चाहिए? मास्टर और रिबेस foo के बीच

+0

क्या यह अनिवार्य रूप से 'git diff foo @ {1} foo' के बराबर नहीं है? – twalberg

+1

@twalberg संख्या; 'गिट diff foo @ {1} foo' मेरे संघर्ष संकल्पों और मास्टर के लिए किए गए परिवर्तनों को दिखाता है जो कि मैंने संघर्ष विरोधों के बजाए, जिस पर मैं पुन: प्रयास किया था। –

+0

आह, ठीक है ... मैं केवल अपने सबसे आम रिबेस मामले पर विचार कर रहा था, जिसमें स्रोत और गंतव्य का विलय-आधार वही रहता है (धक्का देने से पहले शाखा को पुनः लिखना/स्क्वैश करना)। – twalberg

उत्तर

2

अंतर:

git diff master..foo

बनाम

की

मतभेद पूर्व rebase मास्टर बंद शाखाओं के बाद foo (तीन बिंदुओं पर ध्यान दें):

git diff [email protected]{1}

?

+0

धन्यवाद, '...' का उपयोग करके कमांड कम करता है, और मैंने वास्तव में ऐसा पहले उपयोग किया है मुझे इसके बारे में सोचना चाहिए था। हालांकि, मैं अभी भी उन दो diffs की स्पष्ट रूप से तुलना करने के साथ छोड़ दिया गया है। क्या आपके पास इसके लिए कोई सुझाव है? –

2

चूंकि यह विद्रोह है और विलय नहीं है, तो आप foo की तुलना अपने साथ कर सकते हैं लेकिन मर्ज से पहले। अगर मुझे सही याद है [email protected]{1}foo के लिए वर्तमान प्रतिबद्धता के माता-पिता को मिलेगा, और शायद यह वह नहीं है जिसे आप ढूंढ रहे हैं।

मुझे लगता है कि आप निम्नलिखित की तरह कुछ कर सकते हैं (यह मानते हुए आप नहीं किया है एक git gc):

शाखा foo रिबेस के बाद पर:

$ git reflog 

यह दिखा देंगे कि कैसे अपनी शाखा के HEAD ले जाया गया है।

64d3c9e [email protected]{15}: rebase -i (finish): returning to refs/heads/master 
64d3c9e [email protected]{16}: rebase -i (fixup): Fixes external dependencies 
049169e [email protected]{17}: rebase -i (fixup): updating HEAD 
d4c2e69 [email protected]{18}: rebase -i (pick): Fixes external dependencies 
049169e [email protected]{19}: rebase -i (fixup): Imports futures 
e490bed [email protected]{20}: rebase -i (fixup): updating HEAD 
... 
etc 
... 

foo के लिए प्रतिबद्ध के अंतिम करने के लिए तत्पर मर्ज से पहले: आप इस तरह की कुछ रिकॉर्ड (निर्भर करता है अगर आप सहभागी या नहीं rebase) देखना चाहिए। आपने जो किया है उसके आधार पर यह मुश्किल हो सकता है या नहीं। यही कारण है कि मैंने एक ऐसा स्क्रिप्ट प्रदान नहीं किया है।

रीबेज से पहले foo के लिए अंतिम प्रतिबद्धता वाले प्रतिबद्ध आईडी को चुनें और उसके बाद उस प्रतिबद्ध आईडी की तुलना करें। कि आईडी प्रतिबद्ध कहो है: XXXX:

git diff XXXX...foo 

हो सकता है कि तुम क्या चाहते हो।

+0

जैसा कि मैंने twalberg का जवाब दिया, यह उन मास्टरों में किए गए परिवर्तनों को शामिल नहीं करेगा जिन्हें मैंने पीछे छोड़ दिया था, और इसलिए बहुत शोर है। (वैसे, हेड के रीफ्लॉग के माध्यम से खुदाई जरूरी नहीं है; * शाखा * के रेफ्लॉग में केवल राज्यों के पहले और बाद में शामिल होगा, और 'foo @ {1}' वास्तव में वह प्रतिबद्धता है जिसे आप मैन्युअल रूप से खोजना चाहते हैं। '@ ' रेफ्लॉग में दिखता है, वंश नहीं।) –

+0

@ केविन रेड आप सही हैं, मैंने '~' '' 'के साथ भ्रमित किया है। मैं अक्सर उनका उपयोग नहीं करता हूं। माफ़ कीजिये। – manu

1

थोड़ा अलग दृष्टिकोण: गिट के विलय के मामले में इसे दिखाने के लिए गिट का अच्छा समर्थन है। अर्थात।"माता-पिता के सापेक्ष क्या बदल गया है जिसे माता-पिता द्वारा समझाया जा सकता है?"

विकल्प 1::

  1. एक थ्रो-दूर मर्ज पहले (एक रिबेस के बजाय)

    कई तरीकों से आप का लाभ उठाने सकता है आपके रिबेस के लिए समर्थन कर रहे हैं। फिर सामान्य मर्ज डिस्प्ले दिखाएगा कि मर्ज बदल गया है। यह वही है जो आप चाहते थे।

  2. वापस जाएं और पुन: प्रयास करें, और मर्ज परिणाम के विरुद्ध रिबेस किए गए टिप की तुलना करें - वे समान होना चाहिए।

विकल्प 2 (यदि रिबेसिंग विलय की तुलना में आसान है):

  1. रिबेस करो।
  2. इसे स्थानीय/अस्थायी रूप से विलय की तरह दिखने के लिए एक भ्रष्टाचार का उपयोग करें।

कि ऐसा करने के लिए, एक .git/जानकारी बनाने/एक पंक्ति के साथ ग्राफ्ट:

TIP UPSTREAM OLDTIP 

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

मुझे इसे स्वचालित करने के बारे में निश्चित नहीं है; मैं इस सामान को गिट खोल के साथ करता हूं, क्योंकि यह सही संशोधन की तुलना करना आसान बनाता है (राइट-क्लिक मेनू का उपयोग करके)।

यदि आप वास्तव में दो diffs की तुलना करना चाहते हैं तो आप इंटरडिफ (1) को देखना चाहेंगे, लेकिन मुझे यकीन नहीं है कि यह आधार फ़ाइलों के साथ अलग-अलग कैसे सामना करेगा।

+0

विकल्प 1 के संबंध में, जिन मामलों में मैं यह चेक बनाना चाहता हूं, विलय की तुलना में एक विलय की * अलग-अलग संघर्ष * होने की संभावना है, और किसी भी मामले में मैं वास्तव में हुआ विद्रोह को सत्यापित करना चाहता हूं। विकल्प 2 के संबंध में, मैंने कोशिश की और पाया कि दृश्य मास्टर पर पेश किए गए परिवर्तनों से अव्यवस्थित है, जो वही है जो मैं छिपाना चाहता हूं। मेरे पास 'इंटरडिफ' नहीं है, लेकिन इसके मैन पेज का कहना है कि "अंतर दोनों एक ही फाइल के सापेक्ष होना चाहिए।" –

+0

मेरे पास इसके लिए एक समान उत्तर है जो श्रृंखला के लिए काम करता है और मूल रूप से "केवल प्रतिबद्ध-पेड़ का उपयोग करें विलय के परिणाम को समझकर विलय पोस्ट-रीबेस उत्पन्न करें जो कि पूर्ण रिबेस का पेड़ होना चाहिए यह हमें अनिवार्य रूप से अपस्ट्रीम से v1 में विलय करने देता है और इसके परिणामस्वरूप v2 का पेड़ होता है। यह तब हो सकता है गिट-शो में पारित किया गया और यह सुंदर संयुक्त प्रारूप का उत्पादन करेगा, बिना ग्राफ्ट पर भरोसा किए बिना, और इस प्रकार इसे स्वचालित किया जा सकता है। – Jake

2

git-cherry एक शाखा पर काम करने के लिए खोज जो दूसरे पर नहीं हैं। आप के रूप में यह प्रयोग करना होगा:

git cherry -v OLDTIP TIP UPSTREAM 

अर्थात प्रतिबद्ध है कि OLDTIP पर थे, लेकिन जो देखने UPSTREAM..TIP पर नहीं हैं। यह पैच हस्ताक्षर को देखने के लिए देखता है कि पैच शामिल है या नहीं, इसलिए यदि पैच जोड़ा गया है, तो रिबेस के दौरान गिरा दिया गया है या संशोधित किया गया है, तो यह सूची में दिखाई देगा। परिवर्तन के बिना लागू चीजें दिखाई नहीं देगी।

OLDTIP पर जाकर और git rebase -i TIP पर जाकर एक समान प्रभाव प्राप्त किया जा सकता है, क्योंकि यह काम की सूची को पॉप्युलेट करने के लिए एक ही तर्क का उपयोग करता है।

+0

यह इंट्रा-फ़ाइल परिवर्तनों की जांच करने में मदद नहीं करता है। मुझे हंक- खराब संघर्ष संकल्पों के कारण स्तर परिवर्तन खो गए या क्षतिग्रस्त हो गए, पूरे काम नहीं करते। –

+0

यहां विचार यह है कि आपको तुलना करने की आवश्यकता वाले कमियों की संख्या को कम करना है (आदर्श रूप से शून्य)। यह उपयोगी नहीं है यदि आप एच बड़ी संख्या में बड़ी, विवादित प्रतिबद्धताएं हैं, लेकिन यह बड़ी संख्या में छोटी प्रतिबद्धताओं में मदद कर सकती है। –

+0

आह, मुझे लगता है कि, इस मानक से मेरे पास बड़ी संख्या में बड़ी प्रतिबद्धताएं हैं, क्योंकि फॉलो-अप प्रश्न जो दिमाग में आया था, "एक बार जब मैं तुलना करने की कोशिश करता हूं, तो आप कैसे प्रस्तावित करते हैं कि मैं उनकी तुलना करता हूं, मैं diff-diff के साथ शुरू करने के अलावा शुरू किया? " –

3

हम जो वास्तव में दिखाना चाहते हैं वह संघर्ष संयुक्त अंतर है जो उत्पन्न होता है जैसे कि हमने (ए) से (बी) प्राप्त करने के लिए विलय किया था, जहां (ए) पहले (अपस्ट्रीम-पुराने) पर आधारित था और (बी) अब (अपस्ट्रीम-न्यू) पर आधारित है।

हम सिर्फ एक सीधा अंतर नहीं चाहते हैं।

इसके बजाए, हम अनिवार्य रूप से विलय कर सकते हैं लेकिन परिणामी पेड़ को $ b^{tree} होने के लिए मजबूर कर सकते हैं जिसे हम पहले से ही जानते हैं कि हम क्या चाहते हैं "सही" बिंदु है।

अधिक या कम, मान लेते हैं कि हम

newcommit -> the new version of the series 
oldcommit -> the old version of the series 
upstream -> the (new) version of the base of the series 

हम के माध्यम से

git commit-tree newcommit^{tree} -p oldcommit -p upstream -m "message" 

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

यह भी बस के रूप में अच्छी तरह से एक परिवर्तन ammending लिए काम करता है, और आप में कुछ अधिक परिश्रम सुनिश्चित उत्पन्न मर्ज के लिए प्रतिबद्ध है कि सटीक लेखक है और प्रतिबद्ध timestamps इतना है कि यह कई कॉल से अधिक संगत है (क्योंकि हम भंडारण कर रहे हैं करने के लिए क्या कर सकते हैं ऑब्जेक्ट डेटाबेस में एक ढीला रेफरी)।

दुर्भाग्य से मैं यह समझने में सक्षम नहीं हूं कि वास्तव में एक पेड़ पैदा करने के बिना "गिट diff" को कैसे अलग किया जाए। मुझे यकीन नहीं है कि उस बिंदु पर पहुंचने के लिए हमें किन तर्कों को पारित करना होगा।

+0

चालाक विचार! मुझे यह देखना होगा कि अगली बार मुझे यह समस्या कितनी उपयोगी होगी। –

+0

मुझे बस इसे आजमाने का अवसर मिला। मुझे एक चेतावनी मिली है जिसे नोट किया जाना चाहिए: 'अपस्ट्रीम' _deleted_ एक फ़ाइल जिसमें परिवर्तन हुए थे (ताकि इसे कई अन्य फाइलों में विभाजित किया जा सके), और इस तकनीक द्वारा उत्पादित diff उस फ़ाइल का बिल्कुल उल्लेख नहीं करता है, इसलिए नहीं दिखाया जाएगा उन परिवर्तनों का नुकसान। –