द्विआधारी फ़ाइलों के साथ एक गिट संघर्ष का समाधान


464

मैं विंडोज (msysgit) पर Git का उपयोग कर रहा हूँ, जो मैं कर रहा हूँ कुछ डिज़ाइन कार्य के लिए परिवर्तनों को ट्रैक करने के लिए।

आज मैं एक अलग पीसी पर काम कर रहा हूं (रिमोट रेपो के साथ brian) और मैं अब अपने लैपटॉप पर आज किए गए संपादन को अपने नियमित स्थानीय संस्करण में मर्ज करने की कोशिश कर रहा हूं।

अपने लैपटॉप पर, मैंने git pull brian masterअपने स्थानीय संस्करण में परिवर्तनों को खींचने के लिए उपयोग किया है। मुख्य इनडिजाइन दस्तावेज़ के अलावा सब कुछ ठीक था - यह एक संघर्ष के रूप में दिखाता है।

पीसी पर संस्करण ( brian) नवीनतम है जिसे मैं रखना चाहता हूं, लेकिन मुझे नहीं पता कि कमांड इस रेपो का उपयोग करने के लिए क्या कहता है।

मैंने सीधे अपने लैपटॉप पर फ़ाइल को कॉपी करने की कोशिश की, लेकिन यह पूरी मर्ज प्रक्रिया को तोड़ता हुआ प्रतीत होता है।

क्या कोई मुझे सही दिशा दिखा सकता है?

जवाबों:


853

git checkoutइस तरह के मामलों के लिए एक विकल्प --oursया --theirsविकल्प स्वीकार करता है । इसलिए यदि आपके पास एक मर्ज संघर्ष है, और आप जानते हैं कि आप जिस शाखा में विलय कर रहे हैं, उससे बस फ़ाइल चाहते हैं, तो आप यह कर सकते हैं:

$ git checkout --theirs -- path/to/conflicted-file.txt

फ़ाइल के उस संस्करण का उपयोग करने के लिए। इसी तरह, यदि आप जानते हैं कि आप अपना संस्करण चाहते हैं (किसी का विलय नहीं किया जा रहा है) तो आप उपयोग कर सकते हैं

$ git checkout --ours -- path/to/conflicted-file.txt

47
मुझे --ours का उपयोग करने से पहले फ़ाइल पर 'git रीसेट HEAD पाथ / टू / कंट्रोल्ड-फाइल.txt' चलाना था, अन्यथा इसका कोई असर नहीं पड़ता था।
ज़िट्रैक्स

6
@Zitrax चलाने के बाद क्या आपने फ़ाइल को अलग किया git checkout --ours? मैन पेज सुझाव देता है (IMHO) कि चेकआउट --ours / - उनकी "" संशोधित, जरूरत मर्ज "" सूची से परिवर्तन को हटा देगा और इसे सूचकांक में जोड़ देगा, और मुझे लगता है कि यह सही नहीं है। मेरा मानना ​​है git addकि चेकआउट के बाद आपको दौड़ने की आवश्यकता होगी ।
टिम कीटिंग

15
नोट: आप अभी भी "git add परस्पर-फ़ाइल.txt " और "git कमिट" करना चाहते हैं। हाथ से, जब मैंने इसे आज़माया, तो संघर्ष के बारे में एक नोट के साथ प्रतिबद्ध संदेश पूर्व-आबाद था।
एडवर्ड फॉक

2
"जिस शाखा में आप विलय कर रहे हैं, उसकी शाखा" खतरनाक रूप से "जिस शाखा में आप विलय कर रहे हैं, उसके करीब है", मुझे लगता है कि सिर्फ प्रीपोज़ को छोड़ना बेहतर होगा: "जिस शाखा में आप विलय कर रहे हैं", जो कि gip कमांड को भी प्रतिबिंबित करेगी। (यानी git merge branch_name)।
और्रीबक

