गिट के साथ सबसे हालिया प्रतिबद्ध (एस) को एक नई शाखा में स्थानांतरित करें


4981

मैं पिछले कई कमिट्स को स्थानांतरित करना चाहता हूं, जिन्हें मैंने एक नई शाखा में करने के लिए प्रतिबद्ध किया है और उन कमिट्स को बनाने से पहले मास्टर को वापस ले जाना चाहिए। दुर्भाग्य से, मेरा गिट-फू अभी तक मजबूत नहीं है, कोई मदद?

यानी मैं इससे कैसे जा सकता हूं

master A - B - C - D - E

इसके लिए?

newbranch     C - D - E
             /
master A - B 

114
नोट: मैंने यहां
बेंजोल

3
eddmann.com/posts/… यह एक काम करता है
सागर नलियापारा

6
क्या यहाँ टिप्पणियाँ शुद्ध थीं? मैं पूछता हूं क्योंकि इस प्रश्न के बारे में मेरी द्वैमासिक यात्रा के दौरान, मैं हमेशा उस टिप्पणी से स्क्रॉल करता हूं।
तेजस काले

जवाबों:


6446

किसी मौजूदा शाखा में जाना

यदि आप अपने कमिट को मौजूदा ब्रांच में ले जाना चाहते हैं , तो यह इस तरह दिखेगा:

git checkout existingbranch
git merge master         # Bring the commits here
git checkout master
git reset --keep HEAD~3  # Move master back by 3 commits.
git checkout existingbranch

--keepइसी तरह क्या करने के लिए - विकल्प किसी भी अप्रतिबद्ध परिवर्तन आप असंबंधित फ़ाइलें, या रोकता में हो सकता है कि अगर उन परिवर्तनों को ओवरराइट किया जा करने के लिए होता बरकरार रखता git checkoutहै। यदि यह रद्द करता है, तो git stashआपके परिवर्तन और पुन: प्रयास करें, या --hardपरिवर्तनों को खोने के लिए उपयोग करें (यहां तक ​​कि उन फ़ाइलों से भी जो कमिट के बीच नहीं बदले!)

नई शाखा में जाना

यह विधि पहले कमांड ( git branch newbranch) के साथ एक नई शाखा बनाकर काम करती है, लेकिन इसे स्विच करने के लिए नहीं। फिर हम वर्तमान शाखा (मास्टर) को वापस रोल करते हैं और काम जारी रखने के लिए नई शाखा पर स्विच करते हैं।

git branch newbranch      # Create a new branch, containing all current commits
git reset --keep HEAD~3   # Move master back by 3 commits (Make sure you know how many commits you need to go back)
git checkout newbranch    # Go to the new branch that still has the desired commits
# Warning: after this it's not safe to do a rebase in newbranch without extra care.

लेकिन यह सुनिश्चित करें कि कितने वापस जाने के लिए प्रतिबद्ध है। वैकल्पिक रूप से, इसके बजाय HEAD~3, आप बस कमिट का हैश प्रदान कर सकते हैं (या जैसा संदर्भ origin/master) आप वापस करना चाहते हैं उदाहरण के लिए:

git reset --keep a1b2c3d4

चेतावनी: Git संस्करण 2.0 के साथ और बाद में, यदि आप बाद git rebaseमें मूल ( master) शाखा पर नई शाखा , आप छूट के --no-fork-pointदौरान एक स्पष्ट विकल्प की आवश्यकता हो सकती है ताकि आप मास्टर शाखा से चले गए कमिट को खोने से बचा सकें। branch.autosetuprebase alwaysसेट होने से यह अधिक होने की संभावना है। देखें जॉन मेलर का जवाब जानकारी के लिए।


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

107
आश्चर्य है कि क्या आप इस काम को समझा सकते हैं। मेरे लिए आप एक नई शाखा बना रहे हैं, जिस पुरानी शाखा से आप अभी भी हैं, उस पर से 3 कमिट्स हटा दें, और फिर आपके द्वारा की गई शाखा की जाँच करें। तो नई शाखा में जादुई तरीके से दिखाए गए कमेंट्स को आप कैसे देखते हैं?
जोनाथन ड्यूमाइन

