एक संपूर्ण फ़ाइल को 'स्वीकार करें' या 'एक्सेप्ट माइन' का सरल टूल, जो कि git का उपयोग करके पूरी फाइल पर है


399

मैं एक दृश्य मर्ज उपकरण नहीं चाहता, और मुझे भी विवादित फ़ाइल को vi नहीं करना है और मैन्युअल रूप से HEAD (मेरा) और आयातित परिवर्तन (उनके) के बीच चयन करना है। ज्यादातर समय मैं या तो उनके सभी बदलाव चाहता हूं या मेरा सभी। आमतौर पर ऐसा इसलिए होता है क्योंकि मेरे बदलाव ने इसे और तेज कर दिया है और एक पुल के माध्यम से मेरे पास वापस आ रहा है, लेकिन विभिन्न स्थानों में इसे थोड़ा संशोधित किया जा सकता है।

क्या एक कमांड लाइन टूल है जो संघर्ष मार्करों से छुटकारा पायेगा और मेरी पसंद के आधार पर सभी एक तरह से या किसी अन्य का चयन करेगा? या git कमांड का एक सेट, जिसे मैं प्रत्येक को करने के लिए खुद को उपनाम दे सकता हूं।

# accept mine
alias am="some_sequence;of;commands"
alias at="some_other_sequence;of;commands"

ऐसा करना कष्टप्रद है। 'मेरा स्वीकार करो' के लिए मैंने कोशिश की है:

randy@sabotage ~/linus $ git merge test-branch
Auto-merging Makefile
CONFLICT (content): Merge conflict in Makefile
Automatic merge failed; fix conflicts and then commit the result.

randy@sabotage ~/linus $ git checkout Makefile 
error: path 'Makefile' is unmerged

andy@sabotage ~/linus $ git reset --hard HEAD Makefile 
fatal: Cannot do hard reset with paths.

इन परिवर्तन मार्करों से मुझे कैसे छुटकारा मिलना चाहिए?

मैं कर सकता हूँ:

git reset HEAD Makefile; rm Makefile; git checkout Makefile

लेकिन ऐसा लगता है कि इसके बारे में गोल नहीं है, एक बेहतर तरीका होना चाहिए। और इस बिंदु पर, मुझे यकीन नहीं है कि अगर मुझे भी लगता है कि मर्ज हुआ है, तो मुझे नहीं लगता कि यह जरूरी भी काम करता है।

दूसरे तरीके से जाना, 'अपने को स्वीकार' करना भी उतना ही गड़बड़ है। एकमात्र तरीका है कि मैं यह पता लगा सकता हूँ:

git show test-branch:Makefile > Makefile; git add Makefile;

यह मुझे एक गड़बड़ संदेश भी देता है, जिसमें दो बार टकराव: मेकफाइल है।

क्या कोई कृपया यह बता सकता है कि उपर्युक्त दोनों क्रियाओं को सरल तरीके से कैसे किया जाए? धन्यवाद


4
मुझे आपको इसे तीन साल + git कमांड लाइन उपयोगकर्ता के रूप में देना है, मुझे यह हास्यास्पद रूप से स्मृति से करना मुश्किल लगता है। यह वास्तव में डिफ़ॉल्ट रूप से बनाया जाना चाहिए।
मावी लेडफोर्ड

जवाबों:


602

समाधान बहुत सरल है। सूचकांकgit checkout <filename> से फ़ाइल की जाँच करने की कोशिश करता है , और इसलिए मर्ज पर विफल रहता है।

आपको क्या करने की आवश्यकता है (यानी एक जांच करें ):

अपने स्वयं के संस्करण की जांच करने के लिए आप इनमें से किसी एक का उपयोग कर सकते हैं :

git checkout HEAD -- <filename>

या

git checkout --ours -- <filename>

या

git show :2:<filename> > <filename> # (stage 2 is ours)

अन्य संस्करण की जांच करने के लिए आप इनमें से किसी एक का उपयोग कर सकते हैं :

git checkout test-branch -- <filename>

या

git checkout --theirs -- <filename>

या

git show :3:<filename> > <filename> # (stage 3 is theirs)

इसे हल करने के लिए आपको 'ऐड' चलाने की भी आवश्यकता होगी:

git add <filename>

31
मुझे यह थोड़ा अजीब लगा --oursऔर --theirsइसका मतलब है कि इस कमांड को
आजमाते

6
उपयोग करते समय सावधानी बरतें git show- यह नईलाइन को सामान्य बनाने में मदद करता है।
क्रोनिकल