13
कुछ महत्वपूर्ण बिंदु जो इस विषय के स्पष्टीकरण में हमेशा गायब हैं। मर्ज के बजाय रिबास करते समय, अर्थ --theirऔर --oursअदला-बदली कर रहे हैं, यानी-their == वर्तमान में चेक-आउट की गई शाखा और --ours वह शाखा है, आमतौर पर एक दूरस्थ शाखा, या पथ युक्ति जिसे आप वर्तमान में मर्ज करने का प्रयास कर रहे हैं। डाली। [space]--[space]शाखा का नाम और पथ कल्पना है कि दोनों एक ही नाम के साथ मौजूद होता है के बीच पथ कल्पना करने का विकल्प स्पष्ट रूप से दिखाता है (जैसे एक मौजूदा शाखा का नाम "abc" है और एक निर्देशिका "abc" कहा जाता है मौजूद है)।
BoiseBaked 16

147

आपको संघर्ष को मैन्युअल रूप से हल करना होगा (फ़ाइल को कॉपी करना) और फिर फ़ाइल को कमिट करें (कोई फर्क नहीं पड़ता कि आपने इसे कॉपी किया है या स्थानीय संस्करण का उपयोग किया है) इस तरह से

git commit -a -m "Fix merge conflict in test.foo"

मर्ज करने के बाद सामान्य रूप से ऑटोकॉमिट करें, लेकिन जब यह पता लगाता है कि यह अपने आप हल नहीं कर सकता है, तो यह सभी पैच लागू करता है जो इसे पता लगाता है और आपको हल करने और मैन्युअल रूप से प्रतिबद्ध करने के लिए बाकी छोड़ देता है। Git मर्ज मैन पृष्ठ , Git-SVN क्रैश कोर्स या इस ब्लॉग प्रविष्टि है कि यह कैसे काम चाहिए था पर कुछ प्रकाश डाला सकता है।

संपादित करें: नीचे दी गई पोस्ट देखें, आपको वास्तव में फ़ाइलों को स्वयं कॉपी करने की आवश्यकता नहीं है, लेकिन उपयोग कर सकते हैं

git checkout --ours -- path/to/file.txt
git checkout --theirs -- path/to/file.txt

उस फ़ाइल के संस्करण का चयन करने के लिए जिसे आप चाहते हैं। यदि आप दोनों संस्करणों का मिश्रण चाहते हैं, तो फ़ाइल की प्रतिलिपि बनाना / संपादित करना आवश्यक होगा।

कृपया सही के रूप में मिपादियों के उत्तर को चिह्नित करें।


1
उसके लिए धन्यवाद। मुझे यकीन नहीं था कि किसी फ़ाइल को 'सही' के रूप में चिह्नित करने के लिए किसी तरह का निर्माण हुआ था। बताते हैं कि मुझे गैर-मौजूद आदेश क्यों नहीं मिला!
केविन विल्सन

हाँ, थोड़ा अचिंत्य है - जैसे कुछ संकल्प अच्छा होगा, लेकिन यह भी एक अतिरिक्त कदम होगा ...
VolkA

120

आप इस समस्या को भी दूर कर सकते हैं

git mergetool

जिसके कारण gitविवादित बाइनरी की स्थानीय प्रतियां बनाने और उन पर अपने डिफ़ॉल्ट संपादक को स्पॉन करने का कारण बनता है:

  • {conflicted}.HEAD
  • {conflicted}
  • {conflicted}.REMOTE

जाहिर है कि आप एक पाठ संपादक में उपयोगी बायनेरिज़ फ़ाइलों को संपादित नहीं कर सकते। इसके बजाय आप संपादक को बंद किए बिना नई {conflicted}.REMOTEफ़ाइल की प्रतिलिपि बनाएँ {conflicted}। फिर जब आप संपादक gitको बंद करते हैं तो देखेंगे कि अघोषित कार्य-प्रति को बदल दिया गया है और आपके मर्ज संघर्ष को सामान्य तरीके से हल किया जाता है।


