2015-06-23 6 views
6

मर्ज विवादों को हल करते समय, अधिकांश समय ऐसा होता है क्योंकि फ़ाइल के एक ही बिंदु पर दो लोग डाले जाते हैं। और मैं हमेशा वही करता हूं: बाईं ओर से नया कोड का उपयोग करें, दाएं तरफ से नया कोड कॉपी करें और बाईं ओर से कोड के बाद इसे संलग्न करें।विलय conflics का समाधान करते समय गिट स्वचालित रूप से सम्मिलन संभाल सकता है?

यह मैं सोच रहा है, अगर मैं हमेशा एक ही है, यह इस स्वचालित करने के लिए संभव हो जाना चाहिए मिला है। क्या मैं गिट को भरोसा दिला सकता हूं कि दोनों नए हिस्सों का इस्तेमाल सिर्फ एक के बाद किया जा सकता है?

मुझे लगता है कि, अगर सम्मिलन कुछ लाइनें अलग होगा (एक स्थिति Git स्वचालित रूप से हल करता है), यह किसी भी कम बग प्रस्तुत करने की संभावना नहीं होगा। मैं वैसे भी परिणाम की जांच करने जा रहा हूँ।

(वर्तमान में मैं अपने mergetool रूप DiffMerge उपयोग कर रहा हूँ, कि यदि कोई फर्क नहीं पड़ता।)

+0

क्या होगा यदि आपके पास दो शाखाएं हैं, जिनमें से एक ने 'वापसी 1;' कथन प्रस्तुत किया है, और दूसरे ने 'वापसी -1;' कथन प्रस्तुत किया है? मैं तर्क दूंगा कि उनमें से केवल एक (यदि कोई है) सही होने की संभावना है, और यह कि दोनों को जोड़ना वास्तव में गलत काम है। सभी मामूली मामलों में सही विलय करने के लिए वास्तविक सोच करने की वास्तविक सोच की आवश्यकता होती है, और आम तौर पर यह आवश्यक है कि विलय के पास बुद्धिमान निर्णय लेने के लिए आसपास के कोड को क्या करना चाहिए, इसकी अच्छी समझ हो ... – twalberg

+1

