क्या कोई गिट-मर्ज -ड्री-रन विकल्प है?


724

मैं एक दूरस्थ शाखा में विलय कर रहा हूं जिसमें बहुत सारे संघर्ष हो सकते हैं। मैं कैसे बता सकता हूं कि इसमें टकराव होगा या नहीं?

मैं एक ऐसा कुछ नहीं दिख रहा है --dry-runपर git-merge


5
चूँकि Git से ब्रांचिंग सस्ती है, इसलिए कॉपी की जांच न करें और फिर आपको सूखा रन करने की आवश्यकता नहीं है? आप बाद में कॉपी को बाहर फेंक सकते हैं।
अलेक्जेंडर मिल्स

जवाबों:


811

जैसा कि पहले उल्लेख किया गया था, --no-commitझंडे में पास , लेकिन एक तेजी से आगे की प्रतिबद्ध से बचने के लिए, इस तरह से भी गुजरें --no-ff:

$ git merge --no-commit --no-ff $BRANCH

मंचन परिवर्तनों की जांच करने के लिए:

$ git diff --cached

और आप मर्ज को पूर्ववत कर सकते हैं, भले ही यह तेजी से अग्रेषित मर्ज हो:

$ git merge --abort

51
यह बहुत अच्छा है, लेकिन फिर भी आपकी कार्यशील प्रति संशोधित होगी। यदि आपका रेपो एक जीवित वेबसर्वर है तो आप संघर्षों के साथ फाइलें परोस सकते हैं।
dave1010

21
आप वास्तव में काम की नकल को प्रभावित किए बिना मर्ज नहीं कर सकते।
मियादी

55
सच है, लेकिन कुछ ऐसा है git merge --only-if-there-wont-be-any-conflictsया git diff --show-conflicts <commit>वास्तव में आसान होगा। शर्म की बात है यह अभी तक संभव नहीं है, या मैं कुछ याद कर रहा हूँ?
dave1010

344
@ dave1010 आपको लाइव वेबसर्वर पर मर्ज को संभालना नहीं चाहिए !!! यही आपका विकास बॉक्स है! "ठेस" शाखा को ठीक करें और फिर इसे असली वेबसर्वर पर धकेल दें।
jpswain

52
यदि आप एक लाइव / प्रोडक्शन सर्वर पर काम करते हैं तो आप कभी भी कुछ नहीं करना चाहते हैं लेकिन git pull --ff-only!
ThiefMaster

237

मुझे बस एक ऐसा तरीका लागू करना था जो स्वचालित रूप से एक भंडार और इसके रिमोट के बीच टकराव का पता लगाता है। यह समाधान मेमोरी में मर्ज करता है, इसलिए यह सूचकांक को नहीं छूएगा, न ही काम करने वाले पेड़ को। मुझे लगता है कि यह सबसे सुरक्षित संभव तरीका है जिससे आप इस समस्या को हल कर सकते हैं। यहां देखिए यह कैसे काम करता है:

  1. रिमोट को अपने रिपॉजिटरी में लाएं। उदाहरण के लिए: git fetch origin master
  2. रन मर्ज मर्ज-बेस: git merge-base FETCH_HEAD master
  3. रन गेट मर्ज-ट्री: git merge-tree mergebase master FETCH_HEAD( मर्जबेस हेक्साडेसिमल आईडी है जो पिछले बेस में मर्ज-बेस प्रिंट होता है)

अब मान लीजिए कि आप दूरस्थ मास्टर को अपने स्थानीय मास्टर के साथ मिलाना चाहते हैं, लेकिन आप किसी भी शाखा का उपयोग कर सकते हैं। git merge-treeमेमोरी में मर्ज को निष्पादित करेगा और परिणाम को मानक आउटपुट पर प्रिंट करेगा। पैटर्न के लिए Grep <<या >>। या आप आउटपुट को फ़ाइल में प्रिंट कर सकते हैं और जाँच सकते हैं। यदि आप 'दोनों में परिवर्तित' से शुरू होने वाली रेखा पाते हैं, तो संभवत: एक संघर्ष होगा।


41
यह उत्तर आइएमएचओ का तरीका है, क्योंकि यह काम की कॉपी या इंडेक्स को छूने के बिना एक साफ समाधान है।
sschuberth

23
BTW, चरण 2 और 3 को एक कदम में मर्ज किया जा सकता है, लिनक्स कंसोल के बैकटिक ऑपरेटर का उपयोग करके, जो इसकी सामग्री का मूल्यांकन करता है:git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
jakub.g

