سؤال

لطالما فكرت في git reset و git checkout كما هو الحال ، بمعنى أن كلاهما يعيد المشروع إلى التزام معين. ومع ذلك ، أشعر أنهم لا يمكن أن يكونوا متماثلين تمامًا ، لأن ذلك سيكون زائداً. ما هو الفرق الفعلي بين الاثنين؟ أنا مرتبك بعض الشيء ، كما أن SVN لديه فقط svn co لعودة الالتزام.

وأضاف

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

http://a.imageshack.us/img651/1559/86421927.png http://a.imageshack.us/img801/1986/resetr.png

وأضاف 3

من http://think-like-a-git.net/sections/rebase-from-the-ground up/using-git-cherry-pick-to-simulate-git-rebase.html, ، يمكن الخروج وإعادة ضبط محاكاة Rebase.

enter image description here

git checkout bar 
git reset --hard newbar 
git branch -d newbar 

enter image description here

هل كانت مفيدة؟

المحلول

  • git reset هو على وجه التحديد عن تحديث الفهرس, ، تحريك الرأس.
  • git checkout حول تحديث شجرة العمل (إلى الفهرس أو الشجرة المحددة). سيتم تحديث الرأس فقط إذا قمت بالخروج من فرع (إن لم يكن كذلك ، ينتهي بك الأمر بـ رأس منفصل).
    (في الواقع ، مع GIT 2.23 Q3 2019 ، سيكون هذا git restore, ، ليس بالضرورة git checkout)

بالمقارنة ، نظرًا لأن SVN ليس لديه فهرس ، فقط شجرة عاملة ، svn checkout سوف نسخ مراجعة معينة على دليل منفصل.
أقرب ما يعادل git checkout سيكون:

  • svn update (إذا كنت في نفس الفرع ، وهذا يعني عنوان URL SVN نفسه)
  • svn switch (إذا قمت بالخروج على سبيل المثال في نفس الفرع ، ولكن من عنوان URL آخر SVN REPO)

كل هؤلاء التعديلات الثلاثة العاملة (svn checkout, update, switch) لديك أمر واحد فقط في git: git checkout.
ولكن نظرًا لأن GIT لديها أيضًا فكرة الفهرس (هذا "منطقة التدريج" بين الريبو وشجرة العمل) ، لديك أيضًا git reset.


رقيقة يذكر في التعليقات المقالة "إعادة تعيين إزالة الغموض ".

على سبيل المثال ، إذا كان لدينا فرعين ، 'master' و 'develop"الإشارة إلى ارتباطات مختلفة ، ونحن حاليًا"develop'(لذلك يشير الرأس إلى ذلك) ونركضنا git reset master, 'develop"سوف يشير الآن إلى نفس الالتزام"master' يفعل.

من ناحية أخرى ، إذا ركضنا بدلاً من ذلك git checkout master, 'developلن يتحرك ، HEAD نفسها سوف. HEAD سوف تشير الآن إلى 'master'.

لذلك ، في كلتا الحالتين نتحرك HEAD للإشارة إلى الالتزام A, ، لكن كيف نفعل ذلك مختلف تمامًا. reset سوف يتحرك الفرع HEAD يشير إلى ، تحركات الخروج HEAD نفسها للإشارة إلى فرع آخر.

http://git-scm.com/images/reset/reset-checkout.png

على هذه النقاط ، على الرغم من:

لارس يضيف في التعليقات:

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

git checkout a839e8f updates HEAD to point to commit a839e8f.

من جديد تتفق في التعليقات:

larsh صحيح.
الرصاصة الثانية لديها مفهوم خاطئ حول ماهية الرأس سوف تحديث الرأس فقط إذا قمت بالخروج من فرع.
يذهب الرأس إلى أينما كنت ، مثل الظل.
إن التحقق من بعض المرجع غير المتصاعد (على سبيل المثال ، علامة) ، أو التزام مباشرة ، سوف ينتقل رأسه. لا يعني الرأس المنفصل أنك منفصل عن الرأس ، فهذا يعني أن الرأس منفصل عن المرجع الفرعي ، والذي يمكنك رؤيته ، على سبيل المثال ، git log --pretty=format:"%d" -1.

  • ستبدأ دول الرأس المرفقة بـ (HEAD ->,
  • سوف لا يزال منفصلة تظهر (HEAD, ، ولكن لن يكون لها سهم إلى فرع المرجع.

نصائح أخرى

في أبسط أشكالها ، reset أعد ضبط الفهرس دون لمس شجرة العمل ، بينما checkout يغير شجرة العمل دون لمس الفهرس.

إعادة تعيين الفهرس للمطابقة HEAD, ، تركت شجرة العمل بمفردها:

git reset

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

git checkout

بمجرد البدء في إضافة المعلمات ، يكون هناك بعض التداخل.

checkout عادة ما يستخدم مع فرع أو علامة أو الالتزام. في هذه الحالة ، سيتم إعادة تعيينها HEAD والمؤشر إلى الالتزام المحدد وكذلك إجراء الخروج من الفهرس في شجرة العمل.

أيضا ، إذا كنت تزود --hard إلى reset تستطيع أن تسأل reset للكتابة فوق شجرة العمل وكذلك إعادة تعيين الفهرس.

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

أشكال أخرى من reset و commit تنطوي على توفير المسارات.

إذا قمت بتزويد المسارات reset لا يمكنك توفير --hard و reset سوف يغير فقط إصدار الفهرس من المسارات الموردة إلى الإصدار في الالتزام المقدم (أو HEAD إذا لم تحدد التزام).

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

حالة استخدام بسيطة واحدة عند تغيير التغيير:
1. استخدم إعادة تعيين إذا كنت تريد التراجع عن تشغيل ملف معدّل.
2. استخدم الخروج إذا كنت ترغب في تجاهل التغييرات إلى ملف/s غير المنقوش.

أتلاسيان أعطنا شرحًا ممتازًا عن إعادة تعيين GIT, Git Checkout وهكذا، GIT يعود. في هذه المقالة ، تم شرح الاستخدامات المختلفة لهذه الأوامر على مستويات مختلفة - ملف ، لقطة مرحاة والالتزام.

https://www.atlassian.com/git/tutorials/resetting-checking--.reverting

الفرق الرئيسي في باخرة هو ذلك reset يحرك مرجع الفرع الحالي, ، في حين checkout لا (يتحرك الرأس).

كما يشرح كتاب Pro Git تحت إعادة تعيين إزالة الغموض,

الشيء الأول reset سوف تفعل هو نقل ما يشير إليه الرأس. هذا ليس هو نفسه تغيير الرأس نفسه (وهو ما checkout يفعل)؛ reset يحرك الفرع هذا الرأس يشير إلى. هذا يعني أنه إذا تم ضبط الرأس على master فرع (أي أنك حاليًا على master فرع) ، الجري git reset 9e5e6a4 سيبدأ بالعمل master يشير إلى 9e5e6a4. [تم اضافة التأكيدات

انظر أيضًا إجابة Vonc لـ مقتطفات نصية مفيدة للغاية من نفس المقالة ، التي لن أكررها هنا.

بالطبع هناك الكثير من التفاصيل حول الآثار checkout و reset يمكن أن يكون على الفهرس وشجرة العمل ، اعتمادًا على المعلمات المستخدمة. يمكن أن يكون هناك الكثير من أوجه التشابه والاختلاف بين الأوامر. لكن كما أراها ، فإن الاختلاف الأكثر أهمية هو ما إذا كانت تحرك طرف الفرع الحالي.

يختلف الأمران (إعادة ضبطهم والخروج) تمامًا.

checkout X ليس reset --hard X

إذا كان x اسم فرع ،checkout X سيغير الفرع الحالي أثناء reset --hard X سوف لن.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top