8
यदि फाइलें बड़ी हैं या आप टेक्स्ट एडिटर में बाइनरी खोलने का जोखिम नहीं उठाना चाहते हैं, तो आप मेरिटोल प्रॉम्प्ट (" Hit return to start merge resolution tool") में ctrl + c को हिट कर सकते हैं और git अतिरिक्त फाइलों को जगह में छोड़ देगा। फिर आप उन्हें संशोधित कर सकते हैं या उन्हें एक बाहरी टूल (बाइनरी डॉक्यूमेंट फॉर्मेट जैसे लिब्रेऑफ़िस / ओपनऑफ़िस / एमएसवॉर्ड के लिए उपयोगी) में मर्ज कर सकते हैं और परिणाम को मूल फ़ाइल नाम में वापस सहेज सकते हैं। यह बताने के लिए कि संघर्ष हल हो गया है, git addमूल फ़ाइल नाम, और फिर आप मर्ज कमिट समाप्त कर सकते हैं।
फेलिक्स

18

अपनी वर्तमान शाखा में संस्करण को रखकर हल करने के लिए (जिस शाखा में आप विलय कर रहे हैं उससे संस्करण को अनदेखा करें), बस फ़ाइल जोड़ें और प्रतिबद्ध करें:

git commit -a

जिस शाखा में आप विलय कर रहे हैं, उस संस्करण से अपनी वर्तमान शाखा में संस्करण को अधिलेखित करके हल करने के लिए, आपको उस संस्करण को अपनी कार्यशील निर्देशिका में पहले प्राप्त करना होगा, और फिर उसे जोड़ना / प्रतिबद्ध करना होगा:

git checkout otherbranch theconflictedfile
git commit -a

अधिक विस्तार से समझाया गया


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

11

mipadi का जवाब मेरे लिए काफी काम का नहीं था, मुझे यह करने की आवश्यकता थी:

git checkout --ours path / to / file.bin

या, संस्करण को मर्ज किए जाने के लिए:

git चेकआउट - पथ / / से फ़ाइल में दर्ज करें

फिर

git add path / to / file.bin

और फिर मैं फिर से "गिट मेरिजेट" करने में सक्षम था और अगले संघर्ष पर जारी रहा।


6

से git checkoutडॉक्स

git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...

--ours
--theirs
इंडेक्स से रास्तों की जाँच करते समय , अनर्जित रास्तों के लिए स्टेज # 2 ( ours) या # 3 ( theirs) देखें।

पिछले विफल मर्ज के कारण अनुक्रमणिका में अनमैरिड प्रविष्टियाँ हो सकती हैं। डिफ़ॉल्ट रूप से, यदि आप इंडेक्स से ऐसी प्रविष्टि की जांच करने का प्रयास करते हैं, तो चेकआउट ऑपरेशन विफल हो जाएगा और कुछ भी चेक आउट नहीं होगा। का उपयोग करते हुए -fइन unmerged प्रविष्टियों की उपेक्षा करेंगे। मर्ज के एक विशिष्ट पक्ष से सामग्री का उपयोग करके --oursया सूचकांक से बाहर की जाँच की जा सकती है --theirs। साथ -m, काम कर पेड़ फाइल करने के लिए त्याग किया जा सकता करने के लिए किए गए परिवर्तनों को मूल विरोध हुआ मर्ज परिणाम फिर से बनाते हैं।


4

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

% git fetch

यह नवीनतम रिपॉजिटरी को दूरस्थ रिपॉजिटरी से प्राप्त करता है (आपको अपने सेटअप के आधार पर एक दूरस्थ शाखा का नाम निर्दिष्ट करने की आवश्यकता हो सकती है), लेकिन उन्हें मर्ज करने का प्रयास नहीं करता है। यह FETCH_HEAD में कमिट को रिकॉर्ड करता है

