git - समझ - स्टेप्स ऑफ़ मेल मर्ज




आप गिट-मर्ज के साथ चुनिंदा फाइलों को कैसे मर्ज करते हैं? (15)

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

मेरा उपयोग मामला चुनिंदा रूप से किसी और की जिथब शाखा से अपने आप में परिवर्तन खींचना चाहता था। यदि आपके पास पहले से ही स्थानीय शाखाएं हैं, तो आपको केवल चरण 2 और 5-7 करने की आवश्यकता है।

  1. उन परिवर्तनों के साथ एक स्थानीय शाखा बनाएं (यदि नहीं बनाई गई) जिसमें आप शामिल करना चाहते हैं।

    $ git branch mybranch <base branch>

  2. इसमें स्विच करें।

    $ git checkout mybranch

  3. दूसरे व्यक्ति के खाते से इच्छित परिवर्तनों को नीचे खींचें। यदि आप पहले से ही नहीं हैं तो आप उन्हें रिमोट के रूप में जोड़ना चाहेंगे।

    $ git remote add repos-w-changes <git url>

  4. अपनी शाखा से सबकुछ नीचे खींचो।

    $ git pull repos-w-changes branch-i-want

  5. यह देखने के लिए प्रतिबद्ध लॉग देखें कि आप कौन से परिवर्तन चाहते हैं:

    $ git log

  6. उस शाखा में वापस स्विच करें जिसमें आप परिवर्तनों को खींचना चाहते हैं।

    $ git checkout originalbranch

  7. चेरी हैश के साथ, एक-एक करके, अपनी प्रतिबद्धता चुनें।

    $ git cherry-pick -x hash-of-commit

हैट टिप: http://www.sourcemage.org/Git_Guide

मैं एक नई परियोजना पर गिट का उपयोग कर रहा हूं जिसमें दो समानांतर हैं - लेकिन वर्तमान में प्रयोगात्मक - विकास शाखाएं:

  • master : मौजूदा कोडबेस के साथ-साथ कुछ मोड जिन्हें मैं आम तौर पर सुनिश्चित करता हूं
  • exp1 : प्रयोगात्मक शाखा # 1
  • exp2 2: प्रयोगात्मक शाखा # 2

exp1 और exp2 दो बहुत ही अलग वास्तुकला दृष्टिकोण का प्रतिनिधित्व करते हैं। जब तक मैं आगे नहीं जाता, मुझे यह जानने का कोई तरीका नहीं है कि कौन सा (यदि कोई हो) काम करेगा। जैसे-जैसे मैं एक शाखा में प्रगति करता हूं, कभी-कभी मेरे पास ऐसे संपादन होते हैं जो अन्य शाखा में उपयोगी होंगे और केवल उनको विलय करना चाहते हैं।

चुनिंदा फाइलों को चुनिंदा फाइलों को एक विकास शाखा से दूसरे में पीछे छोड़ने के लिए सबसे अच्छा तरीका क्या है?

दृष्टिकोण मैंने सोचा है:

  1. git merge --no-commit नो git merge --no-commit बड़ी संख्या में संपादन के मैन्युअल अस्थिरता के बाद जो मैं शाखाओं के बीच आम नहीं बनाना चाहता हूं।

  2. अन्य फ़ाइलों में जाने के लिए git checkout बाद git checkout बाद सामान्य फ़ाइलों की मैन्युअल प्रतिलिपि बनाना और फिर कार्यशील पेड़ में अस्थायी निर्देशिका से अधिक मैन्युअल प्रतिलिपि बनाना।

  3. उपरोक्त पर एक बदलाव। अब के लिए exp शाखाएं छोड़ दें और प्रयोग के लिए दो अतिरिक्त स्थानीय भंडारों का उपयोग करें। यह फ़ाइलों की मैन्युअल प्रतिलिपि को और अधिक सरल बनाता है।

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


आप वर्तमान सूचकांक में दिए गए रिमोट पेड़ को पढ़ने या मर्ज करने के लिए read-tree का उपयोग कर सकते हैं, उदाहरण के लिए:

git remote add foo [email protected]/foo.git
git fetch foo
git read-tree --prefix=my-folder/ -u foo/master:trunk/their-folder

विलय करने के लिए, इसके बजाय -m उपयोग करें।

यह भी देखें: मैं गिट में एक उप निर्देशिका कैसे विलय करूं?