142
@ जोनाथन ड्यूमाइन: क्योंकि मैंने पुरानी ब्रांच से कमिट्स निकालने से पहले नई ब्रांच बनाई थी। वे अभी भी नई शाखा में हैं।
sykora

86
git में शाखाएं केवल मार्कर हैं जो इतिहास में शुरू होने की ओर इशारा करते हैं, कुछ भी क्लोन नहीं किया जाता है, बनाया या हटा दिया जाता है (मार्कर को छोड़कर)
knittl

218
यह भी नोट करें: अपनी कार्यशील प्रति में बिना परिवर्तन के साथ ऐसा न करें! यह सिर्फ मुझे! :(
एडम टटल

1038

उन लोगों के लिए जो यह काम कर रहे हैं (जैसा कि मैं पहले था):

आप C पर वापस जाना चाहते हैं, और D और E को नई शाखा में ले जाना चाहते हैं। यहाँ पहले जैसा दिखता है:

A-B-C-D-E (HEAD)
        ↑
      master

के बाद git branch newBranch:

    newBranch
        ↓
A-B-C-D-E (HEAD)
        ↑
      master

के बाद git reset --hard HEAD~2:

    newBranch
        ↓
A-B-C-D-E (HEAD)
    ↑
  master

चूंकि एक शाखा सिर्फ एक संकेतक है, मास्टर ने आखिरी प्रतिबद्ध की ओर इशारा किया। जब आप newBranch बनाते हैं , तो आपने अंतिम संकेत के लिए बस एक नया पॉइंटर बनाया होता है। तब git resetआपने मास्टर पॉइंटर को वापस ले जाकर दो कमिट का उपयोग किया। लेकिन चूंकि आपने newBranch को स्थानांतरित नहीं किया था , इसलिए यह अभी भी मूल रूप से किए गए वचन को इंगित करता है।


55
मुझे git push origin master --forceमुख्य रिपॉजिटरी में बदलाव दिखाने के लिए भी करने की जरूरत थी ।
द्युजनन

9
इस उत्तर के कारण कमिट्स खो जाता है: अगली बार जब आप git rebase3 कमिट्स को चुपचाप छोड़ देंगे newbranch। विवरण और सुरक्षित विकल्पों के लिए मेरा जवाब देखें ।
जॉन मेलोर

14
@ जॉन, यह बकवास है। यह जाने बिना कि आप क्या कर रहे हैं, यह जानने का कारण बनता है कि खो जाना है। यदि आप हार गए हैं, तो मुझे आपके लिए खेद है, लेकिन यह उत्तर आपके कमिट्स को नहीं खोता है। ध्यान दें कि origin/masterउपरोक्त आरेख में नहीं दिखाई देता है। अगर आपने ऊपर धकेल दिया origin/masterऔर फिर ऊपर बदलाव किए, तो यकीनन, चीजें मज़ेदार होंगी। लेकिन यह एक "डॉक्टर है, यह दर्द होता है जब मैं इस तरह की" समस्या करता हूं। और यह उस दायरे से बाहर है जो मूल प्रश्न पूछा गया था। मेरा सुझाव है कि आप इस एक को अपहृत करने के बजाय अपने परिदृश्य का पता लगाने के लिए अपना प्रश्न लिखें।
रयान लुंडी

1
@ जॉन, आपके जवाब में, आपने कहा "ऐसा मत करो! git branch -t newbranch"। वापस जाओ और फिर से जवाब पढ़ें। किसी ने ऐसा करने का सुझाव नहीं दिया।
रयान लुंडी

1
@Kyralessa, यकीन है, लेकिन अगर आप प्रश्न में आरेख को देखते हैं, तो यह स्पष्ट है कि वे newbranchअपनी मौजूदा masterशाखा से दूर रहना चाहते हैं । स्वीकृत उत्तर को निष्पादित करने के बाद, जब उपयोगकर्ता अंदर चलने के लिए हो जाता git rebaseहै newbranch, तो git उन्हें याद दिलाएगा कि वे अपस्ट्रीम शाखा को सेट करना भूल गए हैं, इसलिए वे git branch --set-upstream-to=masterतब चलेंगे git rebaseऔर समान समस्या होगी। वे git branch -t newbranchपहली जगह में भी उपयोग कर सकते हैं ।
जॉन मेलोर

454

सामान्य रूप में...

सिकोरा द्वारा उजागर विधि इस मामले में सबसे अच्छा विकल्प है। लेकिन कभी-कभी सबसे आसान नहीं होता है और यह एक सामान्य तरीका नहीं है। एक सामान्य विधि के लिए git चेरी-पिक का उपयोग करें :

ओपी क्या चाहता है, इसकी 2-चरणीय प्रक्रिया को प्राप्त करने के लिए:

चरण 1 - ध्यान दें कि आप जिस मास्टर से चाहते हैं, वह newbranch

निष्पादित

git checkout master
git log

(कहें 3) के हैश को नोट करें जो आप चाहते हैं newbranch। यहाँ मैं उपयोग करूँगा:
C प्रतिबद्ध: 9aa1233
D प्रतिबद्ध: 453ac3d
E प्रतिबद्ध:612ecb3

नोट: आप पहले सात वर्णों या पूरे प्रतिबद्ध हैश का उपयोग कर सकते हैं

चरण 2 - उन्हें रखो newbranch

git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233

या (Git 1.7.2+ पर, पर्वतमाला का उपयोग करें)

git checkout newbranch
git cherry-pick 612ecb3~1..9aa1233

git चेरी-पिक उन तीन कमिट्स को newbranch पर लागू करता है।


13
ओ पी ले जाने का प्रयास नहीं कर रहा था से मास्टर करने के लिए newbranch? यदि आप मास्टर पर बार-बार चेरी-पिक करते हैं, तो आप मास्टर ब्रांच में शामिल होंगे - यह कहते हुए कि यह पहले से ही था, वास्तव में। और यह वापस या तो शाखा प्रमुख के पास नहीं जाता है। बी या सूक्ष्म और शांत है जो मुझे नहीं मिल रहा है?
RaveTheTadpole

6
यह बहुत अच्छी तरह से काम करता है अगर आप गलती से गलत, गैर-मास्टर शाखा बनाते हैं, जब आपको एक नई सुविधा शाखा बनानी चाहिए थी।
julianc

5
कुछ स्थितियों में उपयोगी दृष्टिकोण के लिए +1। यह अच्छा है यदि आप केवल अपने स्वयं के कमिट (जो दूसरों के साथ प्रतिच्छेदित हैं) को एक नई शाखा में खींचना चाहते हैं।
टायलर वी।

7
इसका बेहतर जवाब है। इस तरह से आप किसी भी शाखा में आवागमन कर सकते हैं।
स्काईविंदर

8
क्या चेरी का आदेश महत्वपूर्ण है?
कोन साइक

328

ऐसा करने का एक और तरीका है, सिर्फ 2 कमांड का उपयोग करके। अपने वर्तमान कार्यशील पेड़ को भी बरकरार रखता है।

git checkout -b newbranch # switch to a new branch
git branch -f master HEAD~3 # make master point to some older commit

पुराने संस्करण - इससे पहले कि मैंने सीखाgit branch -f

git checkout -b newbranch # switch to a new branch
git push . +HEAD~3:master # make master point to some older commit 

जानने में सक्षम होने के pushलिए .एक अच्छी चाल है।


1
वर्तमान निर्देशिका। मुझे लगता है कि यह तभी काम करेगा जब आप शीर्ष निर्देशिका में होंगे।
अरगा

1
स्थानीय धक्का मुस्कराहट-उत्प्रेरण है, लेकिन प्रतिबिंब पर, यह git branch -fयहां कैसे अलग है?
jthill

2
@GerardSexton .वर्तमान निदेशक हैं। git REMOTES या GIT URL को पुश कर सकता है। path to local directoryसमर्थित URL URL सिंटैक्स है। में GIT URLS अनुभाग देखें git help clone
कमजोर

31
मुझे नहीं पता कि यह उच्च श्रेणीबद्ध क्यों नहीं है। मृत सरल, और बिना रीसेट के छोटे लेकिन संभावित खतरे के बिना - भार।
गॉडस्मिथ

4
@Godsmith मेरा अनुमान है कि लोग तीन साधारण आदेशों को दो और अधिक अस्पष्ट आज्ञाओं को पसंद करते हैं। इसके अलावा, शीर्ष मतदान के जवाबों को पहले प्रदर्शित किए जाने की प्रकृति से और अधिक बढ़ावा मिलता है।
JS_Riddler

321

अधिकांश पिछले उत्तर खतरनाक रूप से गलत हैं!

यह मत करो:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

अगली बार जब आप दौड़ेंगे git rebase(या git pull --rebase) उन 3 कमिट्स को चुपचाप छोड़ दिया जाएगा newbranch! (नीचे स्पष्टीकरण देखें)

इसके बजाय यह करें:

git reset --keep HEAD~3
git checkout -t -b newbranch
git cherry-pick ..HEAD@{2}
  • सबसे पहले यह 3 सबसे हाल के हिट ( --keepजैसा है --hard, लेकिन सुरक्षित है, के रूप में विफल रहता है के बजाय असम्पीडित परिवर्तन फेंक)।
  • तब यह बंद हो जाता है newbranch
  • फिर यह उन 3 को वापस चुनता है जो चेरी-पिक करता है newbranch। चूंकि वे अब किसी शाखा द्वारा संदर्भित नहीं हैं, इसलिए ऐसा होता है कि git के reflog का उपयोग करके : HEAD@{2}यह वह प्रतिबद्धता है HEADजिसका उपयोग 2 ऑपरेशनों से पहले करने के लिए किया गया था, अर्थात इससे पहले कि हमने 1. चेक आउट किया था newbranchऔर 2. git reset3 कमिट्स को छोड़ने के लिए उपयोग किया गया था।

चेतावनी: डिफ़ॉल्ट रूप से फिर से सक्षम किया जाता है, लेकिन यदि आपने इसे मैन्युअल रूप से अक्षम कर दिया है (जैसे कि "नंगे" गिट रिपॉजिटरी का उपयोग करके), तो आप चलने के बाद 3 कमिट्स वापस प्राप्त नहीं कर पाएंगे git reset --keep HEAD~3

एक विकल्प जो रिफ्लॉग पर निर्भर नहीं करता है वह है:

# newbranch will omit the 3 most recent commits.
git checkout -b newbranch HEAD~3
git branch --set-upstream-to=oldbranch
# Cherry-picks the extra commits from oldbranch.
git cherry-pick ..oldbranch
# Discards the 3 most recent commits from oldbranch.
git branch --force oldbranch oldbranch~3

(यदि आप चाहें तो आप लिख सकते हैं @{-1}- पहले से चेक की गई शाखा - के बजाय oldbranch)।


तकनीकी व्याख्या

git rebaseपहले उदाहरण के बाद 3 कमिट्स क्यों छोड़ेंगे? ऐसा इसलिए है क्योंकि git rebaseकोई भी तर्क --fork-pointडिफ़ॉल्ट रूप से विकल्प को सक्षम नहीं करता है, जो अपस्ट्रीम शाखा के बल-धक्का के खिलाफ मजबूत होने की कोशिश करने के लिए स्थानीय रिफ्लॉग का उपयोग करता है।

मान लीजिए कि आपने मूल / मास्टर को बंद कर दिया है, जब इसमें एम 1, एम 2, एम 3 शामिल है, तो तीन ने खुद को बनाया:

M1--M2--M3  <-- origin/master
         \
          T1--T2--T3  <-- topic

लेकिन तब कोई व्यक्ति M2 को हटाने के लिए बल-धक्का मूल / मास्टर द्वारा इतिहास को फिर से लिखता है:

M1--M3'  <-- origin/master
 \
  M2--M3--T1--T2--T3  <-- topic

अपने स्थानीय रिफ्लॉग का उपयोग करते हुए, git rebaseआप देख सकते हैं कि आपने मूल / मास्टर शाखा के पहले अवतार से कांटा था, और इसलिए कि एम 2 और एम 3 कमिट्स वास्तव में आपकी विषय शाखा का हिस्सा नहीं हैं। इसलिए यह यथोचित रूप से मानता है कि चूंकि M2 को अपस्ट्रीम शाखा से हटा दिया गया था, इसलिए अब आप अपनी विषय शाखा में या तो यह नहीं चाहते कि विषय शाखा में एक बार छूट हो:

M1--M3'  <-- origin/master
     \
      T1'--T2'--T3'  <-- topic (rebased)

यह व्यवहार समझ में आता है, और आम तौर पर रिबासिंग करते समय सही काम होता है।

तो यह कारण है कि निम्नलिखित आदेश विफल:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

ऐसा इसलिए है क्योंकि वे गलत स्थिति में शरण छोड़ देते हैं। Git newbranchएक संशोधन में अपस्ट्रीम शाखा को बंद करने के रूप में देखता है जिसमें 3 कमिट शामिल हैं, फिर reset --hardअपस्ट्रीम के इतिहास को कमिट्स को हटाने के लिए फिर से लिखता है, और इसलिए अगली बार जब आप git rebaseइसे चलाते हैं तो उन्हें किसी भी अन्य प्रतिबद्ध की तरह हटा देता है जो अपस्ट्रीम से हटा दिया गया है।

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

अधिक जानकारी के लिए, की परिभाषा को देखने --fork-pointमें Git रिबेस और Git मर्ज आधार डॉक्स।


14
यह उत्तर कहता है "ऐसा मत करो!" ऊपर कुछ ऐसा जो किसी ने करने का सुझाव नहीं दिया।
रयान लुंडी

3
अधिकांश लोग प्रकाशित इतिहास को फिर से नहीं लिखते हैं, विशेषकर पर master। तो नहीं, वे खतरनाक रूप से गलत नहीं हैं।
6

4
@Kyralessa, अगर आप सेट कर चुके हैं, तो आप इसका -tउल्लेख कर रहे हैं । यहां तक ​​कि अगर आप नहीं करते हैं, तो मैंने आपको पहले ही समझाया था कि अगर आप इन आदेशों को पूरा करने के बाद ट्रैकिंग की स्थापना करते हैं, तो वही समस्या होती है, जैसा कि ओपी की संभावना है कि वे अपना प्रश्न दें। git branchgit config --global branch.autosetuprebase always
जॉन मेलर

2
@RockLee, हाँ, ऐसी स्थितियों को ठीक करने का सामान्य तरीका एक सुरक्षित प्रारंभिक बिंदु से एक नई शाखा (newbranch2) बनाना है, फिर चेरी को उन सभी कमियों को चुनना है जिन्हें आप रखना चाहते हैं (badnewbranch से newbranch2 तक)। चेरी-पिकिंग कमिट्स को नया हैश देगा, जिससे आप newbranch2 को सुरक्षित रूप से रीबेस कर पाएंगे (और अब badnewbranch को हटा सकते हैं)।
जॉन मेलर

2
@Alf, आप गलत समझे: git rebase को उनके इतिहास को फिर से लिखने वाली अपस्ट्रीम के खिलाफ मजबूत होने के लिए डिज़ाइन किया गया है। दुर्भाग्य से, उस मजबूती के दुष्परिणाम सभी को प्रभावित करते हैं, भले ही वे और न ही उनके अपस्ट्रीम कभी इतिहास को फिर से लिखते हों।
जॉन मेलोर

150

गिट स्टैश का उपयोग करते हुए बहुत सरल उपाय

यहाँ गलत शाखा के लिए आने के लिए एक सरल उपाय है। masterतीन गलत तरीके से होने वाली शाखा पर शुरू :

git reset HEAD~3
git stash
git checkout newbranch
git stash pop

इसका उपयोग कब करें?

  • यदि आपका प्राथमिक उद्देश्य वापस रोल करना है master
  • आप फ़ाइल परिवर्तन रखना चाहते हैं
  • आपको गलत तरीके से किए गए संदेशों के बारे में परवाह नहीं है
  • आपने अभी तक धक्का नहीं दिया है
  • आप चाहते हैं कि यह याद रखना आसान हो
  • आप अस्थाई / नई शाखाओं, कमिटेड हैश, और अन्य सिरदर्द को खोजने और कॉपी करने जैसी जटिलताएं नहीं चाहते हैं

यह क्या करता है, लाइन नंबर द्वारा

  1. पिछले तीन कमिट्स (और उनके संदेश) को हटाता है master, फिर भी सभी कार्यशील फ़ाइलों को बरकरार रखता है
  2. सभी कार्यशील फ़ाइल परिवर्तनों को दूर करता है, जिससे masterकार्यशील पेड़ HEAD ~ 3 राज्य के बराबर हो जाता है
  3. किसी मौजूदा शाखा में स्विच करता है newbranch
  4. आपके वर्किंग डायरेक्टरी में स्टैक्ड बदलावों को लागू करता है और स्टैश को साफ करता है

अब आप उपयोग कर सकते हैं git addऔर git commitजैसा कि आप सामान्य रूप से करेंगे। सभी नए आवागमन को जोड़ा जाएगा newbranch

यह क्या नहीं करता है

  • यह आपके पेड़ को अव्यवस्थित करने वाली यादृच्छिक अस्थायी शाखाओं को नहीं छोड़ता है
  • यह गलत प्रतिबद्ध संदेशों को संरक्षित नहीं करता है, इसलिए आपको इस नई प्रतिबद्ध के लिए एक नया प्रतिबद्ध संदेश जोड़ना होगा
  • अपडेट करें! अपने कमिट मैसेज के साथ पूर्व कमेंट को पुनः प्राप्त करने के लिए अपने कमांड बफर के माध्यम से स्क्रॉल करने के लिए अप-एरो का उपयोग करें (धन्यवाद @ आरके)

लक्ष्य

ओपी ने कहा कि बदलाव को खोए बिना "उन कामों को करने से पहले मास्टर को वापस लेना" लक्ष्य था और यह समाधान यही करता है।

मैं इसे सप्ताह में कम से कम एक बार करता हूं जब मैं गलती से masterइसके बजाय नए कमिट करता हूं develop। आमतौर पर मेरे पास रोलबैक के लिए केवल एक ही कमिटमेंट होता है, जिसमें git reset HEAD^लाइन 1 का उपयोग करने के मामले में सिर्फ एक कमिटबैक करने का एक सरल तरीका है।

यदि आप मास्टर के बदलावों को ऊपर की ओर धकेलते हैं तो ऐसा न करें

हो सकता है कि किसी और ने उन परिवर्तनों को खींच लिया हो। यदि आप केवल अपने स्थानीय मास्टर को फिर से लिख रहे हैं तो ऊपर की ओर धकेलने पर कोई प्रभाव नहीं पड़ता है, लेकिन सहयोगियों के लिए एक लिखित इतिहास को आगे बढ़ाने से सिरदर्द हो सकता है।


4
धन्यवाद, मुझे बहुत खुशी है कि मैंने यहाँ तक पहुँचने के लिए अतीत / बहुत पढ़ा, क्योंकि यह मेरे लिए भी एक बहुत ही सामान्य उपयोग का मामला है। क्या हम इतने atypical हैं?
जिम मैक

6
मुझे लगता है कि हम पूरी तरह से विशिष्ट हैं और "उफ़ मैं गलती से मास्टर हो गया" एक मुट्ठी भर या कम हिट्स को वापस करने की आवश्यकता के लिए सबसे आम उपयोग-मामला है। भाग्यशाली है कि यह समाधान इतना आसान है कि मैंने इसे अब याद किया है।
स्लैम

9
यह स्वीकृत उत्तर होना चाहिए। यह सीधा, समझने में आसान और याद रखने में आसान है
सीना मदनी

1
मुझे नहीं लगता कि स्टैशिंग जरूरी है। मैंने बस इसके बिना किया और अच्छी तरह से काम किया।
एक कैम्पस

1
आप अपने प्रतिबद्ध संदेशों को आसानी से वापस पा सकते हैं, यदि आप ऐसा करते हैं, तो उन्हें अपने सीएलआई (कमांड लाइन) इतिहास में रखें। मुझे लगता है कि मैं दोनों का इस्तेमाल किया था git addऔर git commitआदेशों के लिए हुआ था, इसलिए मुझे यह करना पड़ा कि तीर मारा गया और कुछ समय और उछाल दर्ज किया गया! सब कुछ वापस आ गया था, लेकिन अब सही शाखा पर।
ल्यूक गेडियन

30

यह तकनीकी अर्थों में उन्हें "स्थानांतरित" नहीं करता है लेकिन इसका एक ही प्रभाव है:

A--B--C  (branch-foo)
 \    ^-- I wanted them here!
  \
   D--E--F--G  (branch-bar)
      ^--^--^-- Opps wrong branch!

While on branch-bar:
$ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range)

