كيف يمكنك التراجع عن آخر الإلتزامات في Git؟


Answers

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

لنفترض أن لديك هذا ، حيث C هو HEAD و (F) هي حالة ملفاتك.

   (F)
A-B-C
    ↑
  master

أنت تريد أن ترتكب الجريمة (ج) ولا تراه مرة أخرى . تفعل هذا:

git reset --hard HEAD~1

النتيجه هي:

 (F)
A-B
  ↑
master

الآن B هو الرأس. نظرًا لأنك استخدمت --hard ، تتم إعادة تعيين ملفاتك إلى حالتها في ارتكاب الخطأ B.

آه ، لكن لنفترض أن ارتكاب C لم يكن كارثة ، ولكن كان هناك بعض الشيء. أنت تريد التراجع عن الالتزام ، لكن احتفظ بالتغييرات الخاصة بك لبعض التعديلات قبل القيام بتفويض أفضل. البدء من جديد من هنا ، مع C كـ HEAD:

   (F)
A-B-C
    ↑
  master

يمكنك القيام بذلك ، ترك قبالة --hard :

git reset HEAD~1

في هذه الحالة ، تكون النتيجة:

   (F)
A-B-C
  ↑
master

في كلتا الحالتين ، يعد HEAD مجرد مؤشر إلى أحدث التزام. عندما تقوم بإجراء git reset HEAD~1 ، فأنت تخبر Git لتحريك المؤشر HEAD مرة أخرى مرة واحدة. ولكن (ما لم تستخدم - --hard ) تترك ملفاتك كما كانت. حتى الآن تظهر git status التغييرات التي قمت بتسجيلها في C. لم تفقد أي شيء!

للحصول على أخف لمسة ، يمكنك التراجع عن التزامك مع ترك ملفاتك index :

git reset --soft HEAD~1

هذا لا يترك ملفاتك بمفردها ، بل إنه يترك المؤشر وحده. عندما تقوم git status ، سترى أن الملفات نفسها موجودة في الفهرس كما كان من قبل. في الواقع ، بعد هذا الأمر مباشرة ، يمكنك القيام به في git commit وسوف تكون إعادة نفس الالتزام الذي قمت به للتو.

شيء آخر: لنفترض أنك قمت بتدمير التزام كما في المثال الأول ، ولكن بعد ذلك اكتشفت أنك بحاجة إليه بعد كل شيء ؟ حظًا صعبًا ، أليس كذلك؟

كلا ، لا يزال هناك طريقة لاستعادتها. اكتب git reflog (جزئي) الالتزام التي قمت git reflog . ابحث عن الالتزام الذي قمت بتدميره وقم بذلك:

git checkout -b someNewBranchName shaYouDestroyed

لقد قمت الآن بإحياء هذا الالتزام. في الواقع ، لا يتم القضاء على الالتزام في Git لمدة 90 يومًا ، لذا يمكنك عادةً الرجوع لإنقاذ شخص ما لا يعني التخلص منه.

Question

أنا commit بطريق الخطأ ملفات خاطئة إلى Git ، لكنني لم push على الخادم حتى الآن.

كيف يمكنني التراجع عن هذه الالتزامات من المستودع المحلي؟




أمر واحد:

git reset --soft 'HEAD^' 

إنه يعمل بشكل رائع للتراجع عن الالتزام المحلي الأخير!




أردت التراجع عن آخر 5 التزامات في مستودعنا المشترك. لقد بحثت عن معرّف المراجعة الذي أردت التراجع عنه. ثم كتبت في ما يلي.

prompt> git reset --hard 5a7404742c85
HEAD is now at 5a74047 Added one more page to catalogue
prompt> git push origin master --force
Total 0 (delta 0), reused 0 (delta 0)
remote: bb/acl: neoneye is allowed. accepted payload.
To git@bitbucket.org:thecompany/prometheus.git
 + 09a6480...5a74047 master -> master (forced update)
prompt>



طريق اخر:

تحقق من الفرع الذي تريد العودة إليه ، ثم أعد تعيين نسخة العمل المحلية الخاصة بك مرة أخرى إلى الالتزام الذي تريد أن يكون أحدث نسخة على الخادم البعيد (كل شيء بعد ذلك سيذهب إلى اللقاء). للقيام بذلك ، في SourceTree I بالنقر بزر الفأرة الأيمن على "إعادة تعيين BRANCHNAME لهذا الالتزام" وتحديدها.

ثم انتقل إلى الدليل المحلي لمستودع التخزين الخاص بك وقم بتشغيل هذا الأمر:

git -c diff.mnemonicprefix=false -c core.quotepath=false push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