चुनिंदा रूप से एक शाखा से दूसरी शाखा में फ़ाइलों को मर्ज करने के लिए, चलाएं

git merge --no-ff --no-commit branchX

जहां branchX वह शाखा है जिसे आप वर्तमान शाखा में विलय करना चाहते हैं।

- --no-commit विकल्प उन फ़ाइलों को --no-commit करेगा जो गिट द्वारा वास्तव में उन्हें किए बिना विलय कर दिए गए हैं। यह आपको मर्ज किए गए फ़ाइलों को संशोधित करने का अवसर देगा, हालांकि आप उन्हें स्वयं बनाना चाहते हैं।

फाइलों को मर्ज करना चाहते हैं, इस पर निर्भर करते हुए, चार मामले हैं:

1) आप एक असली विलय चाहते हैं।

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

2) ऐसी कुछ फाइलें हैं जिन्हें आप मर्ज करना नहीं चाहते हैं।

उदाहरण के लिए, आप वर्तमान शाखा में संस्करण को बनाए रखना चाहते हैं और जिस शाखा से आप विलय कर रहे हैं उस संस्करण में संस्करण को अनदेखा करना चाहते हैं।

वर्तमान शाखा में संस्करण का चयन करने के लिए, चलाएं:

git checkout HEAD file1

यह वर्तमान शाखा में फ़ाइल 1 का संस्करण पुनर्प्राप्त करेगा और फ़ाइल 1 को गीट द्वारा स्वचालित रूप से ओवरराइट करेगा।

3) यदि आप ब्रांचएक्स में संस्करण चाहते हैं (और एक वास्तविक विलय नहीं)।

चलाएँ:

git checkout branchX file1

यह branchX 1 में branchX 1 का संस्करण पुनर्प्राप्त करेगा और गिट द्वारा branchX ऑटो-विलय को ओवरराइट करेगा।

4) अंतिम मामला यह है कि यदि आप file1 1 में केवल विशिष्ट विलय चुनना चाहते हैं।

इस मामले में, आप संशोधित file1 सीधे संपादित कर सकते हैं, जो भी आप file1 के संस्करण को बनना चाहते हैं उसे अपडेट करें, और फिर प्रतिबद्ध करें।

यदि गिट स्वचालित रूप से फ़ाइल को मर्ज नहीं कर सकता है, तो यह फ़ाइल को " अनमोल " के रूप में रिपोर्ट करेगा और एक प्रतिलिपि तैयार करेगा जहां आपको मैन्युअल रूप से संघर्षों को हल करने की आवश्यकता होगी।


उदाहरण के साथ आगे बताने के लिए, branchX कि आप शाखा शाखा को वर्तमान शाखा में विलय करना चाहते हैं:

git merge --no-ff --no-commit branchX

संशोधित फ़ाइलों की स्थिति देखने के लिए फिर आप git status कमांड चलाते हैं।

उदाहरण के लिए:

git status

# On branch master
# Changes to be committed:
#
#       modified:   file1
#       modified:   file2
#       modified:   file3
# Unmerged paths:
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#       both modified:      file4
#

जहां फ़ाइल 1, file2 , और file3 फाइल गिट सफलतापूर्वक स्वतः विलय हो गया है।

इसका अर्थ यह है कि उन तीनों फ़ाइलों के लिए master और branchX में परिवर्तन किसी भी संघर्ष के बिना संयुक्त किए गए हैं।

आप निरीक्षण कर सकते हैं कि git diff --cached चलाने के द्वारा विलय कैसे किया गया था;

git diff --cached file1
git diff --cached file2
git diff --cached file3

यदि आपको कुछ विलय अवांछित लगता है तो आप कर सकते हैं

  1. फ़ाइल को सीधे संपादित करें
  2. बचाना
  3. git commit

यदि आप file1 को मर्ज नहीं करना चाहते हैं और वर्तमान शाखा में संस्करण को बनाए रखना चाहते हैं

रन

git checkout HEAD file1

यदि आप branchX को मर्ज नहीं करना चाहते हैं और केवल branchX को branchX में branchX

रन

git checkout branchX file2

अगर आप file3 को स्वचालित रूप से विलय करना चाहते हैं, तो कुछ भी न करें।

इस बिंदु पर गिट पहले से ही विलय कर चुका है।