A--B--C  (branch-foo)
 \
  \
   D-(E--F--G) detached
   ^-- (branch-bar)

Switch to branch-foo
$ git cherry-pick E..G

A--B--C--E'--F'--G' (branch-foo)
 \   E--F--G detached (This can be ignored)
  \ /
   D--H--I (branch-bar)

Now you won't need to worry about the detached branch because it is basically
like they are in the trash can waiting for the day it gets garbage collected.
Eventually some time in the far future it will look like:

A--B--C--E'--F'--G'--L--M--N--... (branch-foo)
 \
  \
   D--H--I--J--K--.... (branch-bar)

1
क्या आप rebaseएक ही चीज़ के लिए उपयोग नहीं कर सकते ?
बर्गी

हाँ आप वैकल्पिक रूप से rebaseऊपर के परिदृश्य में अलग की गई शाखा पर उपयोग कर सकते हैं।
सुकिमा

24

इतिहास को फिर से लिखे बिना ऐसा करने के लिए (यानी यदि आपने पहले ही कमिट को धकेल दिया है):

git checkout master
git revert <commitID(s)>
git checkout -b new-branch
git cherry-pick <commitID(s)>

दोनों शाखाओं को तब बल के बिना धकेला जा सकता है!


लेकिन फिर आपको रिवर्ट परिदृश्य से निपटना होगा, जो आपकी परिस्थिति पर निर्भर करता है, एक बहुत मुश्किल हो सकता है। यदि आप शाखा पर एक कमिट वापस करते हैं, तो Git अभी भी उन कमिट्स को देखेगा जैसे कि जगह ले ली है, इसलिए इसे पूर्ववत करने के लिए, आपको रिवर्ट को वापस करना होगा। यह काफी लोगों को जलाता है, खासकर जब वे एक मर्ज को वापस करते हैं और शाखा को वापस मर्ज करने की कोशिश करते हैं, केवल यह खोजने के लिए कि गिट मानते हैं कि यह पहले से ही उस शाखा में विलय हो गया है (जो पूरी तरह सच है)।
मकोतो

