التراجع عن دمج Git لم يتم دفعه بعد




undo git-merge (18)

  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
        

        حيث يمثل هذا نطاق الالتزامات الصحيحة التي ارتكبتها (باستثناء الدمج الملتزم بطريق الخطأ).

داخل فرع رئيسي ، قمت 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.

لا أريد أن يكون فرعي متقدمًا بأي عدد من الالتزامات. كيف أعود إلى هذه النقطة؟


أبسط أبسط فرصة ، أبسط بكثير من أي شيء يقال هنا:

قم بإزالة الفرع المحلي (المحلي وليس بعيدًا) واسحبه مرة أخرى. بهذه الطريقة ستقوم بالتراجع عن التغييرات على فرعك الرئيسي وسوف يتأثر أي شخص بالتغيير الذي لا تريد دفعه. ابدا الامر.


أعتقد أنه بإمكانك القيام git rebase -i [hash] [branch_name] حيث [hash] هو علامة git rebase -i [hash] [branch_name] على الرغم من أنك تريد الرجوع إلى الوراء بالإضافة إلى واحد (أو على الرغم من ذلك ، فإن العديد من الإلتزامات تريد العودة) ثم حذف الخطوط الالتزام في المحرر أنك لا تريد أكثر من ذلك. حفظ الملف. ىخرج. صلى. ويجب إعادة لفها. قد تضطر إلى القيام git reset --hard ، ولكن يجب أن تكون جيدة في هذه المرحلة. يمكنك أيضًا استخدام هذا لسحب ارتباطات محددة من مجموعة مكدسة ، إذا كنت لا ترغب في الاحتفاظ بها في السجل الخاص بك ، ولكن يمكن أن تترك مستودعك في حالة ربما لا تريدها.


إذا ارتكبت الدمج:

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

إذا لاحظت أنك بحاجة إلى العودة مباشرة بعد الدمج ولم تقم بأي شيء آخر بعد محاولة الدمج ، يمكنك فقط إصدار هذا الأمر: git reset --hard [email protected]{1} .

بشكل أساسي ، سيشير sha الدمج الخاص بك إلى [email protected]{0} إذا لم يتم الالتزام بأي شيء آخر بعد الدمج ، وبالتالي سيكون [email protected]{1} هو النقطة السابقة قبل الدمج.


إذا لم تلتزم بها بعد ، فيمكنك استخدامها فقط

$ git checkout -f

سيؤدي ذلك إلى التراجع عن الدمج (وكل ما فعلته).



بافتراض أن سيدك المحلي لم يكن متقدمًا على الأصل / الرئيسي ، يجب أن تكون قادرًا على القيام بذلك

git reset --hard origin/master

ثم يجب أن يبدو الفرع master المحلي متطابقًا مع origin/master .


حسنًا ، كانت الإجابات التي قدمها أشخاص آخرون هنا قريبة ، ولكنها لم تنجح. اليك ما فعلت.

فعل هذا...

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

حصلت على هذا السؤال أيضا تتطلع إلى العودة إلى مطابقة الأصل (أي ، يرتكب قبل المنشأ). البحث أبعد من ذلك ، وجدت هناك أمر reset بالضبط ذلك:

git reset --hard @{u}

ملاحظة: @{u} هي اختصار للمصدر origin/master . (وبالطبع ، تحتاج إلى هذا المستودع عن بعد لهذا العمل.)


في الآونة الأخيرة ، لقد تم استخدام 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 <branch_name> . إذا كنت ترغب في حفظ التغييرات قبل إعادة تعيينها ، تأكد من إنشاء فرع جديد و git checkout <branch_name> .

يمكنك إعادة تعيين الحالة إلى التزام معين باستخدام git reset --hard <commit_id> أيضًا.

إذا تم دفع التغييرات ، يمكنك استخدام git revert <branch_name> بدلاً من ذلك. تأكد من معرفة كيفية استخدام git revert و git checkout في سيناريوهات أخرى أيضًا.


