क्या यह एक अन्य गिट रिपॉजिटरी से कमिटमेंट लेने के लिए संभव है?


724

मैं एक git रिपॉजिटरी के साथ काम कर रहा हूं जिसे किसी अन्य git रिपॉजिटरी से एक कमिट की जरूरत है जो पहले कुछ भी नहीं जानता है।

आमतौर पर मैं HEAD@{x}रिफ्लॉग में चेरी-पिक का उपयोग कर सकता हूं , लेकिन क्योंकि यह .gitइस रिफ्लॉग एंट्री (अलग-अलग भौतिक निर्देशिका) के बारे में कुछ नहीं जानता, तो मैं इसे कैसे चुन सकता हूं, या मैं कर सकता हूं?

मैं उपयोग कर रहा हूं git-svn। मेरी पहली शाखा उपयोग कर रहा है git-svnकी trunkएक सबवर्सन रेपो की, और अगले शाखा उपयोग कर रहा है git-svnएक सबवर्सन शाखा पर।


2
यही कारण है कि बेन ली ने इस सवाल पर एक बाउंटी खोलने के लिए कहा: "मैं सही जवाब के लिए इनाम देने जा रहा हूं, बल्कि स्वीकृत जवाब। मुझे ऐसा करने के लिए बस 24 घंटे इंतजार करना होगा।" हालाँकि, मुझे समझ में नहीं आता है कि इनमें से कौन सा "सही उत्तर" माना जाता है, और क्यों स्वीकृत उत्तर "सही" नहीं है।

1
यह स्पष्ट नहीं है कि समस्या की प्रकृति क्या है। ये अलग-अलग रिपोज कैसे संबंधित हैं, यदि सभी पर क्या एक दूसरे का कांटा है? या वे वास्तव में दो पूरी तरह से अलग और असंबंधित परियोजनाएं हैं?

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

जवाबों:


554

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

उसके जैसा:

git remote add other https://example.link/repository.git
git fetch other

अब आपके पास बस करने के लिए सारी जानकारी है git cherry-pick

यहाँ रीमोट के साथ काम करने के बारे में अधिक जानकारी: https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes


1
अगर मैं git-svn का उपयोग कर रहा हूँ तो क्या होगा? मेरी पहली शाखा ट्रंक के git-svn का उपयोग कर रही है और अगले एक शाखा पर git-svn का उपयोग कर रही है (त्वरित उत्तर के लिए धन्यवाद)
gitcoder182

1
जब आप पहली बार तोड़फोड़ रिपॉजिटरी को क्लोन करते हैं , तो सुनिश्चित करें कि आप पूरे रिपॉजिटरी को क्लोन करते हैं , न कि केवल ट्रंक। यह भी सुनिश्चित करें कि --stdlayoutयदि आप सबवर्सन में मानक ट्रंक / शाखाओं / टैग लेआउट का उपयोग कर रहे हैं तो आप git-svn के विकल्प का उपयोग करें। फिर तोड़फोड़ शाखा एक मात्र दूरस्थ गिट शाखा होगी।
विल्हेमटेल

33
यदि आप Github का उपयोग कर रहे हैं, तो आप पैच को कमिट कर सकते हैं। कमिट कर सकते हैं URL, और फिर इसे लागू कर सकते हैं git am < d821j8djd2dj812.patch। GH के बाहर, इसी तरह की अवधारणाओं को नीचे दिए गए वैकल्पिक उत्तर में संदर्भित किया जा सकता है।
मूलांक

2
@ श्रद्धानंद जो नीचे उत्तर देता है वह "वैकल्पिक" है? कृपया इसे लिंक करें।

7
एक और रेपो से चेरी लेने के लिए विस्तृत कदम: coderwall.com/p/sgpksw/git-cherry-pick-from-another-repository
टी। किम गुयेन

854