1
यही कारण है कि मैं एक नई शाखा पर अंत में कमियों को चुनता हूं। इस तरह git उन्हें नए कमिट के रूप में देखता है, जो आपके मुद्दे को हल करता है।
तेह_नौस

यह पहले की तुलना में अधिक खतरनाक है, क्योंकि आप इस राज्य के निहितार्थ को समझने के बिना भंडार के इतिहास की स्थिति को बदल रहे हैं।
मकोतो

5
मैं आपके तर्क का पालन नहीं करता - इस उत्तर का मतलब यह है कि आप इतिहास को नहीं बदल रहे हैं, बस नए तरीके जोड़ रहे हैं (जो प्रभावी रूप से परिवर्तनों को पूर्ववत करें)। इन नए कमिटों को सामान्य रूप से धकेला और मर्ज किया जा सकता है।
तेह_सौस

13

सिर्फ यही स्थिति थी:

Branch one: A B C D E F     J   L M  
                       \ (Merge)
Branch two:             G I   K     N

मैंने प्रदर्शन किया:

git branch newbranch 
git reset --hard HEAD~8 
git checkout newbranch

मुझे उम्मीद थी कि कमिटेड मैं HEAD हो जाऊंगा, लेकिन प्रतिबद्ध L यह अब है ...

इतिहास में सही जगह पर उतरना सुनिश्चित करने के लिए कमिट के हैश के साथ काम करना आसान है

