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

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

نقل إيداعات مختارة بالانتقاء (cherry-pick)

انسخ إصلاح زميلة إلى فرع الإصدار دون دمج فرعها كله، ثم افحص الإيداع الجديد ومؤلفه وملفاته وما بقي خلفك.

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

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

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

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

ما ستتعلمه

  • أن تختار الإيداع الواحد الذي تنسخه، وتفهم لماذا لا يأتي أبوه معه.
  • أن تتوقع معرّف الإيداع الجديد ومؤلفه ومن أودعه.
  • أن تتعرّف الاعتماد المفقود أو التغيير المطبَّق من قبل قبل أن تفرض أي شيء.
  • أن تفحص الناتج مقابل فرع المصدر.

قبل البدء

في فرع بريا priya/label إيداعان فوق أساس مشترك B (صفحة التسجيل). الأول ملاحظة غير متعلقة «docs: unrelated source note» تضيف docs/temporary-review.md. والثاني إصلاحها «fix: clarify the fictional email label» الذي يغيّر التسمية في index.html. وفرعك release/label يبدأ من الأساس B نفسه وفيه إيداع واحد لك «docs: record target review» يضيف docs/integration-note.md. فرع release/label محدَّد ومجلد العمل خالٍ. تريد إصلاحها على فرعك، دون ملاحظتها.

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

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

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

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

إيداع المصدر لا يُمَسّ. وللإيداع الجديد معرّف جديد لأن له أبًا جديدًا، لكنه يحتفظ بالمؤلف الأصلي والرسالة. أما المُودِع، من أنشأ هذا الإيداع، فهو أنت. التغيير نفسه بالرسالة نفسها يظل إيداعًا آخر.

الاعتماديات ما زالت مهمة. يعدّل الإصلاح سطرًا من نموذج التسجيل، فيجب أن يملك الفرع الهدف هذا النموذج. إن لم يملكه يتوقف Git بتعارض. وإن كان الهدف يحوي التغيير نفسه فسيكون الانتقاء فارغًا فيتوقف Git من جديد. في الحالتين اقرأ ما تقوله العملية؛ ولا تفرض إيداعًا فارغًا لمجرد التجاوز.

يتحرك الفرع الهدف وحده. يبقى priya/label وكل ما على الخوادم كما هو. ويضيف الإيداع الجديد تغيير التسمية إلى release/label ولا شيء غيره.

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

ابدأ من نسخة عادية منفصلة من المشروع كما تركه الدرس 18، وأبقِ gittree-features الأصلي دون مساس. احفظ SIGNUP أساسًا ثم ابنِ الفرعين. النصوص أدناه هي صفحة الأساس (SIGNUP) والملاحظة غير المتعلقة (DOC_NOISE) والصفحة المصحَّحة (SIGNUP_LABEL) وملاحظتك (DOC_MERGE).

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

احفظ في المرحلة المحددة فقط بصيغة 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/temporary-review.md — DOC_NOISE

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

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/integration-note.md — DOC_MERGE

الناتج
# Integration review

This note was written on main while signup work was private.

في GitTree

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

  1. ابنِ الأساس والفرعين كما يبيّن القسم التالي. حدّد release/label وتأكد أن مجلد العمل خالٍ.
  2. في المخطط ابحث عن إيداع بريا «fix: clarify the fictional email label» لا الملاحظة التي تحته. حدّده واقرأ تفاصيله: مسار واحد متغيّر هو index.html، وأبوه هو الملاحظة غير المتعلقة.
  3. انقر ذلك الإيداع بزر الفأرة الأيمن واختر انتقاء الإيداع (Cherry-Pick Commit). يُطبَّق فورًا على الفرع الذي أنت عليه؛ لا منتقي فروع. والأمر معطَّل على الإيداع الذي هو الحالي بالفعل.
  4. انتظر النتيجة الفعلية. إن توقفت عملية فاستخدم حلّ (Resolve) أو متابعة (Continue) أو إيقاف… (Abort…) من الشريط بدل أن تنتقي من جديد.
  5. حدّد الإيداع الجديد على release/label. معرّفه يختلف عن معرّف بريا، والمؤلف Priya Nair والمُودِع GitTree Demo.
  6. افتح index.html: هو SIGNUP_LABEL. وdocs/temporary-review.md غير موجود، وdocs/integration-note.md الخاص بك موجود. ما زال priya/label يسمّي رأسه القديم.
  7. أبقِ release/label خاليًا. لا تدفع، ولا تدمج priya/label.