سيؤدي هذا إلى محو جميع الإلتزامات بعد الحفظ الحالي في المستودع المحلي الخاص بك ولكن فقط من أجل ذلك الفرع.




فقط قم بإعادة ضبطه باستخدام الأمر أدناه باستخدام git :

git reset --soft HEAD~1

قم بشرح الآتي: ما هي git reset ، إنها في الأساس تتم reset إلى أي التزام تريد العودة إليه ، ثم إذا --soft مع مفتاح --soft ، --soft ، ولكن احتفظ بالتغييرات في ملفك (ملفاتك) ، لذلك ستعود إلى المرحلة التي تمت إضافة الملف إليها فقط ، HEAD هو رأس الفرع وإذا قمت بالدمج مع ~1 (في هذه الحالة يمكنك أيضًا استخدام HEAD^ ) ، فسيرجع مرة واحدة فقط إلى ما تريده. ..

أقوم بإنشاء الخطوات الواردة في الصورة أدناه بمزيد من التفاصيل ، بما في ذلك جميع الخطوات التي قد تحدث في المواقف الحقيقية وارتكاب الرمز:




إذا كنت ترغب في التراجع عن ذلك بشكل دائم وكنت قد استنسخت بعض المستودع

يمكن رؤية معرف الالتزام

git log 

ثم يمكنك القيام به -

git reset --hard <commit_id>

git push origin <branch_name> -f



لتغيير ارتكاب الماضي

استبدال الملفات في الفهرس:

git rm --cached *.class
git add *.java

ثم إذا كان فرعًا خاصًا ، فعدّل الالتزام:

git commit --amend

أو إذا كان فرعًا مشتركًا ، فقم بإجراء التزام جديد:

git commit -m 'Replace .class files with .java files'


( لتغيير التزام سابق ، استخدم rebase التفاعلية رهيبة)

ProTip ™: أضف *.class إلى gitignore لإيقاف هذا يحدث مرة أخرى.

لتكرار ارتكاب

يعد تعديل الالتزام هو الحل المثالي إذا كنت بحاجة إلى تغيير الالتزام الأخير ، ولكن يتم reset حل أكثر عمومية.

يمكنك إعادة تعيين git إلى أي التزام باستخدام:

git reset @~N

حيث N هو عدد الإلتزامات قبل HEAD ، و @~ يعيد تعيين إلى الالتزام السابق.

لذلك ، بدلاً من تعديل الالتزام ، يمكنك استخدام:

git reset @~
git add *.java
git commit -m "Add .java files"

تحقق من git help reset ، وتحديدا أقسام on - --soft --mixed و --mixed ، من أجل فهم أفضل لما يفعله هذا.

Reflog

إذا أخطأت ، يمكنك دائمًا استخدام السجل للعثور على طلبات الإلغاء:

$ git reset @~
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~
2c52489 HEAD@{1}: commit: added some .class files
$ git reset 2c52489
... and you're back where you started





إضافة / إزالة الملفات للحصول على الأشياء بالطريقة التي تريدها:

git rm classdir
git add sourcedir

ثم تعديل الالتزام:

git commit --amend

سيتم تعديل الالتزام السابق الخاطئ ليعكس حالة الفهرس الجديدة - بعبارة أخرى ، سيكون الأمر كما لو أنك لم ترتكب الخطأ أبداً في المقام الأول.

لاحظ أنه يجب عليك القيام بذلك فقط إذا لم تقم بالدفع بعد. إذا كنت قد دفعت ، فسوف يكون عليك فقط أن تلتزم الإصلاح بشكل طبيعي.




كيفية إصلاح الالتزام المحلي السابق

استخدم git-gui (أو ما شابه) لتنفيذ git commit --amend . من واجهة المستخدم الرسومية يمكنك إضافة أو إزالة الملفات الفردية من الالتزام. يمكنك أيضًا تعديل رسالة الالتزام.

كيفية التراجع عن الالتزام المحلي السابق

فقط إعادة تعيين الفرع الخاص بك إلى الموقع السابق (على سبيل المثال ، باستخدام gitk أو git rebase ). ثم أعد تطبيق التغييرات من نسخة محفوظة. بعد جمع القمامة في المستودع المحلي الخاص بك ، سيكون الأمر كما لو أن الالتزام غير المرغوب فيه لم يحدث أبدًا. للقيام بكل ذلك في أمر واحد ، استخدم git reset HEAD~1 .

كلمة تحذير : استخدام الإهمال من git reset هو وسيلة جيدة للحصول على نسخة العمل الخاصة بك في حالة مربكة. أوصي بأن يتجنب Git المبتدئين هذا إذا كان بإمكانهم ذلك.

كيفية التراجع عن التزام العامة