2
यह कुछ फ़ाइलों के लिए अच्छा है, लेकिन जब आपके पास संघर्ष में कई फाइलें होती हैं (क्योंकि एक टिप्पणी में एक तिथि बदल गई थी!), तो आप इसे कैसे करते हैं?
झोवानी

4
@ सेन्थोस: --Git द्वारा पथ नामों (फ़ाइल नाम, निर्देशिका) से संशोधन (शाखा नाम आदि) को अलग करने के लिए उपयोग किया जाता है। यदि कोई नाम शाखा का नाम या फ़ाइल का नाम है, तो यह तय नहीं किया जा सकता है कि यह महत्वपूर्ण है। यह तर्क (फ़ाइल नाम) से अलग विकल्पों के लिए डबल डैश का उपयोग करने के POSIX (या GNU) सम्मेलन का अनुसरण करता है।
जकुब नारबस्की 12

3
@Sammaron @Joshua Muheim; theirs/ oursबदली दिखाई कर सकते हैं अगर आप एक रिबेस आपरेशन के संदर्भ में संघर्ष को हल करने होते हैं। क्योंकि rebase टार्गेट ब्रांच को चेक करके काम करता है तो चेरी-पिकिंग "टार्गेट पर" आपकी "ब्रांच से आती है, इनकमिंग चेंज (" उनका ")" आपकी "ब्रांच से होता है, और करंट ब्रांच टारगेट ब्रांच (हमारा) है )।
RJFalconer

93

इसे इस्तेमाल करे:

उनके परिवर्तनों को स्वीकार करने के लिए: git merge --strategy-option theirs

तुम्हारा स्वीकार करने के लिए: git merge --strategy-option ours


5
ध्यान दें कि यह सभी परस्पर विरोधी फ़ाइलों के लिए आपके बदलावों को बनाए रखेगा, इसलिए यदि कोई अप्रत्याशित संघर्ष होता है तो यह खतरनाक हो सकता है।
जॉन

3
और आप इसे अन्य मर्ज-वाई कमांड जैसे चेरी-पिक और रिबेस के लिए उपयोग कर सकते हैं।
इडबरी

50

जकूब के जवाब के आधार पर आप सुविधा के लिए निम्नलिखित गिट उपनामों को कॉन्फ़िगर कर सकते हैं:

accept-ours = "!f() { git checkout --ours -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"
accept-theirs = "!f() { git checkout --theirs -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"

वे वैकल्पिक रूप से फ़ाइलों के एक या कई पथों को हल करने के लिए लेते हैं और वर्तमान निर्देशिका के तहत सब कुछ हल करने के लिए डिफ़ॉल्ट होते हैं यदि कोई नहीं दिया जाता है।

उन्हें [alias]अपने सेक्शन में जोड़ें ~/.gitconfigया चलाएं

git config --global alias.accept-ours '!f() { git checkout --ours -- "${@:-.}"; git add -u "${@:-.}"; }; f'
git config --global alias.accept-theirs '!f() { git checkout --theirs -- "${@:-.}"; git add -u "${@:-.}"; }; f'

1
मेरे लिए काम नहीं कर रहे हैं ... ये मार या कुछ अन्य खोल के लिए हैं?
user456584

ये गिट एलियाज हैं, इन्हें [alias]अपने सेक्शन में जोड़ें ~.gitconfigया उपयोग करें git config --global accept-ours "..."। मेरे उत्तर का संपादन किया है।
kynan

2
आपको पता नहीं है कि इस उपनाम ने मुझे कितने समय तक बचाया। थम्स अप!
एडम पार्किन

1
@hakre सुनिश्चित करें कि आप उपनाम को उद्धृत करते हैं, अन्यथा आपका शेल इसकी व्याख्या करने का प्रयास करेगा। या सिर्फ मैन्युअल रूप से अपना संपादन करें ~/.gitconfig
kynan