जैसी चीजों का अस्तित्व [अर्थात् मर्ज] (https://www.semanticmerge.com/) प्रमाण है कि एक फ़ाइल में परिवर्तन विलय सामान्य गैर-तुच्छ है। – poke

+1

@twalberg यदि दो रिटर्न एक ही समारोह में होंगे लेकिन कुछ लाइनें अलग होंगी, तो गिट उन्हें ठीक कर देगा और मुझे यह कहने की हिम्मत होगी कि एक बग घुसपैठ करने की समान संभावना है। जब मैं उन्हें मैन्युअल रूप से विलय नहीं कर पाता हूं तो मैं किसी भी अर्थपूर्ण प्रभाव को दोबारा जांचने पर खर्च कर सकता हूं। – AndreKR

उत्तर

9

आप उस के लिए declare a merge driver करने की आवश्यकता होगी:

यह assigned in a .gitattributes गंतव्य शाखा में किया जाता है (जहां आपने मर्ज)

echo yourFiles merge=addTheirs>.gitattributes 
git add .gitattributes 
git commit -m "record addTheirs merge driver" 

(yourFiles की जगह फ़ाइलों के पैटर्न से आप को देखने के लिए कि मर्ज संकल्प लागू करना चाहते हैं)

01 कर रहे हैं

लेकिन यह भी जरूरत है स्थानीय स्तर पर विन्यस्त किया जा करने के लिए:

git config merge.addTheirs.name "keep additions only" 
git config merge.addTheirs.driver addTheirs.sh 

चाल addTheirs स्क्रिप्ट पर है, %O साथ कहा जाता है, %A, %B (पूर्वज, हमारा, उनकी)

एक diff -u %A %B आप जिसे दे देंगे जैसे भिन्नता की:

@@ -1,11 +1,11 @@ 
line 1 
line 2 
-line 3 from master 
+line 3 from dev 
line 4 
line 5 
line 6 
line 7 
line 8 
+line 8bis from dev 
line 9 
line 10 
-line 11 

हालांकि diff हेडर अनुपलब्ध है, एक patch अभी भी करने में सक्षम होगा नई लाइनों को जोड़ने और पुराने को हटा (और क्या आप चाहते हमारा रखने के लिए, और उनकी जोड़ने के लिए)।
विंडोज़ पर, आप gnu patch, but you need to add a manifest ले सकते हैं।

patch -u -p0 $3 $2 

आप इसे लागू करने से पहले पैच से विलोपन को फिल्टर करने की कोशिश कर सकते।

patch=$(diff -u $2 $3 | grep -v "^-") 

लेकिन हंक हैडर (@@ -1,11 +1,11 @@) अब उम्मीद लाइनों की संख्या से मेल खाएंगे (यदि आप केवल 2 पंक्तियाँ जोड़ें और 0 निकाल देता है, यह +1,13 साथ, खत्म होना चाहिए निट +1,11)

आप की जरूरत है करने के लिए अपने पैच पर कार्रवाई: बाहर विलोपन

  • फिल्टर
  • समायोजित हंक हेडर

इसका मतलब है कि addTheirs.sh (यहां तक ​​कि विंडोज पर अपने पथ में डाल करने के लिए,) हो सकता है:

#!/bin/bash 

patch=$(diff -u $2 $3) 
echo "${patch}" > f.pp 

patch2=$(./padd f.pp) 
echo "$patch2" > f.p 

patch -u -p0 $2 -i f.p 

(diff 200+ यूनिक्स का हिस्सा कमांड git-for-windows package का हिस्सा है, इसलिए फिर से है, के सभी यह विंडोज या यूनिक्स पर काम करता है)

'पैड' (पैच एड) उपयोगिता एक स्क्रिप्ट है जो प्रत्येक हंक से किसी भी विलोपन रेखा को हटाती है, और वास्तविक लाइन नंबर का ट्रैक रखने के लिए हंक हेडर को अद्यतन करती है।

मैं जाओ में मेरा बनाया (https://golang.org/, बस unzip a go distro कहीं भी आप चाहते हैं और अपने PATH में जोड़ने)

कॉपी एक padd.go फ़ाइल में निम्न, और टाइप go build padd.go: आप padd निष्पादन मिलता है कि मर्ज चालक कर सकते हैं पैच समायोजित करने के लिए कॉल करें।

package main 

import (
    "fmt" 
    "io/ioutil" 
    "os" 
    "regexp" 
    "strconv" 
    "strings" 
) 

// @@ 1,11 1,13 @@ <= extract prefix '@@ 1, 11 1,' and counter '13' 
var chunkre = regexp.MustCompile(`(?m)^(@@.*,)(\d+)\[email protected]@.*$`) 
var patch = "" 

func main() { 
    fname := os.Args[1] 
    f := "" 
    if b, err := ioutil.ReadFile(fname); err != nil { 
     panic(err) 
    } else { 
     f = string(b) 
    } 
    lines := strings.Split(f, "\n") 

    prefix := "" 
    counter := 0 
    var err error 
    hunk := "" 
    for _, line := range lines { 
     snbadd := chunkre.FindAllStringSubmatch(line, -1) 
     if len(snbadd) > 0 { 
      updatePatch(hunk, prefix, counter) 
      hunk = "" 
      prefix = snbadd[0][1] 
      if counter, err = strconv.Atoi(snbadd[0][2]); err != nil { 
       panic(err) 
      } 
     } else if prefix != "" { 
      if strings.HasPrefix(line, "-") { 
       counter = counter + 1 
       line = " " + line[1:] 
      } 
      hunk = hunk + line + "\n" 
     } 
    } 
    updatePatch(hunk, prefix, counter) 
    fmt.Println(patch) 
} 

func updatePatch(hunk, prefix string, counter int) { 
    if hunk != "" { 
     header := prefix + fmt.Sprintf("%d @@\n", counter) 
     patch = patch + header + hunk 
    } 
} 
+0

ठीक है, मैंने एक फाइल बनाई है, इसे मास्टर करने के लिए प्रतिबद्ध किया है, एक लाइन जोड़ा है और एक अलग लाइन बदल दी है, इसे प्रतिबद्ध किया है, वापस चला गया है, उसी स्थान पर एक और पंक्ति जोड़ा है और उसी लाइन को अलग-अलग बदल दिया है, इसे "परीक्षण" शाखा में प्रतिबद्ध किया है, फिर "मास्टर" में "परीक्षण" को मर्ज करने के लिए अपनी विधि का उपयोग किया। वास्तव में दोनों संघर्ष स्वचालित रूप से हल हो गए थे, लेकिन अब यह "मास्टर" में संस्करण के समान है। एक त्रुटि हुई: http://pastebin.com/U3ADUVjv – AndreKR

+0

@AndreKR f.p और f.pp की सामग्री क्या थी? – VonC

+0

दोनों फाइलों में एक नई लाइन (0x0A)। – AndreKR

संबंधित मुद्दे

 संबंधित मुद्दे