% git checkout FETCH_HEAD stuff/to/update

यह मेरे द्वारा वांछित बाइनरी फ़ाइलों की प्रतिलिपि लेता है और यह बताता है कि दूरस्थ शाखा से लाए गए संस्करण के साथ काम करने वाले पेड़ में क्या है। git किसी भी मर्जिंग को करने की कोशिश नहीं करता है, इसलिए आप बस दूरस्थ शाखा से बाइनरी फ़ाइल की एक सटीक प्रतिलिपि के साथ समाप्त करते हैं। एक बार जब आप ऐसा कर लेते हैं, तो आप सामान्य की तरह नई प्रति जोड़ / जोड़ सकते हैं।


4

यह प्रक्रिया बाइनरी फ़ाइल संघर्ष को हल करने के लिए है जब आपने जीथब को एक अनुरोध भेजा है:

  1. इसलिए गितुब पर, आपने पाया कि आपके पुल अनुरोध में एक द्विआधारी फ़ाइल पर एक संघर्ष है।
  2. अब अपने स्थानीय कंप्यूटर पर उसी गिट शाखा में वापस जाएं।
  3. आप (ए) इस बाइनरी फ़ाइल को फिर से बनाते / फिर से बनाते हैं, और (बी) परिणामी बाइनरी फाइल को इसी git ब्रांच में भेजते हैं।
  4. फिर आप इसी गिट शाखा को फिर से गितुब की ओर धकेलते हैं।

गिथब पर, आपके अनुरोध पर, संघर्ष गायब हो जाना चाहिए।


यह ठीक वैसी ही प्रक्रिया है जिसकी मुझे जरूरत है
Huifang Feng

2

यदि द्विआधारी एक dll या कुछ से अधिक है जो सीधे एक छवि की तरह संपादित किया जा सकता है , या एक मिश्रण फ़ाइल (और आपको एक फ़ाइल या दूसरे को ट्रैश / चयन करने की आवश्यकता नहीं है) एक वास्तविक मर्ज कुछ इस तरह होगा:

मेरा सुझाव है कि आप द्विआधारी फ़ाइल क्या हैं के लिए उन्मुख एक अलग उपकरण के लिए खोज, उदाहरण के लिए छवि फ़ाइलों के लिए कुछ मुफ्त वाले हैं

और उनकी तुलना करें।

यदि आपकी फ़ाइलों की तुलना करने के लिए कोई अलग उपकरण नहीं है, तो यदि आपके पास बिन फ़ाइल का मूल जनरेटर है (अर्थात, इसके लिए एक संपादक मौजूद है ... ब्लेंडर 3 डी की तरह, तो आप उन फ़ाइलों का मैन्युअल रूप से निरीक्षण कर सकते हैं, भी लॉग देखें, और दूसरे व्यक्ति से पूछें कि आपको क्या शामिल करना चाहिए) और फ़ाइलों का आउटपुट आउटपुट https://git-scm.com/book/es/v2/Git-Tools-Advanced-Merging#_manual_remerge के साथ करें

$ git show :1:hello.blend > hello.common.blend $ git show :2:hello.blend > hello.ours.blend $ git show :3:hello.blend > hello.theirs.blend


1

मैं विंडोज़ पर Git के साथ द्विआधारी फ़ाइलों के अंतर / विलय के प्रबंधन के लिए दो रणनीतियों में आया हूं।

  1. Tortoise git आपको विभिन्न फ़ाइल प्रकारों के लिए उनके फ़ाइल एक्सटेंशन के आधार पर भिन्न / मर्ज टूल को कॉन्फ़िगर करने देता है। २.३५.४.३ देखें। Diff / Merge Advanced Settings http://tortoisegit.org/docs/tortoisegit/tgit-dug-settline.html । पाठ्यक्रम की यह रणनीति उपयुक्त भिन्न / मर्ज उपकरण उपलब्ध होने पर निर्भर करती है।

  2. गिट विशेषताओं का उपयोग करके आप अपनी बाइनरी फ़ाइल को पाठ में बदलने के लिए एक टूल / कमांड निर्दिष्ट कर सकते हैं और फिर अपने डिफ़ॉल्ट को अलग कर सकते हैं / उपकरण को मर्ज कर सकते हैं। Http://git-scm.com/book/it/v2/Customizing-Git-Git-Attributes देखें । यहां तक ​​कि लेख भी छवियों को अलग करने के लिए मेटा डेटा का उपयोग करने का एक उदाहरण देता है।