1
डिफ़ॉल्ट मानों के लिए शैल सिंटैक्स:!f() { git checkout --ours -- "${@:-.}" git add -u "${@:-.}; }; f
jthill

17

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

accept-ours = "!f() { [ -z \"$@\" ] && set - '.'; git checkout --ours -- \"$@\"; git add -u -- \"$@\"; }; f"
accept-theirs = "!f() { [ -z \"$@\" ] && set - '.'; git checkout --theirs -- \"$@\"; git add -u -- \"$@\"; }; f"

0

संघर्ष को हल करने के लिए आदर्श स्थिति है जब आप समय जो जिस तरह से आप उन्हें हल करना चाहते हैं और पारित कर सकते हैं के आगे पता है -Xoursया -Xtheirsपुनरावर्ती मर्ज रणनीति विकल्प। इसके बाहर मैं तीन दर्शनीय देख सकता हूं:

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

इन तीन परिदृश्यों को संबोधित करने के लिए आप अपनी .gitconfigफ़ाइल में (या समतुल्य) निम्न पंक्तियाँ जोड़ सकते हैं :

[merge]
  conflictstyle = diff3
[mergetool.getours]
  cmd = git-checkout --ours ${MERGED}
  trustExitCode = true
[mergetool.mergeours]
  cmd = git-merge-file --ours ${LOCAL} ${BASE} ${REMOTE} -p > ${MERGED}
  trustExitCode = true
[mergetool.keepours]
  cmd = sed -I '' -e '/^<<<<<<</d' -e '/^|||||||/,/^>>>>>>>/d' ${MERGED}
  trustExitCode = true
[mergetool.gettheirs]
  cmd = git-checkout --theirs ${MERGED}
  trustExitCode = true
[mergetool.mergetheirs]
  cmd = git-merge-file --theirs ${LOCAL} ${BASE} ${REMOTE} -p > ${MERGED}
  trustExitCode = true
[mergetool.keeptheirs]
  cmd = sed -I '' -e '/^<<<<<<</,/^=======/d' -e '/^>>>>>>>/d' ${MERGED}
  trustExitCode = true

get(ours|theirs)उपकरण सिर्फ फ़ाइल के संबंधित संस्करण रखता है और परिवर्तन अन्य संस्करण से (ताकि मिलाने की होती है) के सभी फेंक देता है।

merge(ours|theirs)उपकरण स्थानीय, आधार से तीन तरह से मर्ज, और फ़ाइल के दूरदराज के कारण बताये दिशा में संघर्ष को सुलझाने के लिए चुनने फिर से करता है,। इसके कुछ गुहिकायन हैं, विशेष रूप से: यह उन विभिन्‍न विकल्‍पों को नजरअंदाज करता है जो मर्ज कमांड (जैसे अल्‍गोरिदम और व्हॉट्सएप हैंडलिंग) में पारित किए गए थे; मूल फ़ाइलों से मर्ज को साफ करता है (इसलिए फ़ाइल में कोई भी मैन्युअल परिवर्तन छोड़ दिया जाता है, जो अच्छा या बुरा हो सकता है); और इसका फायदा यह है कि इसे अलग-अलग मार्करों द्वारा भ्रमित नहीं किया जा सकता है जो कि फ़ाइल में होना चाहिए।

keep(ours|theirs)उपकरण केवल diff मार्करों और संलग्न वर्गों बाहर संपादित करता है, उन्हें नियमित अभिव्यक्ति द्वारा पता लगाने। इसका लाभ यह है कि यह मर्ज कमांड से अलग विकल्प को संरक्षित करता है और आपको हाथ से कुछ संघर्षों को हल करने की अनुमति देता है और फिर स्वचालित रूप से बाकी को हल करता है। इसका नुकसान यह है कि अगर फ़ाइल में अन्य संघर्ष मार्कर हैं तो यह भ्रमित हो सकता है।

ये सभी रनिंग के द्वारा उपयोग किए जाते हैं git mergetool -t (get|merge|keep)(ours|theirs) [<filename>]यदि <filename>आपूर्ति नहीं की जाती है तो यह सभी विवादित फाइलों को प्रोसेस करता है।

आम तौर पर बोलते हुए, आप जानते हैं कि नियमित अभिव्यक्ति को भ्रमित करने के लिए कोई अलग मार्कर नहीं हैं, keep*कमांड के वेरिएंट सबसे शक्तिशाली हैं। यदि आप mergetool.keepBackupविकल्प को सही या सत्य नहीं छोड़ते हैं, तो मर्ज के बाद आप मर्ज *.origके परिणाम के खिलाफ फाइल को यह जांचने के लिए अलग कर सकते हैं कि यह समझ में आता है। एक उदाहरण के रूप में, मैं mergetoolकमिट करने से पहले परिवर्तनों का निरीक्षण करने के लिए निम्नलिखित को चलाता हूं :

for f in `find . -name '*.orig'`; do vimdiff $f ${f%.orig}; done

नोट : यदि merge.conflictstyleऐसा नहीं है, diff3तो नियम में इसके बजाय /^|||||||/पैटर्न sedहोना /^=======/चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.