git - गिट मर्ज को पूर्ववत करें जिसे अभी तक धक्का नहीं दिया गया है




undo git-merge (22)

मेरी मास्टर शाखा के भीतर, मैंने git merge some-other-branch स्थानीय रूप से git merge some-other-branch किया, लेकिन कभी भी मूल मास्टर में बदलावों को धक्का नहीं दिया। मेरा विलय करने का मतलब नहीं था, इसलिए मैं इसे पूर्ववत करना चाहता हूं। मेरे विलय के बाद git status , मुझे यह संदेश मिल रहा था:

# On branch master
# Your branch is ahead of 'origin/master' by 4 commits.

मैंने पाया कुछ निर्देशों के आधार पर, मैंने दौड़ने की कोशिश की

git revert HEAD -m 1

लेकिन अब मुझे यह संदेश git status साथ मिल रहा है:

# On branch master
# Your branch is ahead of 'origin/master' by 5 commits.

मैं नहीं चाहता कि मेरी शाखा किसी भी काम से आगे बढ़े। मैं उस बिंदु पर कैसे वापस आ सकता हूं?


Answers

इस सवाल को भी मिल गया मूल मिलान (यानी, उत्पत्ति से पहले कोई काम नहीं करता) पर वापस लौटना चाहते हैं। आगे की खोज में पाया गया कि वास्तव में एक reset कमांड है:

git reset --hard @{u}

नोट: @{u} origin/master लिए लघुरूप है। (और, ज़ाहिर है, आपको काम करने के लिए उस रिमोट रिपोजिटरी की आवश्यकता है।)


रणनीति: जहां से सबकुछ अच्छा था वहां से एक नई शाखा बनाएं।

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

उपाय:

मान लें कि आप feature-1 में dev को मर्ज करना चाहते हैं।

  1. उस संशोधन को ढूंढें जिसे आप मर्ज प्राप्त करना चाहते हैं:

    git log --oneline feature-1
    a1b2c3d4 Merge branch 'dev' into 'feature-1' <-- the merge you want to undo
    e5f6g7h8 Fix NPE in the Zero Point Module <-- the one before the merge, you probably want this one
    
  2. इसे देखें (समय पर वापस जाएं):

    git checkout e5f6g7h8
    
  3. वहां से एक नई शाखा बनाएं और इसे देखें:

    git checkout -b feature-1
    

अब आप अपने मर्ज को पुनरारंभ कर सकते हैं:

  1. मर्ज करें: git merge dev

  2. अपने विलय संघर्ष को ठीक करें।

  3. प्रतिबद्धता: git commit

  4. जब आप परिणामों से संतुष्ट होते हैं, तो पुरानी शाखा हटाएं: git branch --delete feature-1


git reflog चेक के साथ जो प्रतिबद्धता विलय से पहले एक है (गिट लॉग से गिट रीफ्लॉग बेहतर विकल्प होगा)। फिर आप इसे रीसेट कर सकते हैं:

git reset --hard commit_sha

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

git reset --hard HEAD~1

आपको वापस 1 प्रतिबद्ध मिलेगा।

ध्यान रखें कि किसी भी संशोधित और असामान्य / अनस्टेड फ़ाइलों को उनके असम्बद्ध राज्य में रीसेट कर दिया जाएगा । उन्हें या तो स्टैश परिवर्तनों को दूर रखने के लिए या नीचे --merge विकल्प देखें।

जैसा कि @ वेल्मोंट ने अपने जवाब में नीचे दिया है, इस प्रत्यक्ष मामले में:

git reset --hard ORIG_HEAD

बेहतर परिणाम प्राप्त कर सकते हैं, क्योंकि यह आपके परिवर्तनों को संरक्षित रखना चाहिए। ORIG_HEAD विलय होने से पहले सीधे एक प्रतिबद्धता को इंगित करेगा, इसलिए आपको इसके लिए शिकार करने की आवश्यकता नहीं है।