git branch newbranch 
git reset --hard #########
git checkout newbranch

7

मैं इससे कैसे जा सकता हूं

A - B - C - D - E 
                |
                master

इसके लिए?

A - B - C - D - E 
    |           |
    master      newbranch

दो आज्ञाओं के साथ

  • गिट ब्रांच -एम मास्टर न्यूब्रांच

दे रही है

A - B - C - D - E 
                |
                newbranch

तथा

  • गिट शाखा मास्टर बी

दे रही है

A - B - C - D - E
    |           |
    master      newbranch

हां, यह काम करता है और काफी आसान है। सॉरीकेट्री जीयूआई गिट शेल में किए गए परिवर्तनों के बारे में थोड़ा भ्रमित है, लेकिन एक भ्रूण के बाद यह फिर से ठीक है।
लार्स के।

हाँ, वे इस प्रश्न में हैं। आरेख के पहले जोड़े को प्रश्न में उन लोगों के समतुल्य माना जाता है, जिस तरह से मैं उत्तर में चित्रण के उद्देश्य से चाहूंगा। मूल रूप से नई शाखा के रूप में मास्टर शाखा का नाम बदलें और एक नई मास्टर शाखा बनाएं जहां आप चाहते हैं।
इवान

4

यदि आपको अपने सभी अप्रकाशित को एक नई शाखा में ले जाने की आवश्यकता है , तो आपको बस जरूरत है,

  1. वर्तमान से एक नई शाखा बनाएं :git branch new-branch-name

  2. अपनी नई शाखा को आगे बढ़ाएं :git push origin new-branch-name

  3. अपनी पुरानी (वर्तमान) शाखा को अंतिम धक्का / स्थिर स्थिति में वापस लाएं :git reset --hard origin/old-branch-name