مع إصدارات Git الأحدث ، إذا لم تكن قد ارتكبت الدمج حتى الآن ولديك تعارض دمج ، يمكنك ببساطة القيام بما يلي:

git merge --abort

من man git merge :

يمكن تشغيل [هذا] فقط بعد أن يؤدي الدمج إلى حدوث تعارضات. git merge --abort عملية الدمج ويحاول إعادة بناء حالة الدمج المسبق.


مع التحقق من git reflog الذي ارتكب هو واحد قبل الدمج (git reflog سيكون أفضل خيار من سجل git). بعد ذلك ، يمكنك إعادة تعيينه باستخدام:

git reset --hard commit_sha

هناك أيضا طريقة أخرى

git reset --hard HEAD~1

سوف يعيدك 1 ارتكاب.

يجب أن تدرك أن أي ملفات معدلة وغير ملتزمة / غير متكررة سيتم إعادة تعيينها إلى حالتها غير المعدلة . لإبقائهم --merge التغييرات أو يرون خيار --merge أدناه.

كما اقترحVelmont أدناه في إجابته ، في هذه الحالة المباشرة باستخدام:

git reset --hard ORIG_HEAD

قد تؤدي إلى نتائج أفضل ، حيث يجب أن تحافظ على تغييراتك. ORIG_HEAD إلى الالتزام مباشرة قبل حدوث الدمج ، لذا لن تضطر إلى البحث عنه بنفسك.

نصيحة أخرى هي استخدام مفتاح التبديل - بدلاً من --hard حيث أنه لا يعيد تعيين الملفات دون داع:

--دمج

إعادة تعيين الفهرس وتحديث الملفات الموجودة في شجرة العمل المختلفتين بين <commit> و HEAD ، ولكنها تحتفظ بتلك المختلفتين بين الفهرس وشجرة العمل (أي التي تحتوي على تغييرات لم تتم إضافتها).


يجب إعادة التعيين على الالتزام السابق. يجب أن يعمل هذا:

git reset --hard HEAD^

أو حتى HEAD^^ للعودة إلى الالتزام بالعودة. يمكنك دائمًا تقديم مرجع SHA كامل إذا لم تكن متأكدًا من عدد الخطوات التي يجب عليك اتخاذها.

في حال واجهتك مشاكل ولم يكن لدى فرعك الرئيسي أي تغييرات محلية ، يمكنك إعادة التعيين إلى origin/master .


يمكنك استخدام git reflog للعثور على الخروج السابق. في بعض الأحيان تكون هذه حالة جيدة تريد العودة إليها.

بشكل ملموس،

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

يمكنك استخدام الأمر git-reset.

git-reset - إعادة تعيين الرأس الحالي إلى

حالة محددة. git reset [--mixed |

- سوفت | --ارد | -المزاج] [-q] [] git reset [-q] []

[-] ... git reset --patch

[] [-] [...]

GIT-Reset


الإستراتيجية: إنشاء فرع جديد من حيث كل شيء كان جيدًا.

الأساس المنطقي: العودة إلى دمج أمر صعب. هناك العديد من الحلول ، اعتمادًا على العديد من العوامل مثل ما إذا كنت قد ارتكبت أو دفعت الدمج أو إذا كان هناك تعهدات جديدة منذ الدمج. كما أنك لا تزال بحاجة إلى فهم عميق نسبيًا للواجهة من أجل تكييف هذه الحلول مع حالتك. إذا اتبعت بعض الإرشادات بشكل أعمى ، فيمكن أن ينتهي بك الأمر إلى "دمج فارغ" حيث لن يتم دمج أي شيء ، وستؤدي محاولات الدمج الإضافية إلى جعل Git يخبرك "محدثة بالفعل".

حل:

لنفترض أنك تريد دمج dev في feature-1 .

  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-merge