उपरोक्त file4 गिट द्वारा एक असफल विलय है। इसका मतलब है कि एक ही पंक्ति पर होने वाली दोनों शाखाओं में बदलाव हैं। यह वह जगह है जहां आपको संघर्षों को मैन्युअल रूप से हल करने की आवश्यकता होगी। आप उस फ़ाइल में संस्करण के लिए सीधे फ़ाइल को संपादित करके या चेकआउट कमांड चलाकर विलय को त्याग सकते हैं, जिसे आप file4 बनना चाहते हैं।


अंत में, git commit करने के लिए मत भूलना।


जब दो शाखाओं के वर्तमान कामों के बीच केवल कुछ फाइलें बदल गई हैं, तो मैं अलग-अलग फ़ाइलों के माध्यम से परिवर्तनों को मैन्युअल रूप से विलय करता हूं।

git difftoll <branch-1>..<branch-2>


जैसा कि ऊपर बताया गया है, मेरे पास वही समस्या थी। लेकिन मैंने जवाब देने में jasonrudolph.com/blog/2009/02/25/… स्पष्ट पाया।

उपर्युक्त लिंक से कमांड:

#You are in the branch you want to merge to
git checkout <branch_you_want_to_merge_from> <file_paths...>

फ़ाइल द्वारा चुनिंदा विलय / करने के लिए एक सरल दृष्टिकोण:

git checkout dstBranch git merge srcBranch // make changes, including resolving conflicts to single files git add singleFile1 singleFile2 git commit -m "message specific to a few files" git reset --hard # blow away uncommitted changes


मुझे उपर्युक्त दृष्टिकोण पसंद नहीं हैं। चेरी-पिक का उपयोग करना एक ही बदलाव लेने के लिए बहुत अच्छा है, लेकिन यदि आप कुछ बुरे लोगों को छोड़कर सभी बदलावों को लाने के लिए चाहते हैं तो यह दर्द होता है। मेरा दृष्टिकोण यहाँ है।

कोई --interactive तर्क नहीं है --interactive आप गिट मर्ज करने के लिए पास कर सकते हैं।

यहां विकल्प है:

आपके पास शाखा 'फीचर' में कुछ बदलाव हैं और आप कुछ लाने के लिए नहीं चाहते हैं, लेकिन उन सभी को 'मास्टर' पर एक बेकार तरीके से नहीं लेना चाहते हैं (यानी आप चेरी चुनना और प्रत्येक को प्रतिबद्ध नहीं करना चाहते हैं)

git checkout feature
git checkout -b temp
git rebase -i master

# Above will drop you in an editor and pick the changes you want ala:
pick 7266df7 First change
pick 1b3f7df Another change
pick 5bbf56f Last change

# Rebase b44c147..5bbf56f onto b44c147
#
# Commands:
# pick = use commit
# edit = use commit, but stop for amending
# squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

git checkout master
git pull . temp
git branch -d temp

तो बस एक शेल स्क्रिप्ट में लपेटें, मास्टर को $ में बदलें और सुविधा को $ में बदलें और आप जाने के लिए अच्छे हैं:

#! /bin/bash
# git-interactive-merge
from=$1
to=$2
git checkout $from
git checkout -b ${from}_tmp
git rebase -i $to
# Above will drop you in an editor and pick the changes you want
git checkout $to
git pull . ${from}_tmp
git branch -d ${from}_tmp

मुझे पता है कि मैं थोड़ा देर हो चुकी हूं लेकिन चुनिंदा फाइलों को विलय करने के लिए यह मेरा वर्कफ़्लो है।

#make a new branch ( this will be temporary)
git checkout -b newbranch
# grab the changes 
git merge --no-commit  featurebranch
# unstage those changes
git reset HEAD
(you can now see the files from the merge are unstaged)
# now you can chose which files are to be merged.
git add -p
# remember to "git add" any new files you wish to keep
git commit

मैं एक करूंगा

git diff commit1..commit2 filepattern | गिट-लागू - इंडेक्स और गिट प्रतिबद्ध

इस तरह आप शाखा से फ़ाइलपटल के लिए काम की सीमा को सीमित कर सकते हैं।

से चोरी: http://www.gelato.unsw.edu.au/archives/git/0701/37964.html


मैंने jasonrudolph.com/blog/2009/02/25/… को सबसे सरल जवाब रखने के लिए पाया। केवल करो:

$ #git checkout <branch from which you want files> <file paths>

उदाहरण:

$ #pulling .gitignore file from branchB into current branch
$ git checkout branchB .gitignore

