في هذا الدرس 6تصفّح المواضيع
بينما يتراجع الأمر git revert عن التعديلات عبر إضافة التزام عكسي جديد للأمام، يعمل الأمر git reset عبر إرجاع المؤشر الحالي HEAD إلى التزام سابق في سجلك المحلي. ولفهم آلية عمله بدقة، يجب استحضار المناطق الثلاث في Git:
- 1. مؤشر الالتزام الحالي (HEAD): اللقطة المسجلة التي يشير إليها آخر التزام في السجل.
- 2. منطقة التجهيز (Staging Index): اللقطة المقترحة للالتزام القادم بعد تنفيذ
git add. - 3. مجلد العمل (Working Directory): الملفات الفعلية التي تحررها مباشرة على القرص.
git log --oneline -n 3
# c3d4e5f feat: add contact section
# a1b2c3d feat: add hero banner
# 9f8e7d6 Initial commit
git status -s
يتوقف الأمر git reset --soft <commit> عند الخطوة الأولى فقط؛ إذ يحرك المؤشر HEAD إلى الالتزام الهدف، لكنه يترك كلاً من منطقة التجهيز ومجلد العمل دون أي مساس.
تبقى جميع التعديلات التي كانت ضمن الالتزامات الملغاة مجهزة باللون الأخضر وجاهزة للحفظ من جديد. ويُستخدم الخيار --soft بكثرة لدمج عدة التزامات تجريبية صغيرة في التزام ذري واحد نظيف ومرتب.
# Move HEAD back 2 commits while keeping changes staged
git reset --soft HEAD~2
git status -s
# M index.html
git commit -m "feat: build complete landing header"
عند تنفيذ الأمر git reset دون تمرير أي خيار (أو بكتابة --mixed صراحةً)، ينفذ Git خطوتين: يحرك المؤشر HEAD إلى الالتزام الهدف، ويفرغ منطقة التجهيز لتطابق ذلك الالتزام، بينما يترك ملفات مجلد العمل سليمة تماماً على القرص.
وبذلك تبقى تعديلات الالتزام الملغى موجودة داخل ملفاتك كتعديلات غير مجهزة، مما يتيح لك مراجعتها بالأمر git diff وتجهيز ما تريده منها انتقائياً عبر git add.
# Undo last commit and unstage its changes (default --mixed)
git reset HEAD~1
git status -s
# M index.html
git diff index.html
يمتد تأثير الأمر git reset --hard <commit> ليشمل المناطق الثلاث دفعة واحدة؛ فهو يرجع المؤشر HEAD للخلف، ويعيد ضبط منطقة التجهيز، ويستبدل جميع الملفات المتتبعة في مجلد العمل لتطابق الالتزام الهدف تماماً.
ونظراً لأن الخيار --hard يمسح نهائياً أي تعديلات محلية في مجلد العمل أو منطقة التجهيز لم يسبق حفظها في التزام، يجب دائماً فحص git status بحذر قبل تنفيذه.
# Verify status before running a destructive reset
git status -s
# Reset HEAD, Staging Index, and Working Tree to HEAD~1
git reset --hard HEAD~1
git status -s
ماذا لو نفذت الأمر git reset --hard HEAD~1 ثم أدركت فوراً أنك بحاجة ماسة إلى الالتزام الذي حذفته؟ طالما أن الكود قد حُفظ في التزام محلي سابق، فإن Git يوفر صندوقاً أسود يسجل كافة الحركات يُسمى السجل المرجعي (git reflog).
ففي كل مرة يتحرك فيها المؤشر HEAD بسبب التزام أو تعديل أو إعادة ضبط، يوثق Git تلك الحركة بالترتيب تحت الرموز HEAD@{0} ثم HEAD@{1}. وبمجرد نسخ بصمة الالتزام المفقود من مخرجات git reflog وتمريرها إلى git reset --hard <hash>، يعود الالتزام المحذوف كاملاً.
# Inspect local reference movement history
git reflog -n 4
# 9f8e7d6 HEAD@{0}: reset: moving to HEAD~1
# c3d4e5f HEAD@{1}: commit: feat: add contact section
# Rescue the lost commit using its SHA-1 or HEAD@{1}
git reset --hard c3d4e5f
راجع جدول المقارنة الشامل التالي لاختيار وضع git reset أو أمر التراجع الأنسب لكل موقف برمجي:
| الأمر / الوضع | المؤشر HEAD | منطقة التجهيز Index | مجلد العمل Working Tree | أفضل حالة استخدام |
|---|---|---|---|---|
git reset --soft | يرجع للالتزام الهدف | تبقى مجهزة كما هي | يبقى سليماً دون تغيير | دمج عدة التزامات محلية حديثة في التزام واحد |
git reset --mixed | يرجع للالتزام الهدف | تُعاد لحالة الهدف | يبقى سليماً (غير مجهز) | إلغاء آخر التزام وإعادة تجهيز الملفات انتقائياً |
git reset --hard | يرجع للالتزام الهدف | تُعاد لحالة الهدف | يُستبدل بالكامل لحالة الهدف | التخلص التام من الالتزامات والتعديلات المحلية |
git revert <hash> | يتقدم بالتزام عكسي جديد | نظيفة | يُحدَّث بأمان | عكس التزام سابق دون مسح التاريخ |
git restore <file> | لا يتغير | لا تتغير (إلا مع --staged) | يستعيد ملفاً محدداً | التراجع عن تعديلات ملف واحد دون المساس بالسجل |
git reflog | فحص قراءة فقط | لا تتغير | لا يتغير | العثور على بصمة التزام مفقود بعد إعادة الضبط |
ملخص الدرس
حصاد الدرسمراجعة مركّزة لأهم المفاهيم والقواعد الهندسية التي أتقنتها في هذا الدرس قبل التطبيق العملي
ماذا تعلّمت في هذا الدرس؟
أتقنت في هذا الدرس كيف يحرك الأمر git reset المؤشر HEAD ويؤثر في المناطق الثلاث عبر الأوضاع --soft لدمج الالتزامات، و--mixed الافتراضي لإلغاء التجهيز، و--hard لاستبدال شجرة العمل، كما تدربت على إنقاذ الالتزامات المفقودة عبر git reflog. الخطوة التالية: انتقل الآن إلى الدرس 19 «التخزين المؤقت للتعديلات غير المكتملة عبر الأمر git stash» لحفظ العمل قيد التنفيذ مؤقتاً دون الحاجة لإنشاء التزام.
سجّل الدخول لحفظ تقدمك
تابع إنجاز المواضيع والمصطلحات والمهام، وكمّل من آخر خطوة على أي جهاز.
المصطلحات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 git reset --soft الوضع الناعم --soft
- وضع يعيد المؤشر HEAD إلى التزام سابق مع إبقاء كافة تعديلات الالتزامات الملغاة مجهزة في Index.
- للمراجعة
- 02 git reset --mixed الوضع المختلط --mixed
- الوضع الافتراضي لأمر إعادة الضبط؛ يحرك HEAD ويفرغ منطقة التجهيز مع إبقاء التعديلات في مجلد العمل.
- للمراجعة
- 03 git reset --hard الوضع الصارم --hard
- وضع يعيد ضبط المؤشر ومنطقة التجهيز ويستبدل الملفات المتتبعة في مجلد العمل مما يمسح التعديلات غير المحفوظة.
- للمراجعة
- 04 Reference Log (git reflog) السجل المرجعي git reflog
- سجل محلي زمني يوثق كل حركة للمؤشر HEAD تحت الرمز HEAD@{n} ويتيح استعادة الالتزامات التي اختفت من السجل.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
الاختصارات4
راجع المعنى، اشرحه لنفسك، ثم علّم البطاقة كمفهومة.
- 01 HEAD HEAD
- Current Commit Reference Pointer
- المؤشر المرجعي الذي يحدد لقطة الالتزام النشطة حالياً في المستودع المحلي.
- للمراجعة
- 02 SHA-1 SHA-1
- Secure Hash Algorithm 1
- البصمة التشفيرية السداسية عشرية التي تميز كل التزام في السجل والسجل المرجعي.
- للمراجعة
- 03 WIP WIP
- Work In Progress
- التزامات مرحلية مؤقتة قيد التنفيذ غالباً ما يتم دمجها في التزام واحد عبر git reset --soft.
- للمراجعة
- 04 GC GC
- Garbage Collection
- آلية التنظيف الداخلي في Git التي تزيل الكائنات غير المرتبطة بعد انتهاء مهلة الاحتفاظ بها في reflog.
- للمراجعة
لا توجد بطاقات تطابق البحث والتصفية.
اقرأ البطاقات بحرية. سجّل الدخول لحفظ تقدم مراجعتك.
مهامك قبل الاختبار
خطوة صغيرة كل مرة. وإنجاز تقدر ترجع له.
-
نفّذ الأمر git reset --soft HEAD~2 في مستودع تجريبي، وتحقق بالأمر git status -s من بقاء التعديلات مجهزة ثم احفظها بالتزام موحد.
-
استعرض سجل الحركات عبر git reflog -n 4 بعد إعادة الضبط، وانسخ بصمة الالتزام المفقود واستعده بالأمر git reset --hard.
تأشير المهمة إقرار منك بإتمامها، وليس تصحيحًا آليًا للكود. يُحفظ تقدمك في حسابك.
اختبر فهمك.
ووصلها للإتقان.
كل سؤال خطوة لقدّام. اختار، اكتب كود، وشوف نتيجتك فورًا.
أكمل المهام، واجمع كل الإجابات الصحيحة. أقل من 100%؟ راجع وأعد المحاولة.
الأسئلة متاحة للاطلاع. سجّل الدخول للتفاعل وحفظ تقدمك.
لمحة عن التحدي10 أسئلة تنتظرك +
ما الوضع الافتراضي الذي يعمل به الأمر "git reset HEAD~1" عند عدم تحديد أي راية؟
يعمل الأمر git reset افتراضياً بالوضع --mixed الذي يحرك المؤشر ويفرغ منطقة التجهيز مع الحفاظ على ملفات العمل.
ماذا يحدث لتعديلات الالتزام الملغى عند تنفيذ الأمر "git reset --soft HEAD~1"؟
يحرك الخيار --soft المؤشر HEAD للخلف ويبقي جميع تعديلات الالتزام الملغى مجهزة في منطقة Index.
أي وضع من أوضاع git reset يستبدل الملفات المتتبعة في مجلد العمل بالإضافة لإعادة ضبط المؤشر ومنطقة التجهيز؟
يمسح الوضع --hard التعديلات من المناطق الثلاث: المؤشر HEAD ومنطقة التجهيز ومجلد العمل.
يمثل تنفيذ "git reset --soft HEAD~2" متبوعاً بـ "git commit -m" طريقة نظيفة لدمج آخر التزامين محليين في التزام واحد.
صواب؛ لأن --soft يبقي تعديلات الالتزامين مجهزة في الفهرس، فيجمعها الالتزام الجديد في لقطة واحدة.
أي أمر يعرض السجل الزمني لكافة حركات المؤشر HEAD المحلية لتمكينك من استعادة التزام فُقد بعد "git reset --hard"؟
يعرض الأمر git reflog جميع تنقلات المؤشر HEAD المحلية مع البصمة الرقمية لكل التزام لاستعادته.
يمكن دائماً استرجاع التعديلات غير المحفوظة في أي التزام سابق عبر git reflog بعد مسحها بالأمر "git reset --hard".
خطأ؛ فالسجل المرجعي git reflog يوثق الالتزامات فقط، أما التعديلات التي لم تُحفظ في التزام فتمسح نهائياً مع --hard.
بعد تنفيذ الأمر "git reset HEAD~1" بالوضع الافتراضي، أين تستقر تعديلات الالتزام الذي تم التراجع عنه؟
في الوضع الافتراضي --mixed يُلغى تجهيز التعديلات لكنها تبقى محفوظة داخل ملفات مجلد العمل كـتعديلات غير مجهزة.
في مخرجات الأمر git reflog، إلى ماذا يشير الرمز المرجعي "HEAD@{1}"؟
يشير HEAD@{0} للموضع الحالي، بينما يشير HEAD@{1} إلى الموضع الذي كان عليه المؤشر HEAD قبل الحركة الأخيرة مباشرة.
يُحفظ السجل المرجعي (git reflog) حصرياً داخل مجلد .git/logs/ المحلي على جهازك.
صواب؛ فبيانات git reflog محلية تماماً وتُخزن داخل مجلد .git/logs/ على جهاز المطور فقط.
أي أمر يتراجع عن التزام سابق عبر إنشاء التزام عكسي جديد بدلاً من إرجاع المؤشر HEAD للخلف؟
ينشئ الأمر git revert التزاماً عكسياً جديداً يلغي أثر الالتزام السابق دون مسح السجل.