ما الفرق بين "إعادة تعيين GIT" و "Git Checkout"؟
-
30-09-2019 - |
سؤال
لطالما فكرت في git reset
و git checkout
كما هو الحال ، بمعنى أن كلاهما يعيد المشروع إلى التزام معين. ومع ذلك ، أشعر أنهم لا يمكن أن يكونوا متماثلين تمامًا ، لأن ذلك سيكون زائداً. ما هو الفرق الفعلي بين الاثنين؟ أنا مرتبك بعض الشيء ، كما أن SVN لديه فقط svn co
لعودة الالتزام.
وأضاف
أوضح فونك وتشارلز الاختلافات بين git reset
و git checkout
حقا جيدا. فهمي الحالي هو ذلك git reset
يعود كل التغييرات إلى التزام معين ، في حين git checkout
أكثر أو أقل يستعد لفرع. لقد وجدت أن المخططين التاليين مفيدة للغاية في الوصول إلى هذا الفهم:
وأضاف 3
من http://think-like-a-git.net/sections/rebase-from-the-ground up/using-git-cherry-pick-to-simulate-git-rebase.html, ، يمكن الخروج وإعادة ضبط محاكاة Rebase.
git checkout bar
git reset --hard newbar
git branch -d newbar
المحلول
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
نفسها للإشارة إلى فرع آخر.
على هذه النقاط ، على الرغم من:
لارس يضيف في التعليقات:
الفقرة الأولى من هذه الإجابة ، رغم ذلك ، مضللة: "
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
سوف لن.