उत्तर, जैसा कि दिया गया है, फॉर्मेट-पैच का उपयोग करना है, लेकिन चूंकि सवाल यह था कि किसी अन्य फ़ोल्डर से चेरी-पिक कैसे किया जाए, यहाँ कोड का एक टुकड़ा है:

$ git --git-dir=../<some_other_repo>/.git \
format-patch -k -1 --stdout <commit SHA> | \
git am -3 -k

( @ मांग मा से स्पष्टीकरण )

git format-patchआदेश से एक पैच बनाता some_other_repoहै इसकी SHA द्वारा निर्दिष्ट प्रतिबद्ध ( -1एक एकल के लिए अकेले प्रतिबद्ध)। इस पैच को पाइप किया जाता है git am, जो पैच को स्थानीय रूप से लागू करता है ( -3इसका मतलब है कि यदि पैच साफ तरीके से लागू नहीं होता है तो तीन-तरफा मर्ज करने की कोशिश कर रहा है)। आशा है कि बताते हैं।


18
यह मौके पर है, लेकिन यह बहुत अच्छा होगा अगर कोई भी इस पर विस्तार कर सकता है - वास्तव में क्या चल रहा है (विशेष रूप से उन झंडे के साथ) का एक टूटना अविश्वसनीय रूप से उपयोगी होगा।
निक एफ

45
@NickF, git format-patchकमांड some_other_repoअपने SHA द्वारा निर्दिष्ट एक कमिट से एक पैच बनाता है ( -1अकेले एक सिंगल कमिट के लिए)। इस पैच को पाइप किया जाता है git am, जो स्थानीय रूप से पैच को लागू करता है ( -3यदि पैच साफ-साफ लागू नहीं होता है, तो तीन-तरफा मर्ज करने की कोशिश करता है)। आशा है कि बताते हैं।
कॉन्ग मा

3
त्रुटि: पैच विफल: somefile.cs: 85 त्रुटि: somefile.cs: पैच लागू नहीं होता है क्या आपने अपने पैच को संपादित किया? यह अपने सूचकांक में दर्ज किए गए बूँद पर लागू नहीं होता है। तीन तरफा मर्ज करने के लिए वापस नहीं गिर सकता। पैच 0001 जोड़ा GUI भागों में विफल रहा। जो पैच फेल हुआ उसकी कॉपी इसमें मिलती है: <some_other_repo> /। Git / rebase-apply / पैच जब आपने इस समस्या को हल कर लिया है, तो "git am --continue" चलाएं। यदि आप इस पैच को छोड़ना पसंद करते हैं, तो इसके बजाय "git am --skip" चलाएं। मूल शाखा को पुनर्स्थापित करने और पैचिंग को रोकने के लिए, "git am --abort" चलाएं।
टॉम

8
@Tom का उपयोग करके देखें --ignore-whitespace। पूर्ण आदेश: git --git-dir=../<some_other_repo>/.git format-patch -k -1 --stdout <commit SHA> | git am -3 -k --ignore-whitespace
जेक ग्राहम अर्नोल्ड

7
@BoomShadow क्योंकि यह आसान तरीका है। रिमोट जोड़ना और लाना अन्य रेपो के सभी परिवर्तनों को लाता है। यह कमांड लाइन एक बार की कार्रवाई है।
जोनाथन रेनहार्ट 15

151

यहाँ दूरस्थ-गर्भ-मर्ज का एक उदाहरण है।

cd /home/you/projectA
git remote add projectB /home/you/projectB
git fetch projectB

तब आप कर सकते हो:

git cherry-pick <first_commit>..<last_commit>

या आप पूरी शाखा का विलय भी कर सकते हैं

git merge projectB/master

54
git merge projectB/master बहुत, बहुत गलत है , क्योंकि आप एक ही प्रतिबद्ध (जैसे चेरी-पिक) से परिवर्तनों को लागू नहीं कर रहे हैं, आप वास्तव में उन सभी परिवर्तनों मेंविलय कर रहेprojectB/masterहैं जो आपकी अपनीmasterशाखामें निहित नहीं हैं।