अधिक जानकारी के लिए पोस्ट देखें।


यह वही नहीं है जो आप खोज रहे थे, लेकिन यह मेरे लिए उपयोगी था:

git checkout -p <branch> -- <paths> ...

यह कुछ उत्तरों का मिश्रण है।


यहां बताया गया है कि आप Myclass.java फ़ाइल को master शाखा में Myclass.java साथ Myclass.java 1 शाखा में कैसे बदल सकते हैं। यह तब भी काम करेगा जब Myclass.java master पर मौजूद नहीं है।

git checkout master
git checkout feature1 Myclass.java

ध्यान दें कि यह ओवरराइट होगा - मर्ज न करें - और मास्टर शाखा में स्थानीय परिवर्तनों को अनदेखा करें।


व्यक्तिगत रूप से एक शाखा से काम करने के लिए आप cherry-pick कमांड का उपयोग करते हैं।

यदि आप जो परिवर्तन चाहते हैं वह अलग-अलग काम नहीं करता है, तो व्यक्तिगत प्रतिबद्धताओं में प्रतिबद्धता को विभाजित करने के लिए यहां दिखाए गए तरीके का उपयोग करें। असल में बोलते हुए, आप संपादित करने के लिए मूल प्रतिबद्धता प्राप्त करने के लिए git rebase -i का उपयोग करते हैं, फिर परिवर्तनों को चुनिंदा रूप से वापस करने के लिए git reset HEAD^ को git reset HEAD^ करें, फिर इतिहास में एक नई प्रतिबद्धता के रूप में उस बिट को प्रतिबद्ध git commit लिए प्रतिबद्ध करें।

रेड हैट मैगज़ीन में यहां एक और अच्छी विधि है , जहां वे git add --patch या संभवतः git add --interactive जो आपको एक हंक के कुछ हिस्सों को जोड़ने की अनुमति देता है, अगर आप अलग-अलग बदलावों को अलग-अलग फ़ाइल में विभाजित करना चाहते हैं (खोज उस पृष्ठ में "विभाजन" के लिए)।

परिवर्तनों को विभाजित करने के बाद, अब आप केवल वही चुन सकते हैं जिन्हें आप चाहते हैं।


सबसे आसान तरीका है कि अपने रेपो को उस शाखा में सेट करना है जिसे आप फिर से चलाने के साथ विलय करना चाहते हैं,

git checkout [branch with file] [path to file you would like to merge]

यदि आप भागते हैं

git status

आप पहले से ही बनाई गई फाइल देखेंगे ...

तो भागो

git commit -m "Merge changes on '[branch]' to [file]"

सरल।


हालांकि इनमें से कुछ उत्तर बहुत अच्छे हैं, मुझे लगता है कि किसी ने वास्तव में ओपी की मूल बाधा का उत्तर नहीं दिया: विशेष शाखाओं से विशेष फाइलों का चयन करना। यह समाधान ऐसा करता है, लेकिन कई फाइलें होने पर थकाऊ हो सकती हैं।

exp1 कि आपके पास master , exp1 और exp2 शाखाएं हैं। आप प्रत्येक प्रयोगात्मक शाखाओं से मास्टर में एक फ़ाइल को मर्ज करना चाहते हैं। मैं ऐसा कुछ करूंगा:

git checkout master
git checkout exp1 path/to/file_a
git checkout exp2 path/to/file_b

# save these files as a stash
git stash
# merge stash with master
git merge stash

यह आपको इच्छित फ़ाइलों में से प्रत्येक के लिए फ़ाइल में अंतर देगा। और कुछ नहीं। कुछ भी कम नहीं। यह उपयोगी है कि आपके संस्करण में मूल रूप से अलग-अलग फ़ाइल परिवर्तन हैं - मेरे मामले में, रेल 2 से रेल 3 तक एक ऐप बदलना।

संपादित करें : यह फ़ाइलों को मर्ज करेगा, लेकिन एक स्मार्ट विलय करता है। मैं यह समझने में सक्षम नहीं था कि फाइल को अलग-अलग जानकारी प्राप्त करने के लिए इस विधि का उपयोग कैसे किया जाए (शायद यह अभी भी चरम मतभेदों के लिए होगा। व्हाइट्स स्पेस जैसी परेशान छोटी चीजें तब तक विलय हो जाती हैं जब तक आप -s recursive -X ignore-all-space विकल्प)







git-cherry-pick