15
[। Alias] में .gitconfig जोड़ें: dry = "! F () {git मर्ज-ट्री` git मर्ज-बेस $ 2 $ 1 `$ 2 $ 1;}; f" # चेक करें कि गुरु के साथ देव का विलय कैसे होगा: git dry देव गुरु
नोएल

8
मेरी नई fav GIT लाइन: git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"बस कमाल है! +100
रुडी

4
इस परीक्षण में मुझे 'दोनों के झंडे विलय' में 'परिवर्तन' के लिए मिला, जहाँ दोनों शाखाएँ एक ही फ़ाइल को संशोधित करती हैं, भले ही वे एक विलय संघर्ष में परिणत न हों। केवल वास्तविक संघर्षों की पहचान करने के लिए, मुझे संघर्ष मार्कअप के लिए टटोलना आवश्यक था जो इस तरह से शुरू होता है: +<<<<<<< .ourइसलिए मैं grep अभिव्यक्ति का उपयोग करता हूं जैसेgrep -q '^+<* \.our$'
लड़के

55

इस के लिए मेरा सरल जानवर बल समाधान है:

  1. एक "पूर्व-मास्टर" शाखा बनाएं (पाठ्यक्रम के मास्टर से)

  2. इस प्री-मास्टर में उन सभी चीजों को मिलाएं जो आप चाहते हैं।
    फिर आप देख सकते हैं कि मास्टर को छुए बिना विलय कैसे हुआ।

    • पूर्व गुरु को गुरु या में मिलाएं
    • मास्टर में सभी वानाबे-जारी शाखाओं को मिलाएं

वैसे भी, मैं @ Orange80 की सलाह मानूंगा।


5
मुझे @akostajti समाधान पसंद है, लेकिन यह अभी तक एक और कम विकल्प है। वास्तव में मैं रक्षात्मक रहना पसंद करता हूं और एक नई अस्थायी शाखा बनाता हूं (निश्चित रूप से केवल तभी जब मैं संघर्ष की उम्मीद करता हूं, अन्यथा यह एक ओवरकिल होगा), और अगर कुछ गलत हो जाता है, तो बस इसे हटा दें।
jakub.g

1
अगर यह एक "गंदा" समाधान है या नहीं, लेकिन यह वास्तव में काम करता है। मुझें यह पसंद है! (य)
सारा

3
यह स्वीकृत समाधान होना चाहिए, इमो। यह त्वरित, आसान, सुरक्षित, प्रतिवर्ती, सहज है, और जब तक आप शुरू करने से पहले कोई अनपेक्षित परिवर्तन नहीं करते हैं, तब तक इसका कोई दुष्प्रभाव नहीं होगा।
बॉब रे

3
यह समाधान बताता है कि समझ में नहीं आता कि कैसे काम करता है। शाखा सिर्फ संकेत हैं और आप केवल एक निरर्थक सूचक बना रहे हैं। आपको बुरा लग रहा है कि आप किसी भी तरह अपनी शाखा के विलय पर चोट कर सकते हैं लेकिन आप नहीं कर सकते। आप हमेशा कर सकते हैं git merge --abortयदि कोई विवाद था, git reset --hard HEAD~1अगर कोई मर्ज था या git reset --hard origin/master। एक और शाखा बनाने से आपको सुरक्षा का एहसास होता है लेकिन अगर आप सीखते हैं कि कैसे काम करता है तो आप समझेंगे कि यह गलत डर है। जब चिंता काम की कॉपी नहीं बदलने की होती है, तो इसका कोई समाधान नहीं है।
थिबॉल्ट डी।

@ thibault-d इस बारे में सोचें कि जब आप एक साफ शाखा से शुरू नहीं करते हैं तो समाधान कितना जटिल है। git merge --no-commitयदि यह तेजी से अग्रेषित किया जा सकता है, तो मर्ज को समाप्त न करें। git merge --abortविलय होने पर काम नहीं करता है। यदि आप इसे एक स्क्रिप्ट के रूप में लिखना चाहते हैं, तो यह अजीब है, क्योंकि git mergeविभिन्न प्रकार के संघर्षों को समझाने के लिए अच्छे पर्याप्त त्रुटि कोड के साथ उत्तर नहीं है। एक ताजा शाखा के साथ काम करने से एक टूटी हुई स्क्रिप्ट को अपने रेपो को उस स्थिति में छोड़ने से रोकता है जिसमें मैन्युअल हस्तक्षेप की आवश्यकता होती है। सुनिश्चित करें कि आप कुछ भी नहीं खो सकते हैं। लेकिन यह अन्यथा बनाना आसान है।
एरिक एरोनिटी

