Git - चयनित फाइल पर मर्ज संघर्ष और मैनुअल मर्ज को कैसे मजबूर करें


83

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

मैंने उत्तर की तलाश की:

  1. मैं -no-प्रतिबद्ध और --no-ff मर्ज विकल्पों का उपयोग कर रहा हूं , लेकिन यह समान नहीं है।
  2. यहाँ और यहाँ कोई एक ही सवाल पूछता है लेकिन कोई हल नहीं है।
  3. इसी प्रकार के मामले हो रहा है फ़ाइल से किया जा रहा विलय कर दिया रोकने के लिए कैसे : युक्त .gitattributes का उपयोग कर somefile.php मर्ज = हमारा । मैंने कुछ मर्ज विकल्प खोजने की कोशिश की जो संघर्ष या बल मैनुअल मर्ज उत्पन्न करेगा लेकिन अब तक कोई नहीं मिला।
  4. .gitattributes युक्त: somefile.php -merge को स्वचालित रूप से मर्ज नहीं किया जाता है और इसलिए मैन्युअल मर्ज को मजबूर किया जाता है। यह 90% समाधान है, लेकिन जो मैं चाहता हूं वह स्वचालित मर्ज की कोशिश करना है और इसे संघर्ष के रूप में चिह्नित करना है चाहे यह सफल हो या न हो। लेकिन यह अब तक समाधान के सबसे करीब है। (... स्पष्टीकरण के लिए धन्यवाद चार्ल्स बेली ...)
  5. कोई व्यक्ति कस्टम मर्ज ड्राइवर ( 1 , 2 ) लिखने का सुझाव देता है , लेकिन यह कैसे करना है यह मेरे लिए स्पष्ट नहीं है।

संपादित करें: संस्करण 4. विवरण


6
यह वह सटीक उत्तर नहीं होगा जिसकी आप तलाश कर रहे हैं, लेकिन उसी कारण से मैं git fetchपहले करता हूं , फिर उपयोग करता git difftool <file> FETCH_HEADहूं, इसलिए मैं रिमोट शाखा में परिवर्तन को स्थानीय रूप से मैन्युअल रूप से लागू कर सकता हूं।
MHC

MHC: यह अच्छी चाल है (खासकर यदि प्रत्येक समानांतर शाखा के लिए स्क्रिप्ट में सहेजा गया है + स्वचालित मर्ज से फ़ाइलों को रोकने के साथ संयुक्त)। मुख्य नुकसान यह है कि टीम वर्कफ़्लो में कोई व्यक्ति इस चरण को भूल जाता है और इसके बजाय केवल सामान्य मर्ज करता है।
Stepan

2
सेटिंग -mergeआपको फ़ाइलों को मर्ज करने से नहीं रोकती है, यह आपको इसे मैन्युअल रूप से करने के लिए मजबूर करती है, जैसे कि एक मर्जटूल के साथ। क्या यह आपकी ज़रूरत नहीं है?
सीबी बेली

यह 90% मैं क्या चाहता हूँ। मैं चाहूंगा कि मर्ज अपने आप हो जाए, लेकिन इस संवेदनशील फाइल के लिए मर्ज तब भी संघर्ष माना जाता है, जब कोई नहीं होता है इसलिए हर बार मैनुअल चेक को मजबूर किया जाता है।
Stepan

@Stepan मैं एक समान स्थिति में हूं इसलिए मैं कुछ स्पष्ट करना चाहता हूं। आप क्या कह रहे हैं कि साथ -mergeमें .gitatttributes git mergeकुछ नहीं करता है, और सब काम मर्ज उपकरण के साथ नीचे होना चाहिए? तो मर्ज टूल का उपयोग करने के लिए कोई <<<<<< ===== >>>> नहीं है, है ना? और दान का समाधान यह प्रदान करता है?
नीरो ग्रिस

जवाबों:


60

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

