تخطَّ إلى المحتوى
GitTree

الدرس 23 · الاستعادة

حلّ تعارضات الدمج وإعادة التأسيس

احلّ العنوان المتنافس نفسه في دمج وفي إعادة تأسيس، وافهم لماذا يتبدّل معنى «نسختنا» و«نسختهم» بينهما، واحفظ نتيجة واحدة مقصودة تجمع الفكرتين، وأنهِ كل عملية دون أن تضيّع فكرة أحد.

حُفظ التقدّم في هذا المتصفح.

يحمّل التشغيل الفيديو من YouTube (وضع الخصوصية المحسّنة).

تعليق صوتي بالإنجليزية · ترجمة إنجليزية وعربية

افتح صفحة الفيديوشاهد على YouTube

ما ستتعلمه

  • أن تقرأ تعارضًا حقيقيًا: الأساس والجانب الحالي والجانب الوارد.
  • أن تشرح لماذا تتبدّل «نسختنا» و«نسختهم» بين الدمج وإعادة التأسيس.
  • أن تكتب حلًّا واحدًا مقصودًا ثم تعلّمه محلولًا.
  • أن تتابع العملية وتتأكد أنها لم تبقَ نصف منتهية.

قبل البدء

عدّل زميلان السطر نفسه من الصفحة. على conflict/sara غيّرت سارة العنوان الرئيسي إلى «Review changes with confidence.» وعلى conflict/omar غيّره عمر إلى «Understand each saved change.» يبدأ الفرعان من الإيداع M الذي كان فيه العنوان «See your work clearly.»، ولكل فرع إيداع واحد بالضبط. تصنع نسختين متطابقتين من هذا التباعد: واحدة للدمج (gittree-conflict-merge) وأخرى لإعادة التأسيس (gittree-conflict-rebase). في كلتيهما conflict/sara محدَّد ومجلد العمل خالٍ، ولا دمج أو إعادة تأسيس جارية.

كل شيء هنا محلي وضمن الخطة المجانية (يطلب GitTree تسجيل الدخول): دون حساب استضافة أو مزوّد أو إنترنت. كل الهويات خيالية (example.com). لا تنفّذ الدرس في مشروع حقيقي.

نفّذ التغييرات في GitTree أو بأوامر Git الأصلية، لا بالطريقتين في النسخة نفسها. القراءة بعد التنفيذ آمنة دائمًا. تسميات القوائم مأخوذة من نصوص GitTree 2.0 نفسها، وشُغّلت الأوامر الأصلية بـ Git 2.43 في نسخ مؤقتة. لم تُشغَّل خطوات GitTree على macOS أو Windows أو Linux.

الفكرة وأثر الأفعال

التعارض في المحتوى يعني أن Git لا يستطيع اختيار نتيجة وحده: عدّل الطرفان الأسطر نفسها بشكل مختلف. يتوقف Git ويحتفظ في الفهرس بثلاث نسخ من الملف: المرحلة 1 هي الأساس المشترك، والمرحلة 2 هي «نسختنا»، والمرحلة 3 هي «نسختهم». ويكتب أيضًا علامات التعارض في الملف داخل مجلد العمل. حذف العلامات في المحرر لا يحلّ شيئًا في نظر Git: لا يُعدّ الملف محلولًا إلا حين تحفظ النتيجة وتجهّزها، فتعود المرحلة 0.

«نسختنا» و«نسختهم» موضعان لا شخصان. في الدمج أنت على فرع سارة، فنسختنا هي نسخة سارة (الجانب الحالي) ونسختهم نسخة عمر (الجانب الوارد). وفي إعادة تأسيس سارة على عمر ينتقل Git أولًا إلى فرع عمر ثم يعيد تطبيق إيداع سارة، فنسختنا هي نسخة عمر (الفرع الذي تُعاد التأسيس عليه) ونسختهم إيداع سارة. يكتب GitTree الدور بجانب كل اسم فلا تحتاج إلى التذكّر: «(الحالي)» و«(الوارد)» في الدمج، و«(يُعاد التأسيس عليه)» و«(إيداعك)» في إعادة التأسيس.

النتيجة الصحيحة نادرًا ما تكون أحد الجانبين. هنا الحل المقصود «Review each change with confidence.» لا سطر سارة ولا سطر عمر. أبقِ كل سطر آخر في الصفحة كما كان بالضبط. تعليم الملف محلولًا يجهّز نتيجتك؛ والمتابعة خطوة مستقلة تنهي إيداع الدمج أو تعيد إنشاء إيداع سارة فوق إيداع عمر.

ما دامت العملية متوقفة يبقى الفرع حيث تركته العملية ويبقى الملف متعارضًا. لا شيء يصل إلى أي خادم.

إعداد حالة المشروع المحددة

اصنع تباعدًا واحدًا ثم انسخه مرتين. ابدأ من نسخة عادية منفصلة من المشروع كما تركه الدرس 18، وأبقِ gittree-features الأصلي دون مساس. نسخ الصفحة أدناه: MERGED هو الأساس المشترك، وSARA وOMAR النسختان المتنافستان، وRESOLVED النتيجة التي ستحفظها.

مدخلات الملفات كاملة

احفظ في المرحلة المحددة فقط بصيغة UTF-8 وLF وسطر نهائي. لا تلصق أسوار Markdown. ترث الملفات الثابتة نقطة البداية؛ لا تستبدل الأصل بنسخة إعادة منفصلة.

index.html — MERGED

مقتطف من ملف · html
<!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

مقتطف من ملف · html
<!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

مقتطف من ملف · html
<!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

مقتطف من ملف · html
<!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). تستخدم أفعال الفرع المسمّى قائمة النقر بزر الفأرة الأيمن على صفه.

  1. ابنِ النسختين كما يبيّن القسم التالي. افتح gittree-conflict-merge وconflict/sara محدَّد.
  2. انقر conflict/omar بزر الفأرة الأيمن واختر دمج conflict/omar في conflict/sara (Merge conflict/omar into conflict/sara). تحت طريقة التسجيل (Record it as) اختر إيداع دمج دائمًا (Always a merge commit). يحذّر الحوار «سيتوقف بسبب تعارض في ملف واحد»؛ اختر دمج (Merge). يتوقف الدمج، وهذه هي النتيجة المتوقعة.
  3. يقرأ شريط التنبيه «جارٍ دمج conflict/omar في conflict/sara» مع «تعارض واحد»، ومتابعة (Continue) غير متاحة بعد: «حُلّ التعارضات (1) أولًا». اختر حلّ (Resolve).
  4. افتح index.html من الملفات المتعارضة (Conflicted files). اقرأ الجانبين conflict/sara (الحالي) وconflict/omar (الوارد)، واستخدم إظهار الأساس (Show Base) لقراءة الأساس (السلف المشترك) (Base (common ancestor)).
  5. اختر تحرير النتيجة (Edit Output)، واستبدل العنوان المتعارض بـ Review each change with confidence. وأبقِ كل سطر آخر. ثم اختر حفظ وتعليم كمحلول (Save and Mark Resolved). حذف العلامات وإغلاق الملف لا يكفي.
  6. عد إلى الشريط واختر متابعة. إن عُرضت رسالة فأبقِ المقترحة. انتظر انتهاء الدمج: للإيداع الجديد أبوان.
  7. افتح gittree-conflict-rebase وconflict/sara محدَّد. انقر conflict/omar بزر الفأرة الأيمن واختر إعادة تأسيس conflict/sara على conflict/omar (Rebase conflict/sara onto conflict/omar). أبقِ الخيارات تحت خيارات إعادة التأسيس هذه (Options for this rebase) معطّلة، ثم اختر إعادة تأسيس conflict/sara (Rebase conflict/sara). يتوقف بتعارض.
  8. اختر حلّ وافتح index.html. الجانبان الآن conflict/omar (يُعاد التأسيس عليه) وconflict/sara (إيداعك): تبدّل الدوران. نفّذ تحرير النتيجة ← حفظ وتعليم كمحلول نفسه، ثم متابعة.
  9. افحص النسختين: الملف يطابق RESOLVED، ولا ملف متعارضًا، ولا شريط تنبيه ظاهرًا. أبقِ الناتجين منفصلين ولا تدفع.

لكل إيداع عادي في الدورة: الملخّص (Summary) هو العنوان المحدد، والوصف (Description) خالٍ، وتبقى الخيارات تعديل الإيداع الأخير وتخطّي الخطّافات وإضافة Signed-off-by ومؤلف مختلف والدفع بعد الإيداع والسماح بإيداع فارغ معطّلة.

في الطرفية

في نسخة نظيفة منفصلة من ناتج الدرس 18:

الأمر · bash
git switch --create conflict/sara
BASE_SHA="$(git rev-parse HEAD)"

احفظ SARA باسم index.html ثم:

الأمر · bash
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 ثم:

الأمر · bash
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

BASE_SHA هو M قبل أي من الإيداعين المتنافسين. اصنع نسختين نظيفتين من هذا التباعد، واحدة للدمج وأخرى لإعادة التأسيس (cd .. && cp -R gittree-features gittree-conflict-merge && cp -R gittree-features gittree-conflict-rebase). في نسخة الدمج:

الأمر · bash
git merge --no-ff --no-edit conflict/omar
git ls-files --unmerged
git show :2:index.html
git show :3:index.html

يتوقف الدمج برمز الخروج 1، ويسرد git ls-files --unmerged ثلاثة مدخلات هي المراحل 1 و2 و3. git show :2:index.html نسخة سارة (نسختنا) و:3: نسخة عمر (نسختهم)، و:1: هو الأساس. احفظ RESOLVED باسم index.html ثم:

الأمر · bash
git add -- index.html
git -c core.editor=true merge --continue
git ls-files --unmerged
git status --short

لا يطبع الأمران الأخيران شيئًا. وفي نسخة إعادة التأسيس التي لم تُمَس:

الأمر · bash
git rebase conflict/omar
git show :2:index.html
git show :3:index.html

تتوقف إعادة التأسيس. الآن :2: نسخة عمر و:3: نسخة سارة: تبدّل الدوران. احفظ RESOLVED باسم index.html ثم:

الأمر · bash
git add -- index.html
git -c core.editor=true rebase --continue
git ls-files --unmerged
git status --short

يطابق الملفان الآن RESOLVED ولا شيء غير مدمج. يقبل core.editor=true رسالة الإيداع الموجودة لهذا الأمر وحده؛ ولا يغيّر إعداد المحرر عندك. وللخروج من عملية متوقفة دون حل استخدم git merge --abort أو git rebase --abort.

النتيجة

أين تنتهي: نسخة الدمج فيها إيداع جديد بأبوين والعنوان المجمّع؛ ونسخة إعادة التأسيس فيها إيداع سارة معاد إنشاؤه فوق إيداع عمر والعنوان المجمّع نفسه. في كلتيهما يطابق index.html الملف RESOLVED، ولا مدخل تعارض باقٍ، والعملية انتهت والحالة خالية.

أخطاء شائعة

  • افتراض أن «نسختنا» تعني دائمًا ميزتك أنت. تعني الجانب الذي يقف عليه Git، وهو يتغير بتغير العملية.
  • أخذ جانب واحد كاملًا («أخذ الكل») قبل قراءة النسختين وبقية الملف.
  • حذف علامات التعارض دون حفظ الملف وتعليمه محلولًا.
  • تكرار دمج أو إعادة تأسيس انتهت بالفعل.

إن حدث خطأ

إن بدا التوقف خاطئًا فـ إيقاف… من الشريط يعيد الحالة التي بدأت منها العملية ويسقط الحلول التي أجريتها حتى الآن؛ ويحفظ GitTree لقطة استعادة أولًا. وإن تغيّر الملف أثناء تحريرك فاستخدم خياري مقارنة واستخدامها نتيجةً بدل فرض حفظ قديم. احتفظ بنسخة من مسودتك قبل استبدالها.

اختبر فهمك

أجب عن كل سؤال ثم اقرأ السبب. الأسئلة المعلَّمة «مطلوب» تُحتسب لإكمال الدرس.

  1. السؤال 1 من 6

    أنت على conflict/sara وتدمج فيه conflict/omar. أي جانب يسميه Git «ours» (نسختنا)؟

    اختر إجابة واحدة.

  2. السؤال 2 من 6

    أي العبارات صحيحة عن ملف متعارض في الفهرس؟

    اختر كل إجابة صحيحة.

  3. السؤال 3 من 6
    مطلوب

    تعيد تأسيس conflict/sara على conflict/omar فيتوقف بتعارض. أي نسخة هي «ours» الآن؟

    اختر إجابة واحدة.

  4. السؤال 4 من 6

    غيّر المُدخل: حذفت علامات التعارض في المحرر وحفظت الملف، لكنك لم تعلّمه محلولًا. في أي حالة أنت؟

    اختر إجابة واحدة.

  5. السؤال 5 من 6
    مطلوب

    حفظت نتيجتك لكن الشريط ما زال يقول «حُلّ التعارضات (1) أولًا» و«متابعة» غير متاحة. ما السبب الأرجح؟

    اختر إجابة واحدة.

  6. السؤال 6 من 6
    مطلوب

    أي قراءات تبيّن أن نسخة الدمج انتهت على الوجه الصحيح؟

    اختر كل إجابة صحيحة.

0 من 6 صحيحة

أجب عن الأسئلة المطلوبة إجابة صحيحة لتكمل الدرس.

جرى التحقق في هذا المتصفح.

تدريب

أثبت أدوار المراحل في العمليتين بـ git show :2:index.html وgit show :3:index.html، ثم احفظ ملف RESOLVED نفسه وأنهِ كل عملية. توقّع ما يبقى في الصفحة لو أخذت «نسختنا» عمياء في النسختين.

تأكيد منك أنت: لا يستطيع الموقع رؤية جهازك.

لإكمال الدرس، أجب عن الأسئلة المطلوبة إجابة صحيحة وأكّد تنفيذ التمرين العملي.

خلاصة

  • يتوقف دورا «نسختنا» و«نسختهم» على العملية.
  • احفظ وعلّم محلولًا أولًا، ثم تابع.
  • افحص الملف كاملًا وحالة العملية بعد ذلك.

المصطلحات الجديدة

تعارض — Conflict؛ الأساس — base؛ نسختنا — ours؛ نسختهم — theirs؛ حلّ — resolve.

نص الفيديو

ترجمة التعليق الصوتي الإنجليزي للفيديو، مقطعًا بعد مقطع.

اعرض النص
  1. التعارض ليس خطأ. هو سؤال لا يجيب عنه سواك.
  2. عدّل شخصان السطر نفسه من الملف نفسه.
  3. كتبت سارة عنوانًا وكتب عمر آخر. وكلاهما بدأ من الصفحة نفسها.
  4. لا يستطيع Git تخمين أي سطر يفوز، فيتوقف ويسألك.
  5. أولًا، ابنِ فرعي سارة وعمر ونسختين متطابقتين.
  6. في النسخة الأولى ندمج. وفي الثانية نعيد التأسيس.
  7. افتح نسخة الدمج، على فرع سارة.
  8. انقر فرع عمر بزر الفأرة الأيمن واختر أمر الدمج.
  9. يحذّر الحوار مسبقًا: سيتوقف بسبب تعارض في ملف واحد.
  10. اختر إيداع دمج دائمًا ثم دمج مرة واحدة. يتوقف كما هو متوقع.
  11. يعرض الشريط تعارضًا واحدًا. «متابعة» غير متاحة بعد.
  12. اختر حلّ وافتح index.html.
  13. جانبان: فرع سارة هو الحالي وفرع عمر هو الوارد.
  14. يكشف إظهار الأساس السلف المشترك، الصفحة قبل أي تغيير.
  15. الآن تحرير النتيجة. استبدل العنوان بسطر واحد مقصود.
  16. حفظ وتعليم كمحلول. الآن فقط يعدّ Git الملف محلولًا.
  17. عد إلى الشريط واختر متابعة. ينتهي الدمج.
  18. للإيداع الجديد أبوان، والعنوان المجمّع.
  19. الآن نسخة إعادة التأسيس، وهي أيضًا على فرع سارة.
  20. انقر فرع عمر بالزر الأيمن وأعد تأسيس فرع سارة عليه.
  21. أبقِ الخيارات معطّلة وأعد التأسيس مرة واحدة. يتوقف بتعارض.
  22. انظر إلى التسميات. الآن فرع عمر هو ما نعيد التأسيس عليه.
  23. إيداع سارة هو ما يُعاد تطبيقه. تبدّلت الأدوار.
  24. الحل نفسه: تحرير النتيجة ثم حفظ وتعليم كمحلول ثم متابعة.
  25. يُعاد إنشاء إيداع سارة فوق إيداع عمر، بالعنوان نفسه.
  26. في الطرفية، اسرد المدخلات غير المدمجة لدمج متوقف.
  27. المرحلة الثانية نسختنا: عنوان سارة. والثالثة نسختهم: عنوان عمر.
  28. في إعادة تأسيس متوقفة، المرحلتان الثانية والثالثة بالعكس.
  29. بعد الإصلاح، لا شيء غير مدمج، والحالة خالية.
  30. لرأس نسخة الدمج أبوان، ولرأس نسخة إعادة التأسيس أب واحد.
  31. غيّر المُدخل: احذف العلامات واحفظ، لكن لا تعلّم محلولًا.
  32. ما زال Git يرى ثلاث مراحل، فتبقى «متابعة» غير متاحة.
  33. عالق؟ يعيد الإيقاف الفرع إلى حيث بدأت العملية.
  34. يحفظ GitTree لقطة استعادة أولًا، فحتى الإيقاف آمن.
  35. لا تأخذ الكل من جانب قبل أن تقرأ النسختين.
  36. تدريب: أثبت أدوار المراحل في النسختين ثم أنهِ كلتيهما.
  37. التالي: تابع أو تخطَّ أو أوقف عملية توقفت.