47

जीआईटी के साथ मर्ज को हटाना इतना आसान है कि आपको सूखे रन के बारे में भी चिंता नहीं करनी चाहिए:

$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world

संपादित करें: जैसा कि नीचे दिए गए टिप्पणियों में उल्लेख किया गया है, यदि आपके पास अपनी कार्यशील निर्देशिका या मंचन क्षेत्र में परिवर्तन हैं, तो आप ऊपर दिए गए कार्य करने से पहले उन्हें रोकना चाहेंगे (अन्यथा वे git resetउपरोक्त का पालन ​​करते हुए गायब हो जाएंगे )


7
बस जाँच करें कि क्या मर्ज तेजी से आगे होगा (एफएफ) git branch --contains HEADसीधे या उससे भी अधिक की सूची की जांच करने का मामला है , बस उपयोग करेंgit merge --ff-only
ब्रायन फिलिप्स

7
git reset --hard, कुछ डिलीट-ऑफ-इन-इंफोर्मेशन-विथ-नो-बैकआउट कमांड्स में से एक है जो git में है, इसलिए इसे अत्यधिक सावधानी के साथ उपयोग किया जाना चाहिए। इस तरह, -1 के रूप में
Kzqai

8
@ टच्क्वाक में अभी भी रिफ्लेक्ट है।
Kissaki

3
--dry-run"अगर एक मर्ज तेजी से आगे होगा" जाँच नहीं। यह सटीक आउटपुट लौटाएगा जो एक मर्ज होगा: फाइलें, संघर्ष आदि। क्या एफएफ वास्तव में दिलचस्प नहीं है, है?
रुडी

3
कैसे के बारे में git stash; git reset --hard? @BrianPhillips
कोड

41

मैंने इसे करने के लिए एक उपनाम बनाया और एक आकर्षण की तरह काम करता है, मैं यह करता हूं:

 git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '

अब मैं सिर्फ फोन करता हूं

git mergetest <branchname>

यह पता लगाने के लिए कि क्या कोई संघर्ष है।


प्रतिभाशाली! मैं यह रख रहा हूं।
qbert65536

28

बस अपनी वर्तमान शाखा को दूरस्थ शाखा के विरुद्ध अलग करें, यह आपको बताएगा कि जब आप एक पुल / मर्ज करते हैं तो क्या बदलने वाला है।

#see diff between current master and remote branch
git diff master origin/master

1
दिलचस्प विचार। मैं उस आउटपुट को कैसे देखूंगा और यह निर्धारित करूंगा कि मर्ज काम करने वाला है या नहीं?
MatrixFrog

6
यह आपको नहीं बताएगा कि क्या कोई संघर्ष होगा ... लेकिन यह आपको एक सामान्य विचार देगा कि यदि आपने एक पुल / मर्ज किया तो क्या होगा।
तिम

10
यह आपको केवल दो शाखाओं के बीच का अंतर बताएगा, यह आपको यह नहीं बताएगा कि मर्ज का परिणाम क्या होगा। यह एक महत्वपूर्ण अंतर है क्योंकि विलय कुछ मामलों में स्वचालित रूप से अलग-अलग शाखाओं से परिवर्तन ले लेता है, जब वे प्रतिबद्ध थे। संक्षेप में, एक बदलाव करने से आपको लगता है कि आपके कुछ बदलावों को वापस ले लिया जाएगा जब वास्तविकता में, मर्ज प्रक्रिया स्वचालित रूप से पुराने लोगों पर नए बदलाव लेगी। आशा है कि समझ में आता है।
मार्कज़्ज़ादा

3
@ Mirthlab की टिप्पणी पर निर्माण करने के लिए, अंतर और विलय के बीच एक महत्वपूर्ण अंतर होगा यदि कोई पहले "हमारा" मर्ज रणनीति (या कुछ अन्य मैनुअल मर्ज फ़िक्सअप) के साथ मर्ज करता है; अंतर आपको उन अंतरों को भी दिखाएगा जो पहले से ही "मर्ज" के रूप में गिने जाते हैं।
ताओ

21