एक और युक्ति है - के बजाय --merge स्विच का --hard क्योंकि यह अनावश्यक रूप से फ़ाइलों को रीसेट नहीं करता है:

--merge

इंडेक्स को रीसेट करता है और काम करने वाले पेड़ में फ़ाइलों को अपडेट करता है जो <प्रतिबद्ध> और HEAD के बीच अलग होते हैं, लेकिन इंडेक्स और वर्किंग पेड़ के बीच अलग-अलग होते हैं (यानी जिनके पास बदलाव नहीं किए गए हैं)।


आपको पिछली प्रतिबद्धता पर रीसेट करना चाहिए। यह काम करना चाहिए:

git reset --hard HEAD^

या यहां तक ​​कि HEAD^^ को वापस करने की प्रतिबद्धता को वापस करने के लिए। यदि आप सुनिश्चित नहीं हैं कि आपको कितने कदम उठाने चाहिए तो आप हमेशा एक पूर्ण SHA संदर्भ दे सकते हैं।

यदि आपको समस्याएं होती हैं और आपकी मास्टर शाखा में कोई स्थानीय परिवर्तन नहीं होता है, तो आप origin/master रीसेट कर सकते हैं।


मुझे लगता है कि आप git rebase -i [hash] [branch_name] कर सकते हैं जहां [hash] पहचान हैश है, लेकिन अभी तक आप एक से अधिक रिवाइंड करना चाहते हैं (या फिर कई लोग वापस जाना चाहते हैं) और फिर लाइनों को हटाएं संपादक में यह काम करता है कि आप और नहीं चाहते हैं। फ़ाइल सहेजें। बाहर जाएं। प्रार्थना करना। और यह rewound होना चाहिए। आपको एक git reset --hard करना होगा - git reset --hard , लेकिन इस बिंदु पर यह अच्छा होना चाहिए। यदि आप उन्हें अपने इतिहास में नहीं रखना चाहते हैं, तो आप स्टैक से विशिष्ट काम खींचने के लिए इसका भी उपयोग कर सकते हैं, लेकिन यह आपके भंडार को ऐसे राज्य में छोड़ सकता है जिसे आप शायद नहीं चाहते हैं।


यदि आप कमांड लाइन समाधान चाहते हैं, तो मैं बस एमबीओ के जवाब के साथ जाने का सुझाव देता हूं।

यदि आप एक नौसिखिया हैं, तो आप ग्राफिकल दृष्टिकोण पसंद कर सकते हैं:

  1. gitk को gitk (कमांड लाइन से, या यदि आपके पास है तो फ़ाइल ब्राउज़र में राइट क्लिक करें)
  2. आप वहां आसानी से विलय प्रतिबद्धता को देख सकते हैं - दो माता-पिता के साथ शीर्ष से पहला नोड
  3. पहले / बाएं माता-पिता के लिंक का पालन करें (विलय से पहले आपकी वर्तमान शाखा में से एक, आमतौर पर मेरे लिए लाल)
  4. चयनित प्रतिबद्धता पर, "यहां शाखा रीसेट करें" पर राइट-क्लिक करें, वहां हार्ड रीसेट चुनें

यदि आपने विलय किया है:

git reset HEAD~1
# Make sure what you are reverting is in fact the merge files
git add .
git reset --hard

सबसे आसान जवाब ओडिंहो - वेलमोंट द्वारा दिया गया है

सबसे पहले git reset --merge ORIG_HEAD

परिवर्तनों को धक्का देने के बाद रीसेट करने वाले लोगों के लिए, ऐसा करें (क्योंकि यह किसी भी गिट रीसेट विलय प्रश्नों के लिए पहली पोस्ट देखी गई है)

git push origin HEAD --force

यह इस तरह से रीसेट हो जाएगा कि आपको खींचने के बाद फिर से मर्ज किए गए परिवर्तन नहीं मिलेंगे।