إجراء اختيار الكرز العكسي ( git-revert ) للتراجع عن التغييرات.

إذا لم تكن قد سحبت تغييرات أخرى على فرعك ، فيمكنك القيام بذلك ببساطة ...

git revert --no-edit HEAD

ثم ادفع الفرع المحدث الخاص بك إلى المستودع المشترك.

سيعرض سجل الالتزام كلا الالتزامين ، بشكل منفصل .

متقدم: تصحيح الفرع الخاص في المستودع العام

هذا يمكن أن يكون خطيرًا - تأكد من حصولك على نسخة محلية من الفرع للتوثيق.

لاحظ أيضًا: لا تريد القيام بذلك إذا كان شخص آخر قد يعمل على الفرع.

git push --delete (branch_name) ## remove public version of branch

تنظيف الفرع الخاص بك محليا ثم repush ...

git push origin (branch_name)

في الحالة العادية ، ربما لا داعي للقلق بشأن تاريخ ارتكاب فرعك الخاص. ما عليك سوى الضغط على الالتزام بالمتابعة (راجع "كيفية التراجع عن التزام عام" أعلاه) ، وبعد ذلك ، قم بعمل squash-merge لإخفاء السجل.




اكتب git log وابحث عن آخر رمز تجزئة للالتزام ثم أدخل:

git reset <the previous co>



"إعادة تعيين شجرة العمل إلى الالتزام الأخير"

git reset --hard HEAD^ 

"ملفات غير معروفة نظيفة من شجرة العمل"

git clean    

انظر - Git المرجع السريع

ملاحظة: سيحذف هذا الأمر التزامك السابق ، لذا استخدمه بحذر! git reset --hard - أكثر أمانًا -







بسيطة ، قم بتشغيل هذا في سطر الأوامر الخاص بك:

git reset --soft HEAD~ 



إذا كنت تخطط للتراجع عن التزام محلي تمامًا ، مهما كانت التغييرات التي قمت بها على الالتزام ، وإذا كنت لا تقلق أي شيء حيال ذلك ، فما عليك سوى القيام بالأمر التالي.

git reset --hard HEAD^1

(سيتجاهل هذا الأمر التزامك بالكامل وسيتم فقد التغييرات بالكامل من شجرة العمل المحلية). إذا كنت تريد التراجع عن التزامك ، لكنك تريد التغييرات الخاصة بك في منطقة التدريج (قبل الالتزام فقط بعد git add ) ، git add بإجراء الأمر التالي.

git reset --soft HEAD^1

الآن تأتي ملفاتك الملتزمة في منطقة التدريج. افترض إذا كنت تريد إلغاء تثبيت الملفات ، لأنك تحتاج إلى تحرير بعض conent خاطئة ، ثم قم بإجراء الأمر التالي

git reset HEAD

الملفات الملتزمة الآن تأتي من المنطقة المرحلي إلى المنطقة غير النظامية. الآن الملفات جاهزة للتحرير ، لذا مهما تغيرت ، فأنت تريد أن تذهب وتحررها وتضيف التزامًا جديدًا / جديدًا.

More




هناك نوعان من السيناريوهات الرئيسية

لم تقم بدفع الالتزام بعد

إذا كانت المشكلة عبارة عن ملفات إضافية تلتزم بها (ولا تريد تلك الموجودة بالمستودع) ، فيمكنك إزالتها باستخدام git rm ثم --amend مع --amend

git rm <pathToFile>

يمكنك أيضًا إزالة أدلة كاملة باستخدام -r أو حتى الدمج مع أوامر Bash الأخرى

git rm -r <pathToDirectory>
git rm $(find -name '*.class')

بعد إزالة الملفات ، يمكنك الالتزام ، مع خيار --amend

git commit --amend -C HEAD # the -C option is to use the same commit message

سيؤدي هذا إلى إعادة كتابة التزامك المحلي حديثًا بإزالة الملفات الإضافية ، لذلك ، لن يتم إرسال هذه الملفات أبدًا على الدُفعة وستتم إزالتها أيضًا من مستودع .git المحلي بواسطة GC.

لقد قمت بالفعل بدفع الالتزام

يمكنك تطبيق نفس الحل الخاص بالسيناريو الآخر ثم القيام git push مع الخيار -f ، ولكن لا يوصى به لأنه يقوم بالكتابة فوق السجل البعيد بتغير مختلف (يمكن أن يفسد المستودع الخاص بك).

بدلاً من ذلك ، يجب عليك تنفيذ الالتزام دون - --amend (تذكر ذلك about -amend`: يقوم هذا الخيار بإعادة كتابة السجل في الالتزام الأخير).




Related