मैं ऐसा करने के लिए अनुरोध-पुल git कमांड का उपयोग करता हूं । यह आपको हर परिवर्तन को देखने की अनुमति देता है जो विलय के समय होता है, लेकिन आपके स्थानीय या दूरस्थ रिपॉजिटरी पर कुछ भी किए बिना

उदाहरण के लिए, कल्पना करें कि आप "फ़ीचर- x" नामक शाखा को अपनी मास्टर शाखा में मर्ज करना चाहते हैं

git request-pull master origin feature-x

आपको क्या होगा (बिना कुछ किए) का सारांश दिखाएगा:

The following changes since commit fc01dde318:
    Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
    http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
    Adding some layout
    Refactoring
ioserver.js            |   8 +++---
package.json           |   7 +++++-
server.js              |   4 +--
layout/ldkdsd.js       | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js

यदि आप -pपैरामीटर जोड़ते हैं , तो आपको पूर्ण पैच पाठ भी मिलेगा, ठीक उसी तरह जैसे यदि आप हर परिवर्तित फ़ाइल पर एक git diff कर रहे थे।


3
आप कमांड-लाइन विकल्पों में क्या masterऔर क्या जोड़कर इसे थोड़ा स्पष्ट कर सकते हैं origin, और क्या होगा यदि मैं एक स्थानीय उदाहरण के लिए हूं branch1और request-pullएक स्थानीय सुविधा शाखा पर करना चाहता हूं branch2? क्या मुझे अभी भी ज़रूरत है origin? बेशक, कोई भी हमेशा प्रलेखन पढ़ सकता है।
इला .२ Jul२

अफसोस की बात है कि यह कमांड केवल तभी काम करता है जब Rev # 2 एक शाखा का नाम है, यह हैश के लिए काम नहीं करता है: /
Jared Grubb

20

मुझे आश्चर्य है कि किसी ने भी पैच का उपयोग करने का सुझाव नहीं दिया है।

आप से किसी मर्ज का परीक्षण करना चाहते कहो your_branchमें master(मैं तुम्हें है संभालने हूँ masterकी जाँच):

$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch

यह ट्रिक काम आना चाहिए।

अगर आपको त्रुटियाँ मिलती हैं

error: patch failed: test.txt:1
error: test.txt: patch does not apply

इसका मतलब है कि पैच सफल नहीं था और एक मर्ज संघर्ष का उत्पादन करेगा। कोई आउटपुट का मतलब पैच साफ नहीं है और आप आसानी से शाखा को मर्ज कर पाएंगे


ध्यान दें कि यह वास्तव में आपके काम करने वाले पेड़ को नहीं बदलेगा (बेशक पैच फ़ाइल बनाने से, लेकिन आप बाद में इसे सुरक्षित रूप से हटा सकते हैं)। Git-apply प्रलेखन से:

--check
    Instead of applying the patch, see if the patch is applicable to the
    current working tree and/or the index file and detects errors. Turns
    off "apply".

किसी ऐसे व्यक्ति पर ध्यान दें, जो मुझसे अधिक समझदार / अनुभवी है: कृपया मुझे बताएं कि क्या मैं यहां गलत हूं और यह विधि एक नियमित मर्ज की तुलना में अलग व्यवहार दिखाती है। यह अजीब लगता है कि 8+ वर्षों में इस सवाल का कोई अस्तित्व नहीं है कि यह स्पष्ट रूप से स्पष्ट समाधान का सुझाव देगा।


यह पद्धति इस प्रश्न के लिए स्वीकृत उत्तर है और टिप्पणियों में कुछ कैविएट हैं जैसे "git 'पुनरावर्ती' मर्ज रणनीति" का उपयोग करने में सक्षम नहीं था और "पैच फ़ाइल नई फ़ाइलों के लिए त्रुटि देता है"। नहीं तो बहुत अच्छा लगता है।
नीनो

1
एक अस्थायी पैच फ़ाइल बनाए बिना छोटा तरीका git diff master your_branch | git apply --check:।
ks1322

9

यह दिलचस्प हो सकता है: प्रलेखन से:

यदि आपने एक मर्ज की कोशिश की जिसके परिणामस्वरूप जटिल संघर्ष हुआ और वह शुरू करना चाहता है, तो आप git मर्ज --abort से पुनर्प्राप्त कर सकते हैं ।

लेकिन आप इसे भोला (लेकिन धीमा) तरीके से भी कर सकते हैं:

rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)

(ध्यान दें: यह सिर्फ क्लोनिंग / tmp से काम नहीं करेगा, आपको एक कॉपी की आवश्यकता होगी, ताकि यह सुनिश्चित किया जा सके कि अनपेक्षित परिवर्तन संघर्ष नहीं करेंगे)।