कुछ लोगों के पास इसके upstreamsबजाय अन्य भी हैं origin, उन्हें उचित उपयोग करना चाहिएupstream


3

1) एक नई शाखा बनाएँ, जो आपके सभी परिवर्तनों को new_branch में ले जाती है।

git checkout -b new_branch

2) फिर पुरानी शाखा में वापस जाएं।

git checkout master

3) गिट रिबेस करें

git rebase -i <short-hash-of-B-commit>

4) तब खोले गए संपादक में अंतिम 3 प्रतिबद्ध जानकारी होती है।

...
pick <C's hash> C
pick <D's hash> D
pick <E's hash> E
...

5) बदलें pickकरने के लिए dropउन 3 प्रतिबद्ध सब में। फिर संपादक को सहेजें और बंद करें।

...
drop <C's hash> C
drop <D's hash> D
drop <E's hash> E
...

6) अब पिछले 3 कमिट को करंट ब्रांच ( master) से हटा दिया जाता है । अब शाखा को बलपूर्वक धक्का दें, +शाखा नाम से पहले संकेत के साथ ।

git push origin +master

2

आप कर सकते हैं यह सिर्फ 3 सरल कदम है जो मैंने उपयोग किया है।

1) नई शाखा बनाएं जहां आप हाल ही में अद्यतन करना चाहते हैं।

git branch <branch name>

2) नई शाखा के लिए प्रतिबद्ध के लिए हाल ही में ईद खोजें।

git log

3) उस आईडी नोट को कॉपी करें जो सबसे हालिया प्रतिबद्ध सूची शीर्ष पर है। तो आप अपनी प्रतिबद्धता पा सकते हैं। आप यह संदेश के माध्यम से भी पाते हैं।

git cherry-pick d34bcef232f6c...

आप कुछ आईडी आईडी भी प्रदान कर सकते हैं।

git cherry-pick d34bcef...86d2aec

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

अब आप अपने कोड को पुश कर सकते हैं

git push


0

ऐसा करने का एक और तरीका:

[१]master अपनी शाखा का नाम बदलें newbranch(यह मानते हुए कि आप masterशाखा में हैं):

git branch -m newbranch

[२]master अपनी इच्छा के अनुसार अपनी ओर से शाखा बनाएँ :

git checkout -b master <seven_char_commit_id>

जैसे git चेकआउट -b मास्टर a34bc22

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