नए गिट संस्करणों के साथ, यदि आपने अभी तक विलय नहीं किया है और आपके पास विलय विवाद है , तो आप बस ऐसा कर सकते हैं:

git merge --abort

man git merge :

[यह] विलय के परिणामस्वरूप विवादों के परिणामस्वरूप ही चलाया जा सकता है। git merge --abort विलय प्रक्रिया को रोक देगा और पूर्व विलय राज्य का पुनर्निर्माण करने का प्रयास करेगा।


सबसे सरल मौका का सबसे सरल, यहां कुछ भी कहा गया है उससे कहीं अधिक सरल:

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


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

git reset --merge ORIG_HEAD

रेफरी ORIG_HEAD मर्ज से पहले मूल प्रतिबद्धता को इंगित करेगा।

( --merge विकल्प में मर्ज के साथ कुछ लेना देना नहीं है। यह git reset --hard ORIG_HEAD तरह है - git reset --hard ORIG_HEAD , लेकिन सुरक्षित है क्योंकि यह git reset --hard ORIG_HEAD परिवर्तनों को स्पर्श नहीं करता है।)


आप पिछले चेकआउट को खोजने के लिए git reflog का उपयोग कर सकते हैं। कभी-कभी यह एक अच्छी स्थिति है जिसे आप वापस लौटना चाहते हैं।

वस्तुतः,

$ git reflog
$ git reset --hard [email protected]{0}

यदि आप देखते हैं कि विलय के तुरंत बाद आपको वापस लौटने की आवश्यकता है और आपने मर्ज प्रयास के बाद कुछ भी नहीं किया है, तो आप केवल यह आदेश जारी कर सकते हैं: git reset --hard [email protected]{1}

अनिवार्य रूप से, आपका मर्ज sha [email protected]{0} इंगित करेगा यदि विलय के बाद कुछ भी नहीं किया गया था और इसलिए मर्ज से पहले [email protected]{1} पिछला बिंदु होगा।


यदि आपने अभी तक इसे प्रतिबद्ध नहीं किया है, तो आप केवल उपयोग कर सकते हैं

$ git checkout -f

यह मर्ज (और जो कुछ भी आपने किया था) पूर्ववत कर देगा।


गिट बुक में अध्याय 4 और लिनस टोरवाल्ड्स द्वारा मूल पोस्ट देखें

एक विलय पूर्ववत करने के लिए जो पहले ही धक्का दिया गया था :

git revert -m 1 commit_hash

यदि आप फिर से शाखा कर रहे हैं, तो लिनस ने कहा, रिवर्ट को वापस करना सुनिश्चित करें।


ठीक है, यहां अन्य लोगों ने जवाब दिया था, लेकिन यह काम नहीं किया। मैंने जो किया है वह यहाँ है।

यह कर रहा हूं...

git reset --hard HEAD^
git status

... मुझे निम्नलिखित स्थिति दी।

# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.

तब मुझे एक ही git reset कमांड में कई बार टाइप करना पड़ा। हर बार जब मैंने ऐसा किया, तो संदेश एक जैसा बदल गया जैसा आप नीचे देख सकते हैं।

> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 3 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 2 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 1 and 3 different commit(s) each, respectively.
> git reset --hard HEAD^
HEAD is now at [...truncated...]
> git status
# On branch master
# Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.

इस बिंदु पर, मैंने स्थिति संदेश बदल दिया, इसलिए मैंने एक git pull की कोशिश की, और यह काम करने लग रहा था:

> git pull
Updating 2df6af4..12bbd2f
Fast forward
 app/views/truncated |    9 ++++++---
 app/views/truncated |   13 +++++++++++++
 app/views/truncated |    2 +-
 3 files changed, 20 insertions(+), 4 deletions(-)
> git status
# On branch master

इतनी लंबी कहानी छोटी है, मेरे आदेश इस पर आ गए:

git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git reset --hard HEAD^
git pull