2
यदि आप सभी की जरूरत है एक हथौड़ा है ... :) +1
kaiser

स्वच्छ प्रति के साथ प्राप्त किया जा सकता cp -r repository/.git /tmp/repository/.git, cd /tmp/repository, git reset --hard, git add --all, git reset --hard(अच्छा उपाय के लिए), git status(जांच करने के लिए है कि यह साफ है)।
ADTC

8

मुझे पता है कि यह एक पुराना प्रश्न है, लेकिन यह Google खोज में प्रदर्शित होने वाला पहला है।

विलय के समय Git ने एक --ff-only विकल्प पेश किया।

प्रेषक: http://git-scm.com/docs/git-merge


केवल---ff

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

ऐसा करने से मर्ज और तेज़-फ़ॉरवर्ड करने का प्रयास किया जाएगा, और यदि यह इसे रद्द नहीं करता है और आपको संकेत देता है कि फ़ॉरवर्ड-फ़ॉरवर्ड नहीं किया जा सकता है, लेकिन आपकी कार्यशील शाखा को छोड़ देता है। यदि यह तेजी से आगे बढ़ सकता है, तो यह आपकी कार्यशील शाखा पर मर्ज का प्रदर्शन करेगा। यह विकल्प भी उपलब्ध है git pull। इस प्रकार, आप निम्न कार्य कर सकते हैं:

git pull --ff-only origin branchA #See if you can pull down and merge branchA

git merge --ff-only branchA branchB #See if you can merge branchA into branchB

1
यह मर्ज तब होगा जब इसे तेजी से आगे बढ़ाया जा सकता है जो कि मूल प्रश्न में मैं नहीं चाहता था। मुझे लगता है कि स्वीकृत उत्तर में दूसरा आधा हिस्सा है जो इसे ठीक करता है।
ओट्टो

हालांकि, फैंसी git इस तरह की चीज के लिए मेरे पास मौजूद जरूरत को पूरा करता है।
ओट्टो

2
यह वास्तव में एक ही नहीं है। गैर-शून्य स्थिति के साथ बाहर निकलना क्योंकि मर्ज को हल नहीं किया जा सकता क्योंकि तेजी से आगे बढ़ने का मतलब यह नहीं है कि संघर्ष हैं । इसका मतलब सिर्फ यह है कि इतिहास ने मोड़ दिया है और एक मर्ज कमिट जरूरी है।
ADTC

7

मैं यह देखने के लिए गिट लॉग का उपयोग करता हूं कि मास्टर शाखा से एक सुविधा शाखा पर क्या बदल गया है

git log does_this_branch..contain_this_branch_changes

उदाहरण के लिए - यह देखने के लिए कि एक सुविधा शाखा में क्या हैं जो मास्टर में विलय नहीं हुए हैं:

git log master..feature_branch

3

यदि आप B से A तक आगे बढ़ना चाहते हैं, तो आपको यह सुनिश्चित करना होगा कि git लॉग B..A आपको कुछ नहीं दिखाता है, अर्थात A के पास ऐसा कुछ भी नहीं है जो B के पास नहीं है। लेकिन यहां तक ​​कि अगर B..A में कुछ है, तो आप अभी भी संघर्षों के बिना विलय करने में सक्षम हो सकते हैं, इसलिए उपरोक्त दो चीजें दिखाता है: कि एक फास्ट-फॉरवर्ड होगा, और इस तरह आपको एक संघर्ष नहीं मिलेगा।


2

मेरा समाधान पीछे की ओर विलय करना है।

अपनी शाखा को दूरस्थ "लक्ष्य" शाखा में विलय करने के बजाय, उस शाखा को आप में मिला दें।

git checkout my-branch
git merge origin/target-branch

आप देखेंगे कि क्या कोई संघर्ष है और उन्हें हल करने के तरीके के बारे में योजना बना सकते हैं।

उसके बाद आप या तो गिट के माध्यम से मर्ज को समाप्त कर सकते हैं merge --abort, या (अगर कोई संघर्ष नहीं हुआ और मर्ज हो गया है) पिछले कमिट के माध्यम से वापस रोल करेंgit reset --hard HEAD~1


-2

अपनी कार्यशील प्रतिलिपि की एक अस्थायी प्रतिलिपि बनाएँ, फिर उस में विलय करें और दोनों को अलग करें।

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