उत्पत्ति संस्करण के लिए गिट शाखा को रीसेट करने की आवश्यकता है


439

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



2.23 के साथ (अगस्त 2019) git switch -C mybranch origin/mybranch:। देखें नीचे मेरी संपादित जवाब
VonC

जवाबों:


814

यदि आपने अभी तक उत्पत्ति के लिए धक्का नहीं दिया है, तो आप अपनी शाखा को अपस्ट्रीम शाखा के साथ रीसेट कर सकते हैं :

git checkout mybranch
git reset --hard origin/mybranch

(सुनिश्चित करें कि आप अपनी नवीनतम प्रतिबद्ध को एक अलग शाखा में संदर्भित करते हैं, जैसे कि आप अपने प्रश्न में उल्लेख करते हैं)

ध्यान दें कि रीसेट के बाद, रीसेट mybranch@{1}करने से पहले पुरानी प्रतिबद्ध को संदर्भित करता है।

लेकिन अगर आपने पहले से ही धक्का दिया था, तो अन्य विकल्पों के लिए " क्रिएट ब्रांच बनाएं, और मूल अपस्ट्रीम स्टेट पर वापस जाएं " देखें।


साथ Git 2.23 (अगस्त 2019) , कि एक कमांड यह होगी: git switch
अर्थात्:git switch -C mybranch origin/mybranch

उदाहरण

C:\Users\vonc\git\git>git switch -C master origin/master
Reset branch 'master'
Branch 'master' set up to track remote branch 'master' from 'origin'.
Your branch is up to date with 'origin/master'.

यह एक की तरह सूचकांक और काम करने के पेड़ को पुनर्स्थापित करता है git reset --hard


जैसा कि ब्रैड हरमन ने कहा था , कोई भी नई फ़ाइलreset --hard को हटा देगा या संशोधित फ़ाइल को HEAD में बदल देगा

वास्तव में, सुनिश्चित करें कि आप एक "क्लीन स्लेट" से शुरू, एक होने के लिए git clean -f -dरीसेट के बाद एक काम कर पेड़ यह सुनिश्चित करना होगा कि वास्तव में शाखा तुम सिर्फ करने के लिए पुनर्स्थापित करने के लिए समान।


यह ब्लॉग पोस्ट उन उपनामों का सुझाव देता है ( masterकेवल शाखा के लिए , लेकिन आप उन लोगों को अनुकूलित / विस्तारित कर सकते हैं):

[alias]
   resetorigin = !git fetch origin && git reset --hard origin/master && git clean -f -d
   resetupstream = !git fetch upstream && git reset --hard upstream/master && git clean -f -d

फिर आप टाइप कर सकते हैं:

git resetupstream

या

git resetorigin

26
यह गैर-परिवर्तन किए गए / हटाए गए (
पीटर

5
मैंने git reset --hard origin/mybranchकई बार कमांड का उपयोग किया है जब मैंने किसी भी स्थानीय परिवर्तन के बारे में परवाह नहीं की और बस एक साफ प्रतिलिपि चाहता था जो मूल से मेल खाती थी। हालांकि, आज, यह काम नहीं किया - मेरे पास अभी भी मुट्ठी भर नई, अस्थिर फाइलें थीं और गिट ने मुझे वादा किया था कि यह HEAD में था। नोट के बारे में git clean -f -dतय है कि सभी नई फ़ाइलों को मिटा कर जो मुझे नहीं चाहिए था।
मैथ्यू क्लार्क

@ मैथ्यू क्लार्क उम्मीद है कि: stackoverflow.com/q/4327708/6309
VonC

1
महान! इसके अलावा कई बार मैं git reset --hard HEADकिसी भी बदलाव को नजरअंदाज करते हुए पिछली
कमिटमेंट में लौट आया हूं

क्या यह संभव है, यह भी संभव है?
लोनजैक

20

यह मानते हुए कि क्या हुआ:

# on branch master
vi buggy.py                 # you edit file
git add buggy.py            # stage file
git commit -m "Fix the bug" # commit
vi tests.py                 # edit another file but do not commit yet

तब आपको एहसास होता है कि आप गलत शाखा पर बदलाव करते हैं।

git checkout -b mybranch    # you create the correct branch and switch to it

लेकिन फिर masterभी आपकी प्रतिबद्धता की ओर इशारा करता है। आप चाहते हैं कि यह उस बिंदु पर पहुंचे जहां उसने पहले बताया था।

समाधान

सबसे आसान तरीका है:

git branch --force master origin/master

एक और तरीका है:

git checkout master
git reset --soft origin/master
git checkout mybranch

ध्यान दें कि उपयोग करने reset --hardसे आपके अनपेक्षित परिवर्तन खो जाएंगे ( tests.pyमेरे उदाहरण में)।


यह मेरे उत्तर की तुलना में अधिक सुरक्षित लगता है;) +1
VONC

8

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

कस के पकड।

[alias]
  catchup = "!f(){ echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \"; read -r ans; if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)); else echo \"catchup aborted\"; fi }; f"

उचित रूप से स्वरूपित (यह .itconfig में नए के साथ काम नहीं करेगा) यह इस तरह दिखता है:

"
!f(){
  echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \";
  read -r ans;
  if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then
    git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD));
  else
    echo \"catchup aborted\";
  fi
}; f
"
  • \\033[0;33mऔर \\033[0mरंग के साथ वर्तमान शाखा और नदी के ऊपर पर बल के लिए है।
  • $(git symbolic-ref -q --short HEAD) वर्तमान शाखा का नाम है
  • $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)) वर्तमान शाखा का अपस्ट्रीम है।

चूंकि रीसेट एक संभावित खतरनाक कॉल है (विशेष रूप से -हार्ड विकल्प के साथ, आप किसी भी परिवर्तन को खो देंगे), यह पहले आपको बताता है कि यह क्या करने वाला है। उदाहरण के लिए, यदि आप रिमोट -क्यूकैप / देव-कंटेनर नामक शाखा देव-कंटेनर पर हैं और आप प्रवेश करते हैं , तो आपको संकेत दिया जाएगा:git catchup

देवक-कंटेनर को qcpp / dev- कंटेनर में रीसेट करें? (Y n)

यदि आप फिर y टाइप करते हैं या सिर्फ रिटर्न हिट करते हैं, तो यह रिसेट करेगा। यदि आप कुछ और दर्ज करते हैं, तो रीसेट नहीं किया जाएगा।

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

चेतावनी का अनिवार्य शब्द: यदि आप सार्वजनिक रिपॉजिटरी पर काम कर रहे हैं तो अन्य लोगों के पास काम पर आधारित है, और आपको इस उपनाम की आवश्यकता है, आप इसे गलत कर रहे हैं ™


1

मैंने यह कोशिश की और इसने मेरी वर्तमान शाखा को अपने दूरस्थ गितुब नवीनतम तक रीसेट नहीं किया। मैंने गुगली की और https://itsyndicate.org/blog/how-to-use-git-force-pull-perperly/ पाया

जो सुझाव दिया

git fetch origin master
git reset --hard origin/master

मैं अपनी v8 शाखा को रीसेट करना चाहता था इसलिए मैंने किया

git fetch origin v8
git reset --hard origin/v8

और यह काम किया


वैसे यह अच्छा है कि आप भ्रूण का उल्लेख करें। मैंने 2 साल पहले एक बार बिना कुछ और रीसेट किए :) :)
एडम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.