मैं git मर्ज संघर्ष को हल करने के लिए vimdiff का उपयोग कैसे करूं?


159

मैंने अभी-अभी गिट में अपने गुरु की एक शाखा का विलय किया और मुझे Automatic merge failed; fix conflicts and then commit the result.अब मिल गया और मैं git mergetoolनीचे की छवि के साथ खुल गया। मैं नहीं जानता कि कैसे vimdiff का उपयोग करें। यहां प्रत्येक पैनल का क्या मतलब है और मुझे मर्ज संघर्ष को ठीक करने के लिए कैसे आगे बढ़ना चाहिए?

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


3
देखें यह पेज । यदि आपके "सही" से इसका मतलब है, तो आपके कोड की वर्तमान स्थिति शीर्ष बाईं ओर है।
रोमन

@romainl मैं यह पढ़ने के बाद भी उलझन में हूँ कि शॉर्टकट क्या हैं और मुख्य शाखा के रूप में किस फ़ाइल का उपयोग करना है?
कूल गाइ यो

2
@ डैनी http://www.rosipov.com/blog/use-vimdiff-as-git-mergetool/ एक अच्छा है।
ᴠɪɴᴄᴇɴᴛ

इसे भी देखें: यह
skelliam

जवाबों:


142

सभी चार बफ़र्स एक ही फ़ाइल का एक अलग दृश्य प्रदान करते हैं। शीर्ष बाएँ बफर (LOCAL) है कि कैसे फ़ाइल आपके लक्ष्य शाखा में दिख रही है (आप किस चीज़ में विलय कर रहे हैं)। शीर्ष दायाँ बफ़र (REMOTE) यह है कि आपकी स्रोत शाखा में फ़ाइल कैसे दिखती है (जहाँ आप विलय कर रहे हैं)। मध्य बफ़र (BASE) दो का सामान्य पूर्वज है (इसलिए आप तुलना कर सकते हैं कि बाएँ और दाएँ संस्करण एक दूसरे से कैसे निकले हैं)।

निम्नलिखित बिंदु पर मुझसे गलती हो सकती है। मुझे लगता है कि मर्ज संघर्ष का स्रोत यह है कि दोनों फाइलों ने फाइल के एक ही हिस्से को BASE से बदल दिया है; LOCAL ने उद्धरणों को डबल से सिंगल में बदल दिया है, और REMOTE ने एक ही बदलाव किया है, लेकिन पृष्ठभूमि मूल्य को एक रंग से URL में भी बदल दिया है। (मुझे लगता है कि मर्ज इतना स्मार्ट नहीं है कि LOCAL में सभी बदलाव REMOTE में भी मौजूद हों; यह सिर्फ इतना जानता है कि LOCAL ने उन जगहों पर BASE से बदलाव किए हैं, जो REMOTE में हैं)।

किसी भी स्थिति में, नीचे वाले बफ़र में वह फ़ाइल होती है जिसे आप वास्तव में संपादित कर सकते हैं-जो आपके वर्किंग डायरेक्टरी में बैठा है। आप अपनी पसंद के अनुसार कोई भी बदलाव कर सकते हैं; vimआपको दिखा रहा है कि यह प्रत्येक शीर्ष दृश्य से कैसे भिन्न होता है, जो ऐसे क्षेत्र हैं जो स्वचालित मर्ज को संभाल नहीं सकते थे। यदि आप REMOTE परिवर्तन नहीं चाहते हैं, तो LOCAL से परिवर्तन खींचें। यदि आप उन स्थानीय परिवर्तनों को पसंद करते हैं, तो REMOTE से परिवर्तन खींचें। यदि आपको लगता है कि REMOTE और LOCAL दोनों गलत हैं, तो BASE से खींचें। यदि आपके पास एक बेहतर विचार है तो कुछ अलग करें! अंत में, आपके द्वारा यहां किए गए परिवर्तन वही हैं जो वास्तव में प्रतिबद्ध होंगे।


4
त्वरित प्रश्न मैं विम में कैसे बचा सकता हूँ?
कूल गाइ यो

6
:xया :w( :xबाहर भी) प्लस 'वापसी'।
जोनाथन लेफ़लर

4
एंडर्स: अन्य मर्ज टूल हैं जिनका आप उपयोग कर सकते हैं यदि आप उपयोग करने के तरीके से परिचित नहीं हैं vim
चेपनर