सबसे पहले, मर्ज ड्राइवर स्क्रिप्ट बनाएं जिसे कहा जाता है merge-and-verify-driver। इसे निष्पादन योग्य बनाएं और इसे एक उपयुक्त स्थान पर रखें (आप इस स्क्रिप्ट को रेपो में चेक करने पर विचार कर सकते हैं, यहां तक ​​कि, क्योंकि रेपो की कॉन्फ़िगरेशन फ़ाइल इस पर निर्भर होने वाली है)। संवेदनशील फ़ाइलों के मर्ज को करने के लिए Git इस शेल स्क्रिप्ट को निष्पादित करने जा रहा है:

#!/bin/bash
git merge-file "${1}" "${2}" "${3}"
exit 1

यह केवल डिफ़ॉल्ट मर्ज व्यवहार करता है जो Git सामान्य रूप से स्वयं करता है। मुख्य अंतर यह है कि स्क्रिप्ट हमेशा गैर-शून्य लौटती है (यह इंगित करने के लिए कि संघर्ष था, भले ही मर्ज वास्तव में संघर्षों के बिना हल हो गया था)।

इसके बाद, आपको Git को अपने कस्टम मर्ज ड्राइवर के अस्तित्व के बारे में बताना होगा। आप इसे रेपो कॉन्फिग फाइल में करते हैं ( .git/config):

[merge "verify"]
        name = merge and verify driver
        driver = ./merge-and-verify-driver %A %O %B

इस उदाहरण में, मैंने merge-and-verify-driverरेपो के शीर्ष स्तर निर्देशिका ( ./) में डाल दिया है । आपको तदनुसार स्क्रिप्ट को पथ निर्दिष्ट करने की आवश्यकता होगी।

अब, आपको बस संवेदनशील फ़ाइलों को उचित विशेषताएँ देने की आवश्यकता है ताकि उन फ़ाइलों को मर्ज करते समय कस्टम मर्ज ड्राइवर का उपयोग किया जाए। इसे अपनी .gitattributesफ़ाइल में जोड़ें :

*.sensitive merge=verify

यहाँ, मैंने Git से कहा है कि पैटर्न से मेल खाने वाले नाम वाली किसी भी फ़ाइल *.sensitiveको कस्टम मर्ज ड्राइवर का उपयोग करना चाहिए। जाहिर है, आपको उस पैटर्न का उपयोग करने की आवश्यकता है जो आपकी फ़ाइल के लिए उपयुक्त है।


इस विस्तृत गाइड के लिए बहुत बहुत धन्यवाद!
Stepan

13
ऐसा लगता है कि मर्ज ड्राइवर को "स्पष्ट" समाधान में नहीं बुलाया गया है। उदाहरण के लिए, यदि फ़ाइल केवल एक शाखा पर बदली गई थी और आप एक मर्ज करते हैं, तो "संवेदनशील" फ़ाइल अधिलेखित हो जाएगी और मर्ज ड्राइवर को नहीं बुलाया जाएगा। क्या इसे ठीक करने का कोई रास्ता है?
विटालिबी

क्या यह वास्तव में ऐसे व्यवहार करेगा जैसे @VitalyB बताता है? धन्यवाद!
फिलीपो

1
यह काम करता है, लेकिन क्या किसी मशीन पर सभी रिपॉजिटरी में इसे वैश्विक विकल्प बनाने का कोई तरीका है? इसके अलावा, कमांड लाइन द्वारा इसे लागू करने का कोई तरीका? काश, कमांड लाइन पर मर्ज की रणनीति को बदलने के रूप में सरल रूप में कुछ ऐसा करने का एक तरीका था।
user1748155