4
यह मेरी धारणा थी कि यह मूल पोस्टर का इरादा था। अन्यथा, हां, यह उनके लिए सही विकल्प नहीं है।
ब्रायन

5
यह शानदार ढंग से काम करता है जब दो रिपॉजिटरी संबंधित हैं।
रॉनी एगर-विक

1
मैंने एक गिट रिपॉजिटरी (मूल रेपो को तोड़े बिना "चारों ओर" बजाने के लिए) से एक प्रति बनाई है और इसे अपने स्रोत के साथ अद्यतित रखने के लिए, ब्रायन का उत्तर ठीक वही है जिसकी मुझे आवश्यकता थी, इसलिए, कपकेक, मैं कहना है, यह "गलत" नहीं है, लेकिन एक और उपयोग मामला है। लेकिन संभावित आपदा को इंगित करना आपके लिए अच्छा है: D
ferrari2k

6
IMO को यह स्वीकृत समाधान होना चाहिए। इसके अलावा, यदि आप इसे से चेरी-पिकिंग करने के बाद रिमोट को हटाना चाहते हैं, तो उपयोग करें git remote rm projectBgit tag -d tag-nameरिमोट रेपो से प्राप्त किसी भी टैग को हटाने के लिए भी उपयोग करें। रिमोट कमिट अब आपके इतिहास में दिखाई नहीं देगा, और प्रूनिंग उन्हें अंततः भंडारण से हटा देगा।
ADTC

130

आप इसे कर सकते हैं, लेकिन इसके लिए दो चरणों की आवश्यकता होती है। ऐसे:

git fetch <remote-git-url> <branch> && git cherry-pick FETCH_HEAD

<remote-git-url>उस url या पथ से रिपॉजिटरी में बदलें जिसे आप चेरी-पिक चाहते हैं।

<branch>उस शाखा या टैग नाम से बदलें जिसे आप दूरस्थ रिपॉजिटरी से चेरी-पिक करना चाहते हैं।

आप FETCH_HEADशाखा से गिट SHA से बदल सकते हैं ।

अपडेट किया गया: @ pkalinow की प्रतिक्रिया के आधार पर संशोधित।


8
यह शाखा नाम के साथ काम करता है, लेकिन SHA के साथ नहीं। आप चाहते हैं चेरी लेने एक प्रतिबद्ध अपने हैश से दर्शाया जाता है, तब यह का उपयोग करें: git fetch <repo-url> <branch> && git cherry-pick <sha>
पल्किनो

धन्यवाद। यह वही था जो मुझे एक रिपॉजिटरी से दूसरे में कई कमिट्स सम्मिलित करने के लिए चाहिए था, जिसे मैंने इस उद्देश्य के लिए बनाया था।
wojciii

यह बिल्कुल वही था जो मुझे अलग-अलग ग्राहकों के लिए हमारे कोड के कई कस्टम कार्यान्वयन के साथ चाहिए था (जिनके पास अपने स्वयं के रिपॉजिटरी / कांटे हैं) हमें अपने आधार / ट्रंक में विशिष्ट कमिट प्राप्त करने के लिए एक तरीके की आवश्यकता थी। धन्यवाद!
18

यह रेपो के पार एक-शॉट चेरी पिक के लिए स्वीकृत उत्तर होना चाहिए। मैं इसका उपयोग हर समय करता हूं, जब पहले से ही स्थानीय रिपॉजिट के बीच उठा होता है, तो दूरस्थ URL तब सिर्फ एक स्थानीय फाइल सिस्टम पथ होता है।
एमी वैन गैससे

61

यहाँ एक दूरस्थ, लाने के लिए शाखाओं को जोड़ने के चरण हैं, और चेरी-कमिट करें

# Cloning our fork
$ git clone git@github.com:ifad/rest-client.git

# Adding (as "endel") the repo from we want to cherry-pick
$ git remote add endel git://github.com/endel/rest-client.git