मुझे सॉफ्टवेयर मॉडल की द्विआधारी फ़ाइलों के साथ काम करने के लिए दोनों रणनीतियां मिलीं, लेकिन हम कछुआ गिट के साथ गए क्योंकि कॉन्फ़िगरेशन आसान था।


0

मैं एक्सेल के लिए Git वर्कफ़्लो का उपयोग करता हूं - https://www.xltrail.com/blog/git-workflow-for-excel एप्लिकेशन को मेरी अधिकांश बाइनरी फ़ाइलों से संबंधित मर्ज समस्याओं को हल करने के लिए। यह ओपन-सोर्स ऐप मुझे बहुत अधिक समय खर्च किए बिना मुद्दों को हल करने में मदद करता है और मुझे चेरी को बिना किसी भ्रम के फ़ाइल का सही संस्करण चुनने देता है।


0

मेरा मामला बग की तरह लगता है .... git का उपयोग करते हुए 2.21.0

मैंने एक पुल किया ... इसने द्विआधारी फाइलों के बारे में शिकायत की:

warning: Cannot merge binary files: <path>
Auto-merging <path>
CONFLICT (content): Merge conflict in <path>
Automatic merge failed; fix conflicts and then commit the result.

और फिर यहां किसी भी जवाब में कुछ भी नहीं निकला, जिसके परिणामस्वरूप कोई भी अर्थ निकला।

अगर मैं देखूं कि अब मेरे पास कौन सी फाइल है ... यह मैंने संपादित किया है। अगर मैं या तो:

git checkout --theirs -- <path>
git checkout --ours -- <path>

मुझे आउटपुट मिलता है:

Updated 0 paths from the index

और मेरे पास अभी भी फ़ाइल का मेरा संस्करण है। अगर मैं rm और उसके बाद चेकआउट करता हूं, तो यह 1 के बजाय कहेगा, लेकिन यह अभी भी मुझे फ़ाइल का मेरा संस्करण देता है।

गिट मेरिजेट कहते हैं

No files need merging

और स्थिति कहते हैं

    All conflicts fixed but you are still merging.
    (use "git commit" to conclude merge)

एक विकल्प के लिए प्रतिबद्ध पूर्ववत है ... लेकिन मैं बदकिस्मत था और मेरे पास कई कमिट थे, और यह बुरा पहला था। मैं समय को दोहराना नहीं चाहता।

तो इस पागलपन को हल करने के लिए:

मैं अभी भागा

git commit

जो दूरस्थ संस्करण को खो देता है, और शायद अतिरिक्त बाइनरी फ़ाइल को संग्रहीत करने के लिए कुछ स्थान बर्बाद करता है ... तब

git checkout <commit where the remote version exists> <path>

जो मुझे दूरस्थ संस्करण वापस देता है

फिर फाइल को फिर से एडिट किया ... और फिर कमिट और पुश किया, जिसका मतलब है कि शायद बाइनरी फाइल की एक और कॉपी के साथ स्पेस बर्बाद कर रहा है।


मेरे मामले में, git checkout --ours <path>मैंने प्राप्त करने की कोशिश करने के बाद Updated 0 paths from the index । मैंने तय किया है कि git add <path>कमांड के साथ , जो ऐसा ही करता है।
एंड्री
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.