الدرس 30 · الاستعادة
التراجع والإعادة ولقطات الاستعادة في GitTree
تراجَع عن إيداع من شريط GitTree العلوي ثم أعده، وتعلّم ما يستطيع التطبيق التراجع عنه وما لا يستطيع، ومتى يرفض، ولماذا يحتفظ بلقطات الاستعادة.
- المستوى: متوسط
- قراءة 7 دقائق
- فيديو 6 دقائق
- آخر تحديث
- قبل هذا الدرس: إعادة التعيين: ناعمة ومختلطة وكاملة, العثور على إيداع ضائع بسجل المراجع (reflog)
حُفظ التقدّم في هذا المتصفح.
يحمّل التشغيل الفيديو من YouTube (وضع الخصوصية المحسّنة).
ما ستتعلمه
- أن تقرأ ما سيفعله التراجع أو الإعادة التاليان قبل أن تضغطهما.
- أن تتوقع أن التراجع عن إيداع يُبقي تغييراته مُجهَّزة، وأن الإعادة تستطيع إرجاع الإيداع.
- أن تعرف لماذا يرفض التطبيق تراجعًا أو إعادة: الفرع تحرك أو الملفات تغيرت أو تغيّر مستودع بعيد.
- أن تعرف ما لقطات الاستعادة وكيف تحذف القديمة منها عن قصد.
قبل البدء
أنت على private/undo-demo، وهو فرع من ناتج الدرس 18 (M) ومجلد عملك نظيف. ستنشئ ملاحظة صغيرة docs/signup-recovery.md وتودعها عبر GitTree، لأن التراجع في GitTree يعمل من الخطوات التي يسجّلها هو بنفسه. أما الإيداع في طرفية فشيء آخر ولا يدخل ذلك السجل.
كل شيء هنا محلي وضمن الخطة المجانية (يطلب GitTree تسجيل الدخول): دون حساب استضافة أو مزوّد أو إنترنت. كل الهويات خيالية (example.com). لا تنفّذ الدرس في مشروع حقيقي.
نفّذ التغييرات في GitTree أو بأوامر Git الأصلية، لا بالطريقتين في النسخة نفسها. القراءة بعد التنفيذ آمنة دائمًا. تسميات القوائم والتلميحات والإشعارات مأخوذة من نصوص GitTree 2.0 وشيفرته. وشُغّلت الأوامر الأصلية بـ Git 2.43 في نسخ مؤقتة وهي تعرض نموذج Git فقط، لا سجل التطبيق. لم تُشغَّل خطوات GitTree على macOS أو Windows أو Linux.
الفكرة وأثر الأفعال
يحتفظ GitTree بـسجل عمليات للخطوات التي ينفّذها. يعكس التراجع أحدث خطوة وتكرر الإعادة الخطوة التي تُراجع عنها أخيرًا. تسمّي تلميحة الشريط العلوي الخطوة، مثل «تراجع: الإيداع …». اقرأها أولًا: إن سمّت شيئًا غير الذي تتوقعه فتوقف.
قبل خطوة مدمّرة يحفظ GitTree لقطة استعادة تحت refs/ogt/trash/* ويكتب مدخل السجل. ويستعيد التراجع من ذلك السجل، وبشرط ألا يتغير شيء منذ ذلك: لا يُرجَع فرع إلا إن كان ما زال يشير إلى حيث تركته الخطوة، ولا تُستعاد ملفات إلا إن لم يعدّلها أحد بعد ذلك. وإلا رُفض التراجع مع سبب، وبقيت اللقطة محفوظة.
التراجع عن إيداع يُرجع الفرع ويُبقي التغييرات المودَعة مُجهَّزة، فلا يضيع شيء. وإعادة ذلك الإيداع تحرّك الفرع إلى الأمام مرة أخرى إلى الإيداع نفسه. لا تُعاد كل خطوة، وبعضها لا يمكن التراجع عنه: الدفع القسري غيّر مستودعًا بعيدًا («ادفع مجددًا لإرجاعه»)، والمخبأ المحذوف محفوظ لقطةً لكن لا يُتراجع عنه بعد، والإيداع الأول لا حالة سابقة له. والخطوة التي توقفت في منتصفها لا نتيجة كاملة للتراجع عنها.
لا تُحذف اللقطات وفق جدول. الأمر حذف لقطات الاستعادة القديمة… يتيح لك اختيار عمر، ويعرض بالضبط اللقطات الأقدم، ولا يحذف إلا تلك بعد أن تؤكد. وحذف لقطة يزيل طريق العودة لتلك الخطوة.
يغيّر التراجع والإعادة المستودع المحلي فقط. ولا يُنشر شيء.
إعداد حالة المشروع المحددة
ابدأ من نسخة عادية منفصلة من ناتج الدرس 18 (M) تثق بها وأبقِ أصلك دون مساس. أنشئ الفرع واصنع الملاحظة. محتوى الملاحظة هو DOC_LOST.
مدخلات الملفات كاملة
احفظ في المرحلة المحددة فقط بصيغة UTF-8 وLF وسطر نهائي. لا تلصق أسوار Markdown. ترث الملفات الثابتة نقطة البداية؛ لا تستبدل الأصل بنسخة إعادة منفصلة.
docs/signup-recovery.md — DOC_LOST
# Recovered signup work
Keep a branch name before leaving useful experimental work.في GitTree
افتح لوحة الأوامر بـ Command+Shift+P (وCtrl+Shift+P على Ubuntu). تراجع وإعادة في الشريط العلوي وفي لوحة الأوامر؛ والاختصاران Command+Z للتراجع وCommand+Shift+Z أو Command+Y للإعادة (Ctrl على Windows وLinux).
- في نسخة منفصلة أنشئ الفرع
private/undo-demoواحفظ DOC_LOST باسمdocs/signup-recovery.md. افتح قائمة التغييرات: الملف جديد. - جهّز هذا الملف وحده وأودِعه بالملخّص
docs: demonstrate a reversible local commit. انتظر النتيجة الفعلية. - مرّر المؤشر على تراجع (Undo) في الشريط العلوي. تقول التلميحة «تراجع: الإيداع …». إن سمّت خطوة أخرى فتوقف: لا تتراجع عن شيء لم تقصده.
- اختر تراجع مرة واحدة. يقول الإشعار «تم التراجع عن: الإيداع.» عاد الفرع إلى M والملاحظة مُجهَّزة لا محذوفة.
- مرّر المؤشر على إعادة (Redo). تقول التلميحة «إعادة: الإيداع …». اختر إعادة مرة واحدة. يقول الإشعار «تمت إعادة: الإيداع.» عاد الإيداع ومجلد العمل نظيف.
- نسخة الحالة القديمة المنفصلة. في نسخة ثانية كرّر الخطوات من 1 إلى 4، ثم أودِع الملاحظة المجهَّزة خارج GitTree بالأمر
git commit -m "docs: external move after app undo". انظر إلى إعادة: هي معطَّلة وسببها «تحرّك الفرع منذ ذلك الحين؛ التراجع سيستبدل ذلك التغيير.» لا تفرضها. - افتح لوحة الأوامر ونفّذ حذف لقطات الاستعادة القديمة… (Delete Old Recovery Snapshots…). اترك أقدم من (بالأيام) على 30 واختر بحث (Find). اقرأ ما تقوله القائمة: إما «لا توجد لقطات بهذا القِدم.» أو قائمة بالقديمة. أغلق الحوار؛ ولا تحذف شيئًا لتنهي الدرس.
لكل إيداع عادي في الدورة: الملخّص (Summary) هو العنوان المحدد، والوصف (Description) خالٍ، وتبقى الخيارات تعديل الإيداع الأخير وتخطّي الخطّافات وإضافة Signed-off-by ومؤلف مختلف والدفع بعد الإيداع والسماح بإيداع فارغ معطّلة.
في الطرفية
لا تستخدم الطرفية سجل التطبيق. هذا نموذج Git العادي لما يفعله التراجع عن إيداع، في نسخة مختلفة ونظيفة من ناتج الدرس 18:
git switch --create private/undo-demo
BEFORE_SHA="$(git rev-parse HEAD)"احفظ DOC_LOST باسم docs/signup-recovery.md ثم:
git add -- docs/signup-recovery.md
git commit --quiet -m "docs: demonstrate a reversible local commit"
AFTER_SHA="$(git rev-parse HEAD)"
git reset --soft "$BEFORE_SHA"
git status --shortA docs/signup-recovery.mdعاد الفرع والملف مُجهَّز. والتقدم مرة أخرى:
git reset --soft "$AFTER_SHA"
git status --shortالحالة خالية. هذه الأوامر لا تستدعي تراجع التطبيق ولا إعادته، ولا تسجّل مدخلًا في سجل GitTree، ولا تنشئ لقطة؛ وgit for-each-ref refs/ogt/trash لا يطبع شيئًا في هذه النسخة. وفي نسخة أنشأها التطبيق يسرد أسماء اللقطات الحقيقية، وتقرؤها دون تغييرها.
والحارس ضد خطوة قديمة هو المقارنة والمبادلة (compare-and-swap). ولدى Git الفكرة نفسها في update-ref الذي لا يحرّك مرجعًا إلا إن كان ما زال يحمل القيمة التي تتوقعها. بعد إيداع خارجي:
git update-ref refs/heads/private/undo-demo "$AFTER_SHA" "$BEFORE_SHA"يرفض Git بعبارة «cannot lock ref … is at … but expected …». أما رفض GitTree فهو ما في التلميحة: «تحرّك الفرع منذ ذلك الحين؛ التراجع سيستبدل ذلك التغيير.»
النتيجة
أين تنتهي: في النسخة الأولى أُودعت الملاحظة ثم تُراجع عنها (مُجهَّزة والفرع على M) ثم أُعيدت (الفرع على الإيداع والمجلد نظيف). وفي نسخة الحالة القديمة رُفضت الإعادة لأن الفرع تحرك، وبقي الإيداع الخارجي سليمًا. وفتحت حوار اللقطات وأغلقته دون حذف شيء.
أخطاء شائعة
- الضغط على تراجع دون قراءة التلميحة، والتراجع عن خطوة لم تقصدها.
- افتراض أن كل فعل يمكن التراجع عنه أو إعادته: الدفع القسري والمخبأ المحذوف لا، ومعظم الخطوات بلا إعادة.
- توقع أن يغطي التراجع تعديلات أجريتها في محرر خارج GitTree.
- حذف اللقطات القديمة للترتيب، فتزيل طريق العودة.
إن حدث خطأ
إن كان التراجع معطَّلًا فاقرأ السبب في التلميحة: تحرك الفرع، أو عُدّلت الملفات منذ ذلك الحين، أو تغيّر مستودع بعيد، أو لا شيء للتراجع عنه. وإن رُفضت خطوة فلقطة استعادتها محفوظة تحت refs/ogt/trash/*؛ لا تحذفها وأنت غير متأكد. أما الإيداعات التي أُجريت خارج GitTree فاستخدم لها سجل المراجع من الدرس 29.
اختبر فهمك
أجب عن كل سؤال ثم اقرأ السبب. الأسئلة المعلَّمة «مطلوب» تُحتسب لإكمال الدرس.
0 من 6 صحيحة
أجب عن الأسئلة المطلوبة إجابة صحيحة لتكمل الدرس.
جرى التحقق في هذا المتصفح.
تدريب
اكتب ما قالته تلميحة التراجع، وكيف بدت قائمة المُجهَّز والفرع بعد التراجع، وماذا فعلت الإعادة. وفي النسخة القديمة اكتب السبب الذي أعطته الإعادة. ثم سمِّ خطوة واحدة لا يستطيع التطبيق التراجع عنها وقل لماذا.
تأكيد منك أنت: لا يستطيع الموقع رؤية جهازك.
لإكمال الدرس، أجب عن الأسئلة المطلوبة إجابة صحيحة وأكّد تنفيذ التمرين العملي.
خلاصة
- اقرأ التلميحة قبل أن تضغط.
- التراجع عن إيداع يُبقي تغييراته مُجهَّزة.
- فرع تحرك أو ملفات عُدّلت تجعل التراجع يرفض؛ واللقطات محفوظة.
ذو صلة
المصطلحات الجديدة
Undo — تراجع; Redo — إعادة; journal — سجل العمليات; recovery snapshot — لقطة استعادة.
نص الفيديو
ترجمة التعليق الصوتي الإنجليزي للفيديو، مقطعًا بعد مقطع.
اعرض النص
- يستطيع GitTree إرجاع بعض الخطوات. إليك الكيفية، وأين يتوقف.
- يحتفظ GitTree بسجل لخطواته. يعكس التراجع أحدثها.
- قبل خطوة خطرة يحفظ لقطة استعادة أولًا.
- لدينا فرع وملاحظة جديدة.
- جهّز هذا الملف وحده.
- اكتب الملخّص. وتبقى كل الخيارات معطّلة.
- أودِع مرة واحدة، في GitTree نفسه.
- الإيداع في الطرفية ليس في هذا السجل.
- مرّر على التراجع. تسمّي التلميحة الخطوة: إيداع.
- إن سمّت شيئًا آخر فتوقف.
- اختر التراجع مرة واحدة. يقول الإشعار تم التراجع عن الإيداع.
- الفرع عاد إلى M.
- والملاحظة مُجهَّزة لا محذوفة. لم يضع شيء.
- الآن تسمّي الإعادة الإيداع نفسه.
- اختر الإعادة مرة واحدة. عاد الإيداع.
- مجلد العمل نظيف من جديد.
- في نسخة ثانية نودِع ونتراجع بالطريقة نفسها.
- الآن أودِع الملاحظة المجهَّزة خارج GitTree.
- الإعادة معطَّلة. الفرع تحرك منذ ذلك الحين.
- يترك إيداعك وشأنه. لا تفرضها أبدًا.
- أسباب أخرى: ملفات عُدّلت، ومستودع بعيد تغيّر، والإيداع الأول.
- الآن اللقطات. نفّذ حذف لقطات الاستعادة القديمة.
- يقول إن اللقطات المدرجة وحدها تُحذف.
- اترك ثلاثين يومًا واختر بحث.
- أغلقه. لا شيء ينتهي من تلقاء نفسه.
- في نسخة Git عادية تعطي إعادة ناعمة الشكل نفسه.
- إلى الأمام مرة أخرى، المجلد نظيف، ولا لقطة من التطبيق.
- يحرس Git المرجع بالطريقة نفسها: لا تحرّكه إلا إن حمل ما تتوقعه.
- التراجع ليس إعادة لف شاملة. يعكس خطوات سجّلها التطبيق.
- تدريب: اكتب التلميحة ونتيجة التراجع والإعادة وسبب الرفض.
- التالي: ماذا يعني HEAD المنفصل.