# Fetch their branches
$ git fetch endel

# List their commits
$ git log endel/master

# Cherry-pick the commit we need
$ git cherry-pick 97fedac

स्रोत: https://coderwall.com/p/sgpksw


17

देखें कि Git के साथ पैच कैसे बनाया और लगाया जाए । (आपके प्रश्न के शब्दांकन से, मैंने माना कि यह अन्य रिपॉजिटरी पूरी तरह से अलग कोडबेस के लिए है। यदि यह समान कोड आधार के लिए रिपॉजिटरी है, तो आपको इसे @CharlesB द्वारा सुझाए गए रिमोट के रूप में जोड़ना चाहिए। यहां तक ​​कि यह दूसरे के लिए भी है। कोड आधार, मुझे लगता है कि आप अभी भी इसे रिमोट के रूप में जोड़ सकते हैं, लेकिन आप पूरी शाखा को अपने भंडार में नहीं लाना चाहते ...)


11

आप इसे निम्नानुसार एक पंक्ति में कर सकते हैं। आशा है कि आप git रिपॉजिटरी में हैं, जिसे चेरी द्वारा चुने गए बदलाव की आवश्यकता है और आपने सही शाखा की जाँच की है।

git fetch ssh://git@stash.mycompany.com:7999/repo_to_get_it_from.git branchToPickFrom && git cherry-pick 02a197e9533
# 

git fetch [ब्रांच URL] [ब्रांच से चेरी-पिक] और & git चेरी-पिक [कमिट आईडी]


1
चीयर्स, जरूरत नहीं थी ssh://हिस्सा है, केवल के लिएhttps://
सिंह

5

हाँ। दूरस्थ शाखा से रिपॉजिटरी और फिर चेरी-पिक प्राप्त करें।


1

मान लिया जाये कि Aरेपो आप करना चाहते है से चेरी लेने, और Bएक आप करना चाहते हैं चेरी लेने के लिए, आप जोड़ कर ऐसा कर सकते हैं </path/to/repo/A/>/.git/objectsकरने के लिए </path/to/repo/B>/.git/objects/info/alternatesalternatesयदि यह मौजूद नहीं है तो इस फाइल को बनाएं ।

यह रेपो बी को रेपो ए से सभी गिट वस्तुओं तक पहुंचाएगा, और आपके लिए चेरी-पिक काम करेगा।


0

मेरी स्थिति यह थी कि मेरे पास एक नंगे रेपो है जो टीम को धक्का देता है, और इसके ठीक बगल में बैठे हुए एक क्लोन। मेरे लिए सही ढंग से मेकफाइल काम में लाइनों का यह सेट:

git reset --hard
git remote update --prune
git pull --rebase --all
git cherry-pick -n remotes/origin/$(BRANCH)

नंगे रेपो के मास्टर को आज तक रखने से, हम नंगे रेपो के लिए प्रकाशित एक प्रस्तावित बदलाव को चुन पाने में सक्षम हैं। हमारे पास समेकित समीक्षा और परीक्षण के लिए बहु-स्तरीय चेरी को चुनने का एक अधिक जटिल तरीका भी है।

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


-n का मतलब गिट डॉक्स के अनुसार नो-कमिट है और मैं कमिट करने से पहले बदलाव को देखने के लिए बहुत महत्वपूर्ण बात करता हूं
कैनबक्स

0

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

# Directory from which to cherry-pick
GIT_DIR=...
# Pick changes only for this file
FILE_PATH=...
# Apply changes from this commit
FIST_COMMIT=master
# Apply changes until you reach this commit
LAST_COMMIT=...

for sha in $(git --git-dir=$GIT_DIR log --reverse --topo-order --format=%H $LAST_COMMIT_SHA..master -- $FILE_PATH ) ; do 
  git --git-dir=$GIT_DIR  format-patch -k -1 --stdout $sha -- $FILE_PATH | 
    git am -3 -k
done
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.