हाल ही में, मैं इसके साथ मदद करने के लिए git reflog का उपयोग कर रहा हूं। यह ज्यादातर तभी काम करता है जब विलय बस हुआ, और यह आपकी मशीन पर था।

git reflog कुछ ऐसा वापस कर सकता है:

fbb0c0f [email protected]{0}: commit (merge): Merge branch 'master' into my-branch
43b6032 [email protected]{1}: checkout: moving from master to my-branch
e3753a7 [email protected]{2}: rebase finished: returning to refs/heads/master
e3753a7 [email protected]{3}: pull --rebase: checkout e3753a71d92b032034dcb299d2df2edc09b5830e
b41ea52 [email protected]{4}: reset: moving to HEAD^
8400a0f [email protected]{5}: rebase: aborting

पहली पंक्ति इंगित करती है कि एक विलय हुआ। दूसरी पंक्ति मेरे विलय से पहले समय है। मैं बस इस शाखा को विलय से पहले ट्रैक करने के लिए मजबूर करने के लिए git reset --hard 43b6032 पर git reset --hard 43b6032 और git reset --hard 43b6032 करता git reset --hard 43b6032


  1. सबसे पहले, सुनिश्चित करें कि आपने सबकुछ किया है।

  2. फिर अपने कामकाज को पिछले कार्यशील स्थिति में रीसेट करें:

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36
    

    या --hard का उपयोग ( यह सभी स्थानीय, प्रतिबद्ध परिवर्तन नहीं हटा देगा! ):

    $ git reset f836e4c1fa51524658b9f026eb5efa24afaf3a36 --hard
    

    हैश का प्रयोग करें जो आपके गलत तरीके से विलय करने से पहले था।

  3. जांचें कि आप पिछले सही संस्करण के शीर्ष पर फिर से प्रतिबद्ध करना चाहते हैं:

    $ git log 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    commit 4c3e23f529b581c3cbe95350e84e66e3cb05704f
    
    ...
    
    commit 16b373a96b0a353f7454b141f7aa6f548c979d0a
    
    ...
    
  4. अपने भंडार के दाएं संस्करण के शीर्ष पर अपने दाएं कामों को लागू करें:

    • चेरी-पिक (कुछ मौजूदा कामों द्वारा पेश किए गए परिवर्तन) का उपयोग करके

          git cherry-pick ec59ab844cf504e462f011c8cc7e5667ebb2e9c7
      
    • या चेरी द्वारा: द्वारा की जाने वाली सीमाओं को चुनकर:

      • सबसे पहले उन्हें विलय करने से पहले सही परिवर्तनों की जांच करना:

        git diff 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        
      • सबसे पहले उन्हें विलय करने से पहले सही परिवर्तनों की जांच करना:

        git cherry-pick 5216b24822ea1c48069f648449997879bb49c070..4c3e23f529b581c3cbe95350e84e66e3cb05704f
        

        जहां यह आपके द्वारा किए गए सही कामों की सीमा है (गलत तरीके से प्रतिबद्ध विलय को छोड़कर)।


आप मर्ज को वापस करने या किसी विशिष्ट प्रतिबद्धता को पुनरारंभ करने के लिए केवल दो आदेशों का उपयोग कर सकते हैं:

  1. git reset --hard commitHash (आपको उस प्रतिबद्धता का उपयोग करना चाहिए जिसे आप पुनरारंभ करना चाहते हैं, उदाहरण के लिए 44a587491e32eafa1638aca7738)
  2. git push origin HEAD --force (नई स्थानीय मास्टर शाखा को मूल / मास्टर को भेजना)

शुभकामनाएँ और आगे बढ़ो!


इस मामले में, आप अपनी शाखा को git reset --hard <branch_name> साथ रीसेट करना git reset --hard <branch_name> । यदि आप उन्हें रीसेट करने से पहले अपने परिवर्तनों को सहेजना चाहते हैं तो एक नई शाखा और git checkout <branch_name> बनाना सुनिश्चित करें।