3
@AndersKitson, चूंकि आप Mac OS X पर हैं, FileMerge सही, मुफ्त है और XCode के साथ आता है।
रोमेनिल

8
क्यों होता है पतन? यदि वास्तव में कुछ गलत है, तो कृपया इसे ठीक करें, या कम से कम इंगित करें।
चेपनर

91

@ chepner का जवाब बहुत अच्छा है, मैं "विवरण मर्ज संघर्ष को ठीक करने के लिए कैसे आगे बढ़ना चाहिए" पर कुछ विवरण जोड़ना चाहूंगा। यदि आप देखते हैं कि वास्तव में इस मामले में vimdiff का उपयोग कैसे किया जाता है, तो यह नीचे जाता है।


सबसे पहले, "एबोर्ट एवरीथिंग" विकल्प को संबोधित करने के लिए - यदि आप "विम्डीफ" का उपयोग नहीं करना चाहते हैं और मर्ज को रोकना चाहते हैं: प्रेस करें Esc, फिर टाइप करें :qa!और हिट करें Enter। (यह भी देखें कि मैं विम संपादक से बाहर कैसे निकलूं? )। Git आपसे पूछेगा कि क्या मर्ज पूरा हो गया था, साथ जवाब दें n


यदि आप vimdiff का उपयोग करना चाहते हैं, तो यहां कुछ उपयोगी शॉर्टकट हैं। यह मानता है कि आप विम की मूल बातें जानते हैं (नेविगेशन और इन्सर्ट / सामान्य मोड):

  • नीचे बफ़र पर जाएँ (परिणाम मर्ज करें): Ctrl-W j
  • j/ के साथ अगले अंतर पर नेविगेट करें k; या, बेहतर, उपयोग ] cऔर [ cअगले और पिछले क्रमशः नेविगेट करने के लिए
  • z oइसे खोलने के लिए एक तह पर उपयोग करें , यदि आप अधिक संदर्भ देखना चाहते हैं
  • प्रत्येक अंतर के लिए, @ चेपर्स के उत्तर के अनुसार, आप या तो स्थानीय, दूरस्थ या बेस संस्करण से कोड प्राप्त कर सकते हैं, या इसे संपादित कर सकते हैं और फिर से देख सकते हैं जैसा कि आप फिट देखते हैं
    • इसे स्थानीय संस्करण से प्राप्त करने के लिए उपयोग करें :diffget LO
    • रिमोट से: :diffget RE
    • आधार से: :diffget BA
    • या, यदि आप स्वयं कोड को संपादित करना चाहते हैं, तो पहले स्थानीय / रिमोट / बेस से एक संस्करण प्राप्त करें, और फिर इन्सर्ट मोड में जाएं और बाकी को संपादित करें
  • एक बार हो जाने पर, मर्ज परिणाम को सहेजें, और सभी विंडो को छोड़ दें :wqa
  • आम तौर पर, गिट यह पता लगाता है कि मर्ज किया गया था और मर्ज कमिट बनाता है

कॉपी पेस्ट या कस्टम शॉर्टकट के बिना स्थानीय और दूरस्थ दोनों संघर्षों को जोड़ना संभव नहीं लगता है: /vi/10534/is-there-a-way-to-take-both जब-प्रयोग-विम-ऐज-मर्ज-टूल जो ऐड जोड़ने के बाद से शर्म की बात है, ऐसा एक सामान्य संघर्ष प्रकार है।

हर बार शुरू होने पर आपको दर्ज करने से रोकने के लिए विमडिफ को रोकने के लिए, अपने में जोड़ें .vimrc:

set shortmess=Ot

जैसा कि यहां बताया गया है: /vi/771/how-can-i-suppress-the-press-enter-prompt-when-opening-files-in-diff-mode

आप अन्य vimdiff शॉर्टकट के लिए इंटरनेट खोज सकते हैं। मैंने इसे एक उपयोगी पाया है: https://gist.github.com/hyamamoto/7783966


10
इसे x1000 बार बढ़ाया जाना चाहिए और बेहतर उत्तर के रूप में स्वीकार किया जाना चाहिए।
एंड्री पोर्टनॉय

अगले संघर्ष के लिए कूदने के लिए, बस === के लिए खोज करें। do "/ ===" और दर्ज करें
Apit John Ismail

यदि एक से अधिक मिलान का उपयोग करते हुए देखें तो यह पोस्ट ( stackoverflow.com/questions/51520705/… ) देखें :diffget
जेसन

7

विमीडिफ को बदलने के लिए अंतिम मर्जेटोल

यह एक प्रकार की जीभ-इन-गाल है, लेकिन यह वही है जो मैंने vimdiff की कोशिश करने के बाद एक विमर के रूप में परिवर्तित किया।

एक मर्ज संघर्ष को हल करने के लिए, मुझे लगभग हमेशा जो देखने की जरूरत है वह है:

  • REMOTE
  • स्थानीय
  • दो अंतर:
    • अंतर दूर करें
    • BASE LOCAL को अलग करें

फिर दोनों को एक साथ रखने की कोशिश करें।

जबकि vimdiff स्क्रीन में BASE, LOCAL और REMOTE दिखाता है:

    +--------------------------------+
    | LOCAL  |     BASE     | REMOTE |
    +--------------------------------+
    |             MERGED             |
    +--------------------------------+

मुझे नहीं पता कि इसे बनाने का तरीका स्पष्ट रूप से उन दो भिन्नताओं को दिखाता है जिनकी मुझे आवश्यकता है इसके अलावा दाएं बाएं सही समय का एक गुच्छा है।

इसके अलावा, LOCAL और REMOTE पहले से ही git मर्ज संघर्ष मार्करों में दिखाई दे रहे हैं, इसलिए मैं एक टूल से इतना हासिल नहीं करता हूं जो उन्हें फिर से दिखाता है।

इसलिए, मैंने इसके बजाय अपने स्वयं के "difftool" का निर्माण किया जो वास्तव में उस अंतर को दिखाता है जो मुझे याद आ रहा था:

~ / Bin / cirosantilli-mergetool

#!/usr/bin/env bash
BASE="$1"
LOCAL="$2"
REMOTE="$3"
diff --color -u "$BASE" "$LOCAL"
diff --color -u "$BASE" "$REMOTE"
exit 1

गिटहब ऊपर

और इसे स्थापित करें:

git config --global mergetool.cirosantilli-mergetool.cmd 'cirosantilli-mergetool $BASE $LOCAL $REMOTE'
git config --global mergetool.cirosantilli-mergetool.trustExitCode true
# If you want this to become your default mergetool.
#git config --global merge.tool 'cirosantilli-mergetool'

अब, जब आप करते हैं:

git mergetool -t cirosantilli-mergetool

यह दो भिन्न दिखाता है जो मैं टर्मिनल पर चाहता हूं, जैसे कुछ साथ:

--- ./src/dev/arm/RealView_BASE_15560.py        2019-12-27 13:46:41.967021591 +0000
+++ ./src/dev/arm/RealView_LOCAL_15560.py       2019-12-27 13:46:41.979021479 +0000
@@ -994,7 +994,7 @@                                                              

     def setupBootLoader(self, cur_sys, loc):
         if not cur_sys.boot_loader:                           
-            cur_sys.boot_loader = [ loc('boot_emm.arm64'), loc('boot_emm.arm') ]
+            cur_sys.boot_loader = [ loc('boot.arm64'), loc('boot.arm') ]
         cur_sys.atags_addr = 0x8000000                  
         cur_sys.load_offset = 0x80000000                    

@@ -1054,7 +1054,7 @@                                           
             ]                                                     

     def setupBootLoader(self, cur_sys, loc):
