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

الدرس 22 · السجل والتكامل

إعادة ترتيب الإيداعات المحلية وضمّها وإعادة صياغتها وإسقاطها

حوّل خمسة إيداعات خاصة غير مرتبة إلى إيداعين نظيفين: انقل إصلاحًا يعتمد على غيره، وأعد صياغة رسالة، واضمم الخطوات، وأسقط الضجيج وحده، ثم تحقق أن الناتج يحوي الملفات التي قصدتها بالضبط.

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

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

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

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

ما ستتعلمه

  • أن تقرأ خطة إعادة التطبيق: الخطوة الأقدم أولًا، وتُطبَّق من الأعلى إلى الأسفل.
  • أن تختار الإجراء المناسب: إعادة صياغة أو ضمّ أو ضمّ مع تجاهل الرسالة أو إسقاط.
  • أن تنقل خطوة دون أن تكسر الخطوة التي تعتمد عليها.
  • أن تتحقق بعد ذلك من الإيداعات الجديدة والملفات وفرع الحفظ.

قبل البدء

فرعك private/signup-polish فيه خمسة إيداعات موجودة على حاسوبك وحده، فوق الإيداع M. مجلد العمل خالٍ، ويشير rescue/before-polish إلى الإيداع الخامس. بالترتيب، الأقدم أولًا:

الخطوةالإيداعماذا يفعل
C1feat: add signup draftيضيف نموذج التسجيل
C2docs: explain signup reviewيضيف docs/replay-a.md
C3docs: explain validationيضيف docs/replay-b.md
C4fixup! feat: add signup draftيصلح تسمية النموذج
C5chore: temporary noteيضيف docs/temporary-review.md

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

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

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

إعادة التأسيس التفاعلية خطة لا لعبة ترتيب. يعيد Git تطبيق الإيداعات المدرجة واحدًا واحدًا فوق القاعدة، من أعلى القائمة إلى أسفلها، فالخطوة الأقدم أولًا. ويخبر كل إجراء Git ماذا يفعل بخطوة واحدة:

  • اختيار (Pick) يُبقي الإيداع كما هو.
  • إعادة صياغة (Reword) يُبقي محتواه ويتيح لك رسالة جديدة.
  • ضمّ (Squash) يطوي الإيداع في الإيداع المُبقى فوقه ويتيح لك رسالة واحدة مجمّعة.
  • ضمّ مع تجاهل الرسالة (Fixup) يطويه كذلك لكنه يتجاهل رسالته.
  • إسقاط (Drop) يترك تغيير الإيداع خارج السجل كليًا.

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

يأخذ كل إيداع معاد التطبيق معرّفًا جديدًا لأن أباه تغيّر. يُعاد كتابة هذا الفرع وحده؛ ويحتفظ فرع الحفظ بالخمسة القدامى. تُعلَّم الإيداعات الموجودة على مستودع بعيد بعبارة «على مستودع بعيد»، وإعادة كتابتها تحتاج تأكيدًا صريحًا. هذا الدرس لا يؤكد ذلك أبدًا.

الخطة التي ستبنيها تحوّل خمسة إيداعات إلى اثنين:

الخطوةالإيداعالإجراءالناتج
1C1إعادة صياغةfeat: complete the local signup form
2C4ضمّ مع تجاهل الرسالةمطوي في الخطوة 1
3C3اختياريبقى؛ هو هدف الضمّ
4C2ضمّdocs: explain signup review and validation
5C5إسقاطيختفي

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

ابدأ من نسخة عادية منفصلة من المشروع كما تركه الدرس 18. أبقِ gittree-features الأصلي دون مساس. ابنِ الإيداعات الخمسة أدناه على فرع جديد، ملفًا بعد ملف، واحفظ كل نص كامل في خطوته المسمّاة فقط.

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

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

index.html — SIGNUP

مقتطف من ملف · 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>
    <section aria-labelledby="signup-title">
      <h2 id="signup-title">Try the demo form</h2>
      <form id="signup-form" novalidate>
        <label for="demo-email">Demo email</label>
        <input id="demo-email" name="email" type="email" autocomplete="off" aria-describedby="signup-hint">
        <p id="signup-hint">Use a fictional example.com address. Nothing is sent.</p>
        <button type="submit">Check the address locally</button>
        <p id="signup-result" role="status"></p>
      </form>
    </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>

docs/replay-a.md — DOC_A

الناتج
# Local signup review

Review the label and hint together.

docs/replay-b.md — DOC_B

الناتج
# Local validation review

No address leaves this demonstration.

index.html — SIGNUP_LABEL

مقتطف من ملف · 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>
    <section aria-labelledby="signup-title">
      <h2 id="signup-title">Try the demo form</h2>
      <form id="signup-form" novalidate>
        <label for="demo-email">Fictional email address</label>
        <input id="demo-email" name="email" type="email" autocomplete="off" aria-describedby="signup-hint">
        <p id="signup-hint">Use a fictional example.com address. Nothing is sent.</p>
        <button type="submit">Check the address locally</button>
        <p id="signup-result" role="status"></p>
      </form>
    </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>

docs/temporary-review.md — DOC_NOISE

الناتج
Temporary rehearsal note, deliberately dropped.

في GitTree

افتح لوحة الأوامر بـ Command+Shift+P (وCtrl+Shift+P على Ubuntu). تستخدم أفعال الإيداع قائمة النقر بزر الفأرة الأيمن على صفه.

  1. ابنِ الإيداعات الخمسة وفرع الحفظ كما يبيّن القسم التالي، مع تحديد private/signup-polish وخلوه. دوّن M والعناوين الخمسة.
  2. انقر M، الإيداع الذي تحت الخمسة، بزر الفأرة الأيمن واختر تعديل السجل (Edit History) ← إعادة تأسيس تفاعلية للإيداعات التي تعلوه… (Interactive Rebase of the Commits Above…). يفتح المحرر بالخطوات الخاصة الخمس، الأقدم أولًا.
  3. تحت خيارات إعادة التأسيس هذه (Options for this rebase) أبقِ الخيارات الثلاثة معطّلة، ومنها رتّب إيداعات fixup! وsquash! وamend! (Arrange fixup!, squash! and amend! commits). ستنقل الإصلاح بنفسك.
  4. ركّز على صف C4 واضغط Alt+↑ مرتين، ثم ركّز على C3 واضغط Alt+↑ مرة. يصير الترتيب C1 وC4 وC3 وC2 وC5. الضغط على p أو r أو e أو s أو f أو d على صف مركَّز يعيّن اختيار أو إعادة صياغة أو تحرير أو ضمّ أو ضمّ مع تجاهل الرسالة أو إسقاط.
  5. اضبط C1 على إعادة صياغة (Reword) واكتب feat: complete the local signup form في حقل رسالته. واضبط C4 على ضمّ مع تجاهل الرسالة (Fixup).
  6. أبقِ C3 على اختيار (Pick) واضبط C2 على ضمّ (Squash). تحت الإيداعات المضمومة (Squashed commits) تعرض المجموعة «إيداعان في «docs: explain validation»» رسالة مجمّعة. استبدلها بـ docs: explain signup review and validation.
  7. اضبط C5 على إسقاط (Drop). اقرأ كل صف والرسالة المجمّعة مرة أخيرة. لا شيء معلَّم «على مستودع بعيد» (On a remote) فلا حاجة إلى تأكيد.
  8. اختر بدء إعادة التأسيس (Start Rebase) مرة واحدة وانتظر. إن توقفت فتابع من شريط التنبيه، ولا تبدأ الخطة كلها من جديد.
  9. تحقق من إيداعين جديدين، وإصلاح التسمية في الصفحة، والوثيقتين، وغياب الملاحظة المؤقتة. أبقِ rescue/before-polish وأبقِ مجلد العمل خاليًا.

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

في الطرفية

ابنِ الإيداعات الخمسة على فرع جديد، واحفظ كل نص كامل في خطوته:

الأمر · bash
git switch --create private/signup-polish

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

الأمر · bash
git add -- index.html
git commit --quiet -m "feat: add signup draft"

احفظ DOC_A باسم docs/replay-a.md ثم:

الأمر · bash
git add -- docs/replay-a.md
git commit --quiet -m "docs: explain signup review"

احفظ DOC_B باسم docs/replay-b.md ثم:

الأمر · bash
git add -- docs/replay-b.md
git commit --quiet -m "docs: explain validation"

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

الأمر · bash
git add -- index.html
git commit --quiet -m "fixup! feat: add signup draft"

احفظ DOC_NOISE باسم docs/temporary-review.md ثم:

الأمر · bash
git add -- docs/temporary-review.md
git commit --quiet -m "chore: temporary note"

احفظ الرأس القديم وسرد النطاق، الأقدم أولًا:

الأمر · bash
git branch rescue/before-polish
BASE_SHA="$(git rev-parse HEAD~5)"
git log --reverse --format=%s "$BASE_SHA"..HEAD

ابدأ الآن إعادة التأسيس التفاعلية (-i صيغة قصيرة لـ --interactive). يفتح Git محررك بقائمة المهام (ستختلف معرّفاتك):

الأمر · bash
git rebase --interactive --no-autosquash --no-update-refs --no-autostash "$BASE_SHA"
الناتج
pick 1a2b3c4 feat: add signup draft
pick 2b3c4d5 docs: explain signup review
pick 3c4d5e6 docs: explain validation
pick 4d5e6f7 fixup! feat: add signup draft
pick 5e6f708 chore: temporary note

أعد كتابة الأسطر الخمسة لتصير الخطة، مع إبقاء معرّف كل سطر، ثم احفظ:

الناتج
reword 1a2b3c4 feat: add signup draft
fixup 4d5e6f7 fixup! feat: add signup draft
pick 3c4d5e6 docs: explain validation
squash 2b3c4d5 docs: explain signup review
drop 5e6f708 chore: temporary note

يفتح Git المحرر مرتين أخريين. عند إعادة الصياغة استبدل الرسالة بـ feat: complete the local signup form. وعند الضمّ يعرض الرسالتين معًا؛ استبدلهما بسطر واحد docs: explain signup review and validation. افحص الناتج:

الأمر · bash
git rev-list --count "$BASE_SHA"..HEAD
git log --reverse --format=%s "$BASE_SHA"..HEAD
git status --short
الناتج
2
feat: complete the local signup form
docs: explain signup review and validation

الحالة خالية. index.html هو SIGNUP_LABEL، والوثيقتان موجودتان، وdocs/temporary-review.md غير موجود.

لو وضعت ضمًّا في السطر الأول لتوقف Git فورًا بـ error: cannot 'squash' without a previous commit. أصلح القائمة بـ git rebase --edit-todo ثم git rebase --continue، أو اخرج بـ git rebase --abort. مع --autosquash ينقل Git إيداعات fixup! ويضبط إجراءها عنك؛ يوقفه هذا الدرس ليريك الخطة.

النتيجة

أين تنتهي: إيداعان معاد كتابتهما فوق M، هما «feat: complete the local signup form» و«docs: explain signup review and validation». في الصفحة إصلاح التسمية، والوثيقتان موجودتان والملاحظة المؤقتة غائبة. الإيداعات الخمسة القديمة محفوظة في فرع الحفظ، ومجلد العمل خالٍ.

أخطاء شائعة

  • استخدام الإسقاط لإخفاء إيداع قد تحتاجه. تغييره ليس في السجل الجديد إطلاقًا.
  • نقل إصلاح فوق الإيداع الذي يصلحه.
  • ضمّ الخطوة الأولى، وليس فوقها ما تُطوى فيه.
  • بدء الخطة من جديد بعد انتهائها بدل فحص الناتج أولًا.

إن حدث خطأ

قبل البدء يترك إلغاء الفرع كما هو. إن قال GitTree إن الفرع تغيّر منذ فتح المحرر فأغلق المحرر وافتحه مجددًا. إن توقفت إعادة التأسيس فأصلح التعارض أو الرسالة وتابع من شريط التنبيه، أو أوقفها عن قصد. وبعد انتهائها قارن مع rescue/before-polish قبل أن تحاول استعادة أي شيء.

اختبر فهمك

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

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

    في قائمة مهام إعادة التأسيس التفاعلية، أي إيداع يُعاد تطبيقه أولًا؟

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

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

    أي من هذه الخطط لا يمكن أن ينجح؟

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

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

    الخطة: إعادة صياغة C1، ضمّ مع تجاهل الرسالة C4، اختيار C3، ضمّ C2، إسقاط C5. بعد التنفيذ كم إيداعًا فوق M، وأين يذهب ملف الملاحظة المؤقتة؟

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

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

    غيّر المُدخل: تركت C5 على اختيار بدل إسقاط. ما الذي يتغير؟

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

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

    ضبطت الخطوة 1 على ضمّ ويرفض GitTree البدء: «الخطوة 1 لا تُضمّ في أي إيداع: انقلها أسفل إيداع مُبقًى عليه». ماذا يعني ذلك وماذا تفعل؟

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

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

    أي قراءات تثبت أن الناتج هو ما قصدته الخطة؟

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

0 من 6 صحيحة

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

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

تدريب

اشرح الخطة C1 وC4 وC3 وC2 وC5 والرسالتين الباقيتين. تحقق: النطاق القديم 5 والجديد 2، والملفات المتوقعة، وغياب الملاحظة. ثم توقّع، دون تنفيذ، لماذا لا يصح نقل C4 فوق C1 ولا ضمّ الخطوة 1.

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

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

خلاصة

  • لخطة إعادة التطبيق ترتيب واعتماديات.
  • يحتفظ الضمّ برسالتين لتجمعهما أنت، ويتجاهل الضمّ مع تجاهل الرسالة رسالته.
  • يزيل الإسقاط التغيير نفسه، فأسقط الضجيج الحقيقي فقط.

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

إعادة صياغة — Reword؛ ضمّ — squash؛ ضمّ مع تجاهل الرسالة — fixup؛ إسقاط — drop؛ خطة إعادة التطبيق — replay plan.

نص الفيديو

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

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