आप git reset --hard <commit_id> साथ राज्य को एक विशिष्ट प्रतिबद्धता में रीसेट कर सकते हैं - git reset --hard <commit_id> साथ ही।

यदि परिवर्तनों को धक्का दिया गया है तो आप इसके बजाय git revert <branch_name> उपयोग कर सकते हैं। अन्य परिदृश्यों में गिट रिवर्ट और गिट चेकआउट का उपयोग कैसे करें, यह जांचना सुनिश्चित करें।


मान लें कि आपका स्थानीय मास्टर मूल / मास्टर से आगे नहीं था, आपको ऐसा करने में सक्षम होना चाहिए

git reset --hard origin/master

तब आपकी स्थानीय master शाखा origin/master समान दिखनी चाहिए।


मैंने checkout बाद fetch उपयोग किया है ...

git fetch <remote> <rbranch>:<lbranch> 
git checkout <lbranch>

... जहां <rbranch> रिमोट शाखा या स्रोत रेफरी है और <lbranch> अभी तक मौजूद गैर-मौजूदा स्थानीय शाखा या गंतव्य रेफरी है जिसे आप ट्रैक करना चाहते हैं और जिसे आप शायद दूरस्थ शाखा या स्रोत रेफरी के रूप में नामित करना चाहते हैं । यह <refspec> के स्पष्टीकरण में options तहत समझाया गया है।

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

इसके अलावा इस तरह के एसओ पोस्ट शो में जवाब , यदि आप स्थानीय शाखा का नाम नहीं लेते हैं, तो आप अभी भी इसे बना सकते हैं जब आप -b ध्वज का उपयोग करके इसे चेक आउट करते हैं। आईई: git fetch <remote> <branch> git checkout -b <branch> <remote>/<branch> मेरे शुरुआती उत्तर के समान ही है। और जाहिर है कि यदि आपके रेपो में केवल एक रिमोट है, तो आप केवल git checkout <branch> fetch और यह आपके लिए एक स्थानीय शाखा बनायेगा। ईजी: आपने अभी एक रेपो क्लोन किया है और रिमोट से अतिरिक्त शाखाएं देखना चाहते हैं।

मेरा मानना ​​है कि fetch लिए कुछ दस्तावेज pull से क्रियात्मक प्रतिलिपि बना सकते हैं। विशेष रूप से options में <refspec> पर अनुभाग समान है। हालांकि, मुझे विश्वास नहीं है कि fetch कभी merge हो जाएगा, ताकि अगर आप कोलन के गंतव्य पक्ष को खाली छोड़ दें तो कुछ भी नहीं करना चाहिए

नोट: उस git fetch <remote> <refspec> लिए छोटा है git fetch <remote> <refspec>: जो कुछ भी नहीं करेगा, लेकिन git fetch <remote> <tag> git fetch <remote> <tag>:<tag> जो दूरस्थ <tag> स्थानीय रूप से कॉपी करना चाहिए।

मुझे लगता है कि यह केवल सहायक है अगर आप स्थानीय रूप से रिमोट शाखा की प्रतिलिपि बनाना चाहते हैं, लेकिन जरूरी नहीं कि इसे तुरंत जांचें। अन्यथा अब मैं ऊपर दिए गए स्वीकृत उत्तर का उपयोग करूंगा, जिसे चेकआउट विवरण के पहले भाग में और बाद में options अनुभाग में विस्तार से समझाया गया है, क्योंकि यह 1-लाइनर है। खैर ... एक 1-लाइनर की तरह, क्योंकि आपको अभी भी git fetch <remote> चलाना होगा।

<refspecs> (स्रोत: गंतव्य) का आदेश रिमोट शाखाओं को हटाने के लिए विचित्र प्री गिट <refspecs> विधि बताता है। आईई: गंतव्य refspec में कुछ भी पुश।





git undo git-merge