4
@VitalyB टिप्पणी में जोड़ना। मर्ज भी प्रकट नहीं होता है अगर दोनों शाखाओं ने एक फ़ाइल में एक ही परिवर्तन किया। उदाहरण के लिए, दोनों शाखाओं ने 1 से संस्करण बढ़ाया, और आप विलय करने की कोशिश करते हुए 2 तक बढ़ाना चाहेंगे ... बहुत व्यावहारिक समस्या, अभी तक अनसुलझी है ।:(
VasiliNovikov

1

कस्टम मर्ज ड्राइवर का उपयोग करने पर इन दोनों आदेशों का समान प्रभाव पड़ता है:

git merge --no-commit your_target_branch
git checkout --conflict merge .   (do not forget the . and run it in the top dir of the repository)

पहला कमांड मर्ज कमेटी के निर्माण से पहले मर्ज को रोकता है, और दूसरा निशान दो शाखाओं में संशोधित सभी फाइलों को एक संघर्ष के रूप में हल करता है, भले ही मूल रूप से कोई संघर्ष न हो।


मुझे "एक समय" समाधान का विचार पसंद है (मैं बस ऐसे मामले में भाग गया), हालांकि यह मेरे लिए काम नहीं करता था। गिट ने एक एफएफ किया जिसके परिणामस्वरूप एक बुरा मर्ज (यह अनिवार्य रूप से और हमारा विलय था)।
नीरो ग्रिस

@Nerogris वास्तव में यह फास्ट-फ़ॉरवर्ड मर्ज के लिए काम नहीं करेगा। आप हमेशा -no-ff विकल्प को जोड़ सकते हैं, लेकिन दूसरी कमांड कोई संघर्ष उत्पन्न नहीं करेगी क्योंकि मर्ज की दो शाखाओं में से एक में सामान्य पूर्वज से कोई बदलाव नहीं होता है।
लूसीउल

मैं अपने वैश्विक विन्यास में गलत करने के लिए तैयार है। जब मैंने कहा कि यह एफएफ मर्ज था तो मेरा मतलब है कि अगर मैंने गिट को ऐसा नहीं करने के लिए कहा था, तो यह होगा।
नीरो ग्रिस

0

नोट: यह आलेख " PO फ़ाइलों के लिए एक गिट मर्ज ड्राइवर लिखना " एक तरह से मैन्युअल रूप से किसी फ़ाइल को मर्ज करने पर आप जिस तरह का हेरफेर कर सकते हैं, उसे दिखाता है: कुछ डेटा तैयार करने के लिए आप अपने मैनुअल मर्ज के लिए इसे पूर्व-संसाधित कर सकते हैं।

git merge-fileमर्ज करने से पहले फ़ाइलों को DECRYPT (और पुनः एन्क्रिप्ट करने) के लिए, उदाहरण के लिए, उपयोग किया जा सकता है (!)

आपके मामले में, आपके मर्ज ड्रायवर को गैर-0 स्थिति से बाहर करना यह सुनिश्चित करता है कि मर्ज मैन्युअल होगा।


2
क्या आप "PO फ़ाइलों के लिए मर्ज ड्राइवर" लिंक के बारे में विस्तार से बता सकते हैं क्योंकि ऐसा लगता है कि मेरे लिए अस्वीकृत एक्सेस का परिणाम है? मैं उम्मीद कर रहा हूँ कि यह सवाल का जवाब प्रदान करेगा stackoverflow.com/questions/16214067/…
मिको Rantalainen

@MikkoRantalainen काम पर अवरुद्ध है, इसलिए मैं आज शाम घर से कोशिश करूंगा।
VonC

1
"PO फाइलों के लिए मर्ज ड्राइवर" मेरे लिए भी काम नहीं करता है :(

1
@sampablokuper I कॉन्कुर: लेख "गैर-अधिकृत" रीडर के लिए अवरुद्ध है। मुझे पता नहीं क्यों होगा।
वॉन

1
@sampablokuper अभी मेरे पास इस ब्लॉग की पहुंच नहीं है। मैं इसकी सामग्री खोजता रहूँगा।
वॉन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.