-        cur_sys.boot_loader = [ loc('boot_emm_v2.arm64') ]
+        cur_sys.boot_loader = [ loc('boot_v2.arm64') ]
         super(VExpress_GEM5_V2_Base,self).setupBootLoader(
                 cur_sys, loc)                             

--- ./src/dev/arm/RealView_BASE_15560.py        2019-12-27 13:46:41.967021591 +0000
+++ ./src/dev/arm/RealView_REMOTE_15560.py      2019-12-27 13:46:41.991021366 +0000
@@ -610,10 +610,10 @@           
     def attachIO(self, *args, **kwargs):              
         self._attach_io(self._off_chip_devices(), *args, **kwargs)

-    def setupBootLoader(self, cur_sys, loc):
-        cur_sys.boot_loader = loc('boot.arm') 
-        cur_sys.atags_addr = 0x100                           
-        cur_sys.load_offset = 0       
+    def setupBootLoader(self, cur_sys, boot_loader, atags_addr, load_offset):
+        cur_sys.boot_loader = boot_loader      
+        cur_sys.atags_addr = atags_addr     
+        cur_sys.load_offset = load_offset

तो आप यहाँ देख सकते हैं कि दोनों टर्मिनल में अलग-अलग हैं:

  • RealView_BASE_15560.py बनाम RealView_LOCAL_15560.py
  • RealView_BASE_15560.py बनाम RealView_REMOTE_15560.py

यदि अंतर बड़े हैं, तो मैं अपने tmux सुपरपावर के साथ खोज करूंगा

हां, आप कुछ ऐसे शॉर्टकट खो देते हैं जो vimdiff प्रदान करता है, लेकिन सामान्य रूप से हल करने वाले संघर्षों में दोनों संस्करणों से सावधानीपूर्वक कॉपी पेस्ट की आवश्यकता होती है, जिसे मैं git संघर्ष मार्करों के साथ एक सामान्य विम सत्र के अंदर ठीक कर सकता हूं।

vimdiffचल रहा है जब फ़ाइलों का अवलोकन और अंतर

इससे पहले कि मैं नीचे बैठती और अपने संपूर्ण सेटअप को स्वचालित करती cirosantilli-mergetool, यह वही है जो मुझे अपनी ज़रूरत के अनुसार दो भिन्नताओं को प्राप्त करने के लिए कर रहा था।

जब कोई फ़ाइल नाम पर कोई विरोधाभास है, तो git mergetoolचल रहा vimdiffहै, कहते हैं main.py, git प्रत्येक संस्करण के लिए फाइल बनाता है, नाम:

main_BASE_1367.py
main_LOCAL_1367.py
main_REMOTE_1367.py

समान निर्देशिका में main.pyजहां 1367git mergetool का PID है, और इसलिए "यादृच्छिक" पूर्णांक है, जैसा कि नीचे उल्लेख किया गया है: git मर्ज संघर्ष में, BACKUP, BASE, LOCAL, और REMOTE दोनों क्या उत्पन्न होते हैं?

इसलिए, अपने इच्छित अंतर को देखने के लिए, मैं पहले जनरेट की गई फ़ाइलों को ढूंढता हूं git status, और फिर नए टर्मिनल खोलता हूं और उन फाइलों के जोड़े के बीच एक विमीडफ करता हूं, जिसकी मुझे परवाह है:

vim -d main_BASE_1367.py main_LOCAL_1367.py
vim -d main_BASE_1367.py main_REMOTE_1367.py

साथ में git mergetool, यह जानकारी ए लॉट को यह पता लगाने में मदद करती है कि क्या जल्दी हो रहा है!

इसके अलावा, भले ही मेरिजेट चल रहा हो, आप केवल फ़ाइल खोल सकते हैं:

vim main.py

सीधे और इसे वहां संपादित करें यदि आपको लगता है कि यह एक बड़ी संपादक विंडो के साथ आसान होने जा रहा है।

संघर्षों को मर्ज करने के लिए सीधे कूदें

हालांकि ]cअगले विंपिड के अंदर अलग-अलग बिंदुओं पर कूदता है, वहाँ हमेशा एक मर्ज संघर्ष नहीं होता है।

इस के साथ मदद करने के लिए, मैं अपने में है ~/.vimrc:

# Git Merge conflict
nnoremap <leader>gm /\v^\<\<\<\<\<\<\< \|\=\=\=\=\=\=\=$\|\>\>\>\>\>\>\> /<cr>

जो सीधे संघर्षों का पता लगाता है।

git इमर्ज

शायद सबसे अच्छा विकल्प केवल विमडिफ का उपयोग करने पर छोड़ देना है और नियमित रूप से विम + गिट इमर्ज पर भरोसा करना है जो इस पर उल्लेख किया गया था: मैं कैसे पता लगा सकता हूं कि कौन से जीआईटी संघर्ष का कारण बनता है? चूंकि विम्डिफ की सीखने की अवस्था कष्टप्रद है, और यह उन कार्यों को नहीं करता है जिनकी हमें सबसे अधिक आवश्यकता होती है।


1
Upvoted। मुझे लगता है कि मैंने उल्लेख किया है कि 9 साल पहले stackoverflow.com/a/3052118/6309 पर । (उत्तर का अंतिम भाग देखें)
वॉन

@VonC हाँ, मुझे लगता है कि आपने इसे जीत लिया है! XD
Ciro Santilli 郝海东
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.