الدرس 24 · الاستعادة
المتابعة أو التخطّي أو الإيقاف لعملية متوقفة
حين يتوقف دمج أو إعادة تأسيس فأمامك ثلاثة مخارج: متابعة أو تخطّي أو إيقاف. تعلّم أيها يناسب الحالة، وما الذي يضيّعه كل منها، وكيف تفحص المستودع بعد ذلك.
- المستوى: متوسط
- قراءة 11 دقيقة
- فيديو 7 دقائق
- آخر تحديث
- قبل هذا الدرس: حلّ تعارضات الدمج وإعادة التأسيس
حُفظ التقدّم في هذا المتصفح.
يحمّل التشغيل الفيديو من YouTube (وضع الخصوصية المحسّنة).
ما ستتعلمه
- أن تعرف أي عملية جارية قبل أن تلمس شيئًا.
- أن تتابع فقط بعد حلّ كل التعارضات وتعليمها.
- أن تشرح ما يتركه التخطّي خارج الناتج ومتى يكون الأداة الخطأ.
- أن توقف عملية وتتأكد أنك عدت إلى البداية.
قبل البدء
تستخدم التباعد من الدرس 23: conflict/sara (عنوان سارة «Review changes with confidence.») وconflict/omar (عنوان عمر «Understand each saved change.»)، وكلاهما من الإيداع M. اصنع منه ثلاث نسخ نظيفة اسمها gittree-continue وgittree-abort وgittree-skip. في كل منها conflict/sara محدَّد ولا شيء جارٍ. ستوقف العملية نفسها في النسخ الثلاث وتترك كل واحدة بطريقة مختلفة.
كل شيء هنا محلي وضمن الخطة المجانية (يطلب GitTree تسجيل الدخول): دون حساب استضافة أو مزوّد أو إنترنت. كل الهويات خيالية (example.com). لا تنفّذ الدرس في مشروع حقيقي.
نفّذ التغييرات في GitTree أو بأوامر Git الأصلية، لا بالطريقتين في النسخة نفسها. القراءة بعد التنفيذ آمنة دائمًا. تسميات القوائم مأخوذة من نصوص GitTree 2.0 نفسها، وشُغّلت الأوامر الأصلية بـ Git 2.43 في نسخ مؤقتة. لم تُشغَّل خطوات GitTree على macOS أو Windows أو Linux.
الفكرة وأثر الأفعال
العملية المتوقفة حالة قائمة بذاتها. ما دامت لم تنتهِ يتذكر المستودع ما كان يفعله، ويجب ألا تبدأ دمجًا أو إعادة تأسيس أخرى فوقها. اعرف أولًا ما الجاري. يقولها شريط GitTree صراحة: «جارٍ دمج … في …» أو «جارٍ إعادة تأسيس … على …» (مع رقم الخطوة حين تتعدد)، وعدد التعارضات المتبقية. وفي الطرفية يبدأ git status بعبارة «You have unmerged paths» وتلميح للدمج، أو «interactive rebase in progress; onto …» لإعادة التأسيس، ثم يسرد الأوامر التي يمكنك استخدامها.
المتابعة تكمل بعد أن يُحَلّ كل تعارض وتُجهَّز نتيجته. ليست إعادة محاولة للدمج أو إعادة التأسيس الأصلية: تنهي إيداع الدمج، أو تنقل إعادة التأسيس إلى إيداعها التالي.
التخطّي موجود للعمليات التي تعيد تطبيق إيداعات، كإعادة التأسيس. يترك تغيير الإيداع الحالي خارج الناتج كليًا. في هذا الدرس يُسقط التخطّي عنوان سارة وينتهي الفرع عند إيداع عمر. ليس طريقة «لقبول الملف» ولا لتأجيل التعارض، وهو الأداة الخطأ كلما أردت هذا التغيير. وليس للدمج تخطٍّ لأن الدمج خطوة واحدة: إما تنهيه أو توقفه.
الإيقاف يعود إلى حيث بدأت العملية. يسقط كل ما حللته حتى الآن. يحفظ GitTree أولًا لقطة استعادة لما يسقطه، ويعود المستودع إلى الإيداع والفهرس والملفات التي كانت قبل العملية بالضبط. هو المخرج حين لا تكون متأكدًا مما تفعله.
| الاختيار | النتيجة | الثمن |
|---|---|---|
| المتابعة | يُنشأ إيداع الدمج، أو يُعاد تطبيق الإيداع التالي | لا شيء، متى حُلّ كل شيء |
| التخطّي | يُترك تغيير الإيداع الحالي خارج الناتج | ذلك التغيير، حتى تجده من جديد |
| الإيقاف | يعود المستودع إلى البداية | العمل المنجز أثناء العملية |
إعداد حالة المشروع المحددة
ابنِ فرعي سارة وعمر مرة واحدة ثم اصنع ثلاث نسخ. ابدأ من نسخة عادية منفصلة من المشروع كما تركه الدرس 18، وأبقِ gittree-features الأصلي دون مساس. نسخ الصفحة: MERGED هو الأساس المشترك، وSARA وOMAR النسختان المتنافستان، وRESOLVED النتيجة التي تحفظها في نسخة المتابعة.
مدخلات الملفات كاملة
احفظ في المرحلة المحددة فقط بصيغة UTF-8 وLF وسطر نهائي. لا تلصق أسوار Markdown. ترث الملفات الثابتة نقطة البداية؛ لا تستبدل الأصل بنسخة إعادة منفصلة.
index.html — MERGED
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">See your work clearly.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>index.html — SARA
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">Review changes with confidence.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>index.html — OMAR
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">Understand each saved change.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>index.html — RESOLVED
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">Review each change with confidence.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>في GitTree
افتح لوحة الأوامر بـ Command+Shift+P (وCtrl+Shift+P على Ubuntu). تستخدم أفعال الفرع المسمّى قائمة النقر بزر الفأرة الأيمن على صفه.
- ابنِ النسخ الثلاث كما يبيّن القسم التالي. في كل منها
conflict/saraمحدَّد والحالة خالية. دوّن المعرّف الكامل لـconflict/saraفي نسخة الإيقاف. - نسخة المتابعة. افتح gittree-continue. انقر
conflict/omarبزر الفأرة الأيمن واختر دمج conflict/omar في conflict/sara (Merge conflict/omar into conflict/sara) مع إيداع دمج دائمًا (Always a merge commit). يتوقف. على الشريط اختر حلّ (Resolve) وافتحindex.htmlواختر تحرير النتيجة (Edit Output) واكتبReview each change with confidence.ثم اختر حفظ وتعليم كمحلول (Save and Mark Resolved). - تأكد أنه لم يبقَ تعارض، ثم اختر متابعة (Continue) على الشريط مرة واحدة. يقول الإشعار «تم.» ويختفي الشريط. للإيداع الجديد أبوان.
- نسخة الإيقاف. افتح gittree-abort وابدأ الدمج نفسه. اترك التعارض دون حل. على الشريط اختر إيقاف… (Abort…). يشرح الحوار «إيقاف العملية؟» أن الفرع والفهرس والملفات تعود إلى ما كانت عليه وأن ما يُسقَط يُحفظ أولًا في لقطات الاستعادة. اختر إيقاف (Abort). يقول الإشعار «تم الإيقاف. التغيير الذي أسقطه محفوظ تحت refs/ogt/trash/…؛ والتراجع يعيده.» (وإن لم يُسقط الإيقاف شيئًا قال «تم الإيقاف. عاد المستودع إلى ما كان عليه من قبل.»)
- افحص الإيقاف:
conflict/saraما زال المعرّف الذي دوّنته، والصفحة هي عنوان سارة كاملًا، ولا شريط ظاهرًا. - نسخة التخطّي. افتح gittree-skip. انقر
conflict/omarبزر الفأرة الأيمن واختر إعادة تأسيس conflict/sara على conflict/omar (Rebase conflict/sara onto conflict/omar). أبقِ الخيارات معطّلة واختر إعادة تأسيس conflict/sara (Rebase conflict/sara). يتوقف. يعرض الشريط الآن تخطّي (Skip) بجانب متابعة وإيقاف…؛ ولم يكن في شريط الدمج تخطٍّ. - اقرأ أي إيداع يُعاد تطبيقه (إيداع سارة)، وأقرّ بأن التخطّي يترك عنوانها خارج الناتج، ثم اختر تخطّي مرة واحدة. يقول الإشعار «تم تخطّي الخطوة.»
- افحص التخطّي: تعرض الصفحة عنوان عمر، ويشير
conflict/saraالآن إلى إيداع عمر، ولا شريط ظاهرًا. قارن النتائج الثلاث وأبقها منفصلة.
لكل إيداع عادي في الدورة: الملخّص (Summary) هو العنوان المحدد، والوصف (Description) خالٍ، وتبقى الخيارات تعديل الإيداع الأخير وتخطّي الخطّافات وإضافة Signed-off-by ومؤلف مختلف والدفع بعد الإيداع والسماح بإيداع فارغ معطّلة.
في الطرفية
في نسخة نظيفة منفصلة من ناتج الدرس 18:
git switch --create conflict/sara
BASE_SHA="$(git rev-parse HEAD)"احفظ SARA باسم index.html ثم:
git add -- index.html
git -c user.name="Sara Lindqvist" -c user.email=sara@example.com commit --quiet -m "feat: Sara clarifies the hero"
git switch --quiet --create conflict/omar "$BASE_SHA"احفظ OMAR باسم index.html ثم:
git add -- index.html
git -c user.name="Omar Haddad" -c user.email=omar@example.com commit --quiet -m "feat: Omar explains the hero"
git switch --quiet conflict/saraاصنع ثلاث نسخ نظيفة من هذه الحالة (gittree-continue وgittree-abort وgittree-skip). أولًا، اعرف ما الجاري كلما شككت:
git statusنسخة المتابعة. يتوقف الدمج برمز الخروج 1. احفظ RESOLVED باسم index.html ثم:
git merge --no-ff --no-edit conflict/omar
git add -- index.html
git -c core.editor=true merge --continue
git ls-files --unmerged
git status --shortلا يطبع الأمران الأخيران شيئًا. نسخة الإيقاف:
git rev-parse conflict/sara
git merge --no-edit conflict/omar
git merge --abort
git rev-parse HEAD conflict/sara
git status --shortيتوقف الدمج ثم ينهيه git merge --abort. المعرّفان اللذان يطبعهما git rev-parse HEAD conflict/sara متساويان، وindex.html هو صفحة سارة كاملة، والحالة خالية. وتُترك إعادة التأسيس المتوقفة بالطريقة نفسها بـ git rebase --abort. نسخة التخطّي:
git rebase conflict/omar
git rebase --skip
git rev-parse HEAD conflict/omar
git status --shortتتوقف إعادة التأسيس؛ وينهيها git rebase --skip بعبارة «Successfully rebased». المعرّفان متساويان، فيقف فرع سارة الآن على إيداع عمر، والصفحة صفحة عمر، والحالة خالية. إيداع سارة المتخطَّى لم يعد على الفرع، لكن Git ما زال يحتفظ به فترة (سجل المراجع، الدرس 29). لا تقرأ هذه النتيجة على أنها حل أبقى المُدخلين.
النتيجة
أين تنتهي: ثلاث نسخ بثلاث نتائج مختلفة. نسخة المتابعة فيها إيداع دمج بأبوين والعنوان المجمّع. ونسخة الإيقاف في مكانها تمامًا حيث بدأت، بعنوان سارة. ونسخة التخطّي فيها عنوان عمر وفرع سارة على إيداع عمر. في الثلاث انتهت العملية والحالة خالية.
أخطاء شائعة
- استخدام التخطّي «لتجاوز» تعارض. هو يحذف تغيير ذلك الإيداع من الناتج.
- بدء دمج أو إعادة تأسيس أخرى وواحدة ما زالت متوقفة.
- استخدام
git reset --hardللهروب بدلgit merge --abortأوgit rebase --abort. - الإيقاف وأنت على بُعد نقرة من الإنهاء، أو المتابعة وأنت لا تدري ما الذي جُهِّز.
إن حدث خطأ
إن ضللت فاقرأ الشريط أو git status أولًا ثم قرّر من جديد. الإيقاف دائمًا هو الطريق الآمن للعودة إلى البداية. وإن تخطّيت بالخطأ فلا تبدأ من جديد عمياء: إيداع التخطّي ما زال قابلًا للوصول فترة من سجل المراجع (الدرس 29)، ويبيّن الدرس 30 ما يستطيع تراجع GitTree إرجاعه.
اختبر فهمك
أجب عن كل سؤال ثم اقرأ السبب. الأسئلة المعلَّمة «مطلوب» تُحتسب لإكمال الدرس.
0 من 6 صحيحة
أجب عن الأسئلة المطلوبة إجابة صحيحة لتكمل الدرس.
جرى التحقق في هذا المتصفح.
تدريب
في كل نسخة، اذكر العملية والاختيار والدليل: للمتابعة الأبوان وقائمة غير المدمج الفارغة، وللإيقاف المعرّفان المتساويان وصفحة سارة، وللتخطّي صفحة عمر والفرع على إيداعه. ثم توقّع لماذا لا يُعرض التخطّي للدمج.
تأكيد منك أنت: لا يستطيع الموقع رؤية جهازك.
لإكمال الدرس، أجب عن الأسئلة المطلوبة إجابة صحيحة وأكّد تنفيذ التمرين العملي.
خلاصة
- اعرف ما الجاري قبل أن تتصرف.
- تابع بعد الحل، وتخطَّ لترك إيداع خارج الناتج فقط، وأوقف للعودة.
- افحص الإيداع والملفات والحالة بعد ذلك.
ذو صلة
المصطلحات الجديدة
متابعة — Continue؛ تخطّي — skip؛ إيقاف — abort؛ عملية — operation.
نص الفيديو
ترجمة التعليق الصوتي الإنجليزي للفيديو، مقطعًا بعد مقطع.
اعرض النص
- يتوقف دمج أو إعادة تأسيس. أمامك ثلاثة مخارج.
- المتابعة تنهيها. والتخطّي يترك إيداعًا خارجها. والإيقاف يعود.
- أولًا، اعرف دائمًا أي عملية جارية.
- يسمّيها الشريط. وفي الطرفية يفعل git status ذلك.
- ابنِ فرعي سارة وعمر وثلاث نسخ متطابقة.
- بداية واحدة، وثلاث نهايات مختلفة.
- النسخة الأولى: سنتابع. ابدأ الدمج فيتوقف.
- اختر حلّ وافتح الملف واكتب العنوان المجمّع.
- احفظ وعلّم محلولًا ليعدّ Git الملف منتهيًا.
- صارت المتابعة متاحة. اخترها مرة واحدة.
- تم. للإيداع الجديد أبوان، واختفى الشريط.
- النسخة الثانية: سنوقف. ابدأ الدمج نفسه.
- اترك التعارض كما هو واختر إيقاف.
- يشرح الحوار ما يعود وما يُحفظ أولًا.
- عاد المستودع إلى ما كان عليه من قبل.
- رأس الفرع هو المعرّف نفسه، والصفحة صفحة سارة من جديد.
- النسخة الثالثة: سنتخطّى. وهذه إعادة تأسيس.
- أعد تأسيس فرع سارة على فرع عمر. يتوقف بتعارض.
- للشريط الآن زر تخطٍّ. ولم يكن للدمج واحد.
- يترك التخطّي إيداع سارة خارج الناتج. قلها بصوت عالٍ.
- اختر تخطّي مرة واحدة.
- تعرض الصفحة عنوان عمر. وفرع سارة يقف الآن على إيداعه.
- التخطّي ليس حلًّا. حذف تغيير سارة من هذه النتيجة.
- في الطرفية يبيّن git status ما الجاري والأوامر المتاحة.
- الدمج: أضف الملف المحلول ثم git merge --continue.
- الإيقاف: رأس الفرع هو نفسه قبل وبعد.
- التخطّي: git rebase --skip، فيقف الفرع على إيداع عمر.
- في كل نسخة الحالة خالية ولا شيء غير مدمج.
- غيّر المُدخل: حلّ الملف ثم اختر الإيقاف بدلًا.
- يُسقَط حلّك بعد حفظ لقطة استعادة.
- لا تستخدم reset --hard للهروب. الإيقاف هو المخرج الآمن.
- إن تخطّيت بالخطأ فالإيداع ما زال في سجل المراجع.
- تدريب: سمِّ العملية والاختيار والدليل لكل نسخة.
- التالي: انسخ إيداعًا واحدًا إلى فرع آخر بالانتقاء.