إن حدّدت إيداعين أو أكثر في المخطط تعرض القائمة انتقاء الإيداعات (Cherry-Pick Commits) وتنسخها بالترتيب. هذا الدرس ينسخ إيداعًا واحدًا.

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

في الطرفية

في نسخة منفصلة من ناتج الدرس 18، أنشئ فرع الأساس قبل حفظ SIGNUP:

الأمر · bash
git switch --create label-base

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

الأمر · bash
git add -- index.html
git commit --quiet -m "feat: prepare the shared signup baseline"
BASE_SHA="$(git rev-parse HEAD)"
git switch --create priya/label

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

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

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

الأمر · bash
git add -- index.html
git -c user.name="Priya Nair" -c user.email=priya@example.com commit --quiet -m "fix: clarify the fictional email label"
PICK_SHA="$(git rev-parse HEAD)"
git switch --create release/label "$BASE_SHA"

احفظ DOC_MERGE باسم docs/integration-note.md ثم:

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

انتقِ الإصلاح الآن واقرأ الناتج:

الأمر · bash
git cherry-pick "$PICK_SHA"
git log -1 --format='%s%n%an <%ae>%n%cn <%ce>'
git diff-tree --no-commit-id --name-only -r HEAD
git status --short
الناتج
fix: clarify the fictional email label
Priya Nair <priya@example.com>
GitTree Demo <demo@example.com>
index.html

يختلف معرّف الإيداع الجديد عن PICK_SHA، وindex.html هو SIGNUP_LABEL، وdocs/temporary-review.md غائب، والحالة خالية. وهناك حالتان تعرفهما وتجرّبهما في نسخ منفصلة لا في النسخة الأساسية: git cherry-pick -x "$PICK_SHA" يضيف سطر «(cherry picked from commit …)» إلى الرسالة الجديدة، وهو مفيد حين تنتقي بين فروع مشتركة؛ وعلى هدف لا يملك نموذج التسجيل يتوقف الأمر نفسه بتعارض في index.html تحلّه (الدرس 23) أو تتركه بـ git cherry-pick --abort. وإن كان الهدف يملك التغيير فيتوقف Git من جديد بانتقاء فارغ، والمخرج git cherry-pick --skip أو --abort.

النتيجة

أين تنتهي: في release/label إيداع جديد واحد بإصلاح بريا، مؤلفه Priya Nair ومُودِعه GitTree Demo، بمعرّف جديد. في الصفحة التسمية الموضَّحة، ولم تأتِ الملاحظة غير المتعلقة، ولم يتغير priya/label ولا الخادم، ومجلد العمل خالٍ.

أخطاء شائعة

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

إن حدث خطأ

إن توقف الانتقاء فاقرأ الشريط. حلّ ومتابعة تنهيانه كما في الدرس 23، وإيقاف… يعيد الفرع إلى حيث كان. وإن كان الانتقاء خطأً بعد أن انتهى فالإيداع الجديد على release/label وحده: تراجع عنه هناك، ولم يُمَسّ فرع المصدر أصلًا.

اختبر فهمك

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

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

    ماذا ينسخ الانتقاء؟

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

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

    بعد الانتقاء، أي مما يلي صحيح عن الإيداع الجديد؟

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

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

    إصلاح بريا فوق إيداع ملاحظة غير متعلقة. تنتقي الإصلاح وحده إلى release/label. هل يوجد docs/temporary-review.md على release/label بعد ذلك؟

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

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

    غيّر المُدخل: لا يملك release/label نموذج التسجيل الذي يعدّله إصلاح بريا. ماذا يحدث عند الانتقاء؟

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

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

    تنتقي إيداعًا فيتوقف Git بعبارة «The previous cherry-pick is now empty». التغيير موجود على فرعك بالفعل. ماذا تفعل؟

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

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

    أي قراءات تبيّن أن الانتقاء فعل ما يقوله الدرس؟

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

0 من 6 صحيحة

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

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

تدريب

اكتب معرّف الإيداع الجديد ومؤلفه ومُودِعه والمسارات المتغيرة، ووجود docs/temporary-review.md من عدمه. ثم توقّع ما يحدث لو انتقيت الإيداع نفسه مرة أخرى إلى release/label.

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

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

خلاصة

  • ينسخ الانتقاء تغيير إيداع واحد إيداعًا جديدًا.
  • يبقى الأب والإيداعات التي قبله خلفك.
  • افحص الاعتماديات والانتقاء الفارغ قبل أن تفرض شيئًا.

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

انتقاء — Cherry-pick؛ إيداع المصدر — source commit؛ الهدف — target؛ اعتماد — dependency.

نص الفيديو

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

اعرض النص
  1. خذ إصلاحًا واحدًا من فرع آخر، واترك الباقي.
  2. ينسخ الانتقاء التغيير الذي أجراه إيداع واحد، إيداعًا جديدًا هنا.
  3. للنسخة معرّف جديد، لكنها تحتفظ بالمؤلف والرسالة.
  4. ابنِ أساسًا وفرع بريا بملاحظة وإصلاح، وفرع الإصدار الخاص بك.
  5. افتح المجلد. يعرض المخطط الفرعين من الأساس نفسه.
  6. إصلاح بريا فوق ملاحظة غير متعلقة. نريد الإصلاح وحده.
  7. حدّد الإصلاح. مسار واحد متغيّر: index.html.
  8. تأكد أن release/label هو الحالي وأن مجلد العمل خالٍ.
  9. انقر الإصلاح بزر الفأرة الأيمن واختر انتقاء الإيداع.
  10. لا منتقي فروع. يُطبَّق على الفرع الذي أنت عليه.
  11. على الإيداع الحالي نفسه يكون الأمر معطّلًا.
  12. نفّذه وانتظر النتيجة الفعلية.
  13. إيداع جديد فوق release/label.
  14. يختلف معرّفه عن معرّف بريا لأن أباه مختلف.
  15. ما زالت بريا المؤلفة. والمُودِع هو أنت.
  16. تحمل الصفحة التسمية الموضَّحة.
  17. لم تأتِ الملاحظة غير المتعلقة. وملاحظتك ما زالت هنا.
  18. فرع بريا كما كان تمامًا.
  19. في الطرفية يعرض git log مع التنسيق العنوان والمؤلف والمُودِع.
  20. يسرد git diff-tree المسارات التي غيّرها هذا الإيداع.
  21. الحالة خالية. لم يُترك شيء.
  22. بخيار x تسجّل الرسالة من أين جاء الانتقاء.
  23. انتقِ الإيداع نفسه مرة أخرى فيتوقف Git: الانتقاء فارغ.
  24. غيّر المُدخل: الهدف بلا نموذج التسجيل.
  25. يتوقف الانتقاء بتعارض. حلّه وتابع، أو أوقف.
  26. قد يعتمد التغيير على إيداعات لم تأخذها. اختبر الهدف.
  27. يعيد الإيقاف الفرع. ولا يُعدَّل المصدر أبدًا.
  28. تدريب: اذكر المعرّف الجديد والمؤلف والمُودِع والملفات.
  29. التالي: اترك العمل غير المنتهي جانبًا بأمان بالمخبأ.