الدرس 10 · العمل اليومي
صِل بعيدًا وعيّن الفرع المتتبَّع دون خلط بينهما
أضف origin محليًا مجردًا، واجلب فرعه main، ثم اختر عمدًا ما يتتبَّعه main المحلي. أثبت أن اسم البعيد ومرجع التتبُّع وإعداد الفرع المتتبَّع أشياء مختلفة.
- المستوى: متوسط
- قراءة 10 دقائق
- فيديو 6 دقائق
- آخر تحديث
- قبل هذا الدرس: أنشئ فرع الميزة واحذف المرجع التجريبي وحده
حُفظ التقدّم في هذا المتصفح.
يحمّل التشغيل الفيديو من YouTube (وضع الخصوصية المحسّنة).
ما ستتعلمه
- التمييز بين origin وorigin/main وإعداد تتبُّع main.
- تحديد ما يغيّره إضافة البعيد والجلب واختيار الفرع المتتبَّع.
- توصيل GitTree بمستودع محلي مجرد حقيقي دون بيانات اعتماد مزوّد.
- إثبات بقاء فرع الميزة محليًا دون نشره.
قبل البدء
تبدأ من حيث انتهى الدرس التاسع، في أصل gittree-features. الفرع المسحوب feature/pricing-cards يحمل إيداع البطاقات F1؛ ولـ main خمسة إيداعات حتى وثيقة التاريخ H5. العمل والفهرس خاليان من التغييرات، ولا بعيد، وdist مُتجاهَل. هذه فروع المشروع التعليمي، لا فرع مستودع الويب.
سُجّل الفيديو باستخدام Git 2.52.0 وGitTree 2.0 على Ubuntu 24.04: الوثيقة والبعيد والجلب والمتتبَّع جرت في التطبيق، أما الوجهة المجردة وحالة الإضافة بلا جلب والفحوص فنُفّذت في الطرفية. لم يُشغَّل شيء على macOS أو Windows، وUbuntu هو نظام Linux الوحيد المسجَّل؛ اختصارات مفتاح Command مأخوذة من خريطة مفاتيح التطبيق. الحد الأدنى المقروء لـ GitTree هو Git 2.39.0. بعد تسجيل الدخول يكون العمل المحلي وتعيين التتبُّع ضمن الخطة المجانية؛ تكامل المزوّد ميزة مختلفة.
احجز وجهة مجاورة غير موجودة باسم gittree-features-origin.git خارج مستودعات المصدر. لا تستبدل مجلدًا موجودًا. ستحتوي نسخة مجردة من main، لا GitLab أو خدمة نسخ احتياطي أو مشغّل CI. إذا كانت الوجهة موجودة، توقّف وحددها بدل حذفها.
لإثبات حالة الإضافة قبل الجلب، عطّل الجلب الخلفي في مستودع التسجيل وحده: التفضيلات (Preferences) بـ Command+, (وCtrl+, على Ubuntu)، ثم صفحة gittree-features التي تحمل اسم المستودع. في فاصل الجلب التلقائي (Auto-fetch interval) أدخل 0، ثم تطبيق (Apply)، وانتظر Saved، ثم الخروج من التفضيلات (Exit Preferences). يحفظ التطبيق هذا في إعداداته الخاصة بكل مستودع، لا في إعداد Git. دوّن القيمة السابقة لاستعادتها لاحقًا دون تغيير الإعداد العام أو أي مستودع آخر.
الفكرة
البعيد إعداد محلي يربط اسمًا بعنوان وقواعد جلب. origin اسم متعارف عليه لا سلطة مركزية داخل Git. لا تتصل الإضافة بالوجهة، ولا تنشئها أو تدفع فرعًا إليها.
مرجع التتبُّع البعيد refs/remotes/origin/main سجل محلي يحدّثه الجلب. ليس هو فرع الخادم refs/heads/main. بعد الإضافة وحدها لا يوجد origin/main. يجلب Fetch الكائنات والمراجع دون تبديل HEAD أو دمج أو إعادة تأسيس أو استبدال الصفحة.
الفرع المتتبَّع (Upstream branch) علاقة إعداد لفرع محلي. هنا branch.main.remote = origin وbranch.main.merge = refs/heads/main. لا ينشئ اختيارها إيداعًا ولا يجلب تاريخًا ناقصًا ولا ينشر feature/pricing-cards.
فكّر في عنوان تحفظه، ورسالة جلبتها آخر مرة، ومحادثة تختار متابعتها. حفظ العنوان ليس إرسالًا أو استقبالًا.
أثر الأفعال
| الفعل | مجلد العمل والفهرس | المراجع والإعداد المحلي | الخادم |
|---|---|---|---|
| التبديل إلى main | ملفات H5 | يرتبط HEAD بـ main | لا تغيير |
| إيداع الوثيقة | يطابقان H6 | يتقدم main إلى H6 | لا تغيير |
| إعداد النسخة المجردة | الأصل ثابت | لا origin في الأصل بعد | main مستقل عند H6 |
| إضافة بعيد | لا تغيير | عنوان origin وقاعدة الجلب | لا تغيير |
| جلب الكل (Fetch All) | لا تغيير | يظهر origin/main عند H6 | قراءة فقط |
| تعيين المتتبَّع | لا تغيير | إعداد علاقة main | لا تغيير |
يبقى F1 على فرع الميزة المحلي. بعد وثيقة main يوجد إيداع مستقل على كل طرف من H5؛ لا دمج بينهما.
تغيير المشروع كاملًا
بدّل إلى main قبل إنشاء docs/remotes.md. احفظ النص كاملًا بصيغة UTF-8 ونهايات LF وسطر نهائي:
# GitTree Features remotes
origin names a separate local bare repository used only for this course.
Its file:// URL is a transport address, not a GitLab project or a login.
main tracks origin/main after an explicit fetch and upstream selection.
origin/main is a local record of the last fetched remote main.
Adding a remote does not fetch, push or publish any branch.
feature/pricing-cards remains local and has no upstream in this checkpoint.
No credentials or machine-specific absolute paths are stored in this document.الملخّص docs: record remotes-and-upstreams practice. المؤلف والمُودِع GitTree Demo <demo@example.com>. لا تُدخل دفتر تدريب ثانٍ أو إيداعًا إضافيًا في هذه النقطة.
في GitTree
تُذكر التسميات الإنجليزية حرفيًا لتحديد التحكم في المصدر؛ تُلتقط الواجهة العربية الفعلية عند الإنتاج مع مراجعة قاموس المنتج.
- في الأصل، انقر main المحلي بزر الفأرة الأيمن → التبديل إلى main (Checkout main). تظهر صفحة عصر وثيقة التاريخ دون قسم سير العمل، والحالة خالية. إن ظهر حوار تبديل مع عمل غير محفوظ، اختر إلغاء (Cancel) وافحصه.
- افتح لوحة الأوامر بـ Command+Shift+P (وCtrl+Shift+P على Ubuntu). اختر ملف جديد… (New File…)، واكتب docs/remotes.md في المسار من مجلد المشروع (Path from the project folder)، ثم إنشاء (Create). الصق النص كاملًا وحفظ (Save) أو Command+S، وانتظر الحفظ.
- العودة إلى الرسم البياني (Back to Graph) → لوحة الأوامر عرض تغييرات مجلد العمل (Show Working Changes). راجع الوثيقة وتجهيز الملف (Stage File)، ثم الملخّص المحدد في الملخّص (Summary) مع الوصف (Description) خالٍ والخيارات العادية معطلة. إيداع تغييرات ملف واحد (Commit Changes to 1 File) مرة واحدة، أو Command+Enter كبديل. أثبت سادس إيداع على main.
- أعدّ النسخة المجردة بأوامر T1. هذه تهيئة أصلية بالطرفية، لا زرًا مختلقًا لإنشاء مشروع استضافة في التطبيق.
- احصل على عنوان file:// الفعلي بـ T2. يقبل محلل GitTree المقروء عنوان ملف، لا المسار المجرد الذي قد يقبله Git الأصلي. تُرمَّز المسافات في العنوان. لا تلصق أمر shell في حقل URL.
- لوحة الأوامر إضافة مستودع بعيد… (Add Remote…) → إضافة مستودع بعيد (Add a remote). أدخل الاسم (Name) = origin وعنوان URL (URL) = العنوان المقاس، ثم إضافة مستودع بعيد (Add Remote). لا حقل Push URL منفصلًا في الإضافة؛ يظهر عند تحرير المستودع البعيد… (Edit Remote…). لا تتوقع origin/main بعد.
- اجلب من لوحة الأوامر بـ جلب الكل (Fetch All؛ Command+Shift+F، وCtrl+Shift+F على Ubuntu). قبل هذا الجلب الأول لا تعرض مجموعة Remote في اللوحة الجانبية origin أصلًا، فلا صف للنقر عليه؛ ولأن البعيد واحد يجلبه جلب الكل (Fetch All). انتظر النتيجة الفعلية. يظهر origin/main عند SHA نفسه لـ main دون تبديل HEAD أو الملفات.
- انقر main المحلي بزر الفأرة الأيمن، وافتح القائمة الفرعية الفرع المتتبَّع (Upstream)، ثم اختر تعيين الفرع المتتبَّع… (Set Upstream…). في ماذا يتتبّع main؟ (What should main track?) اختر الفرع المتتبَّع (Upstream branch) = origin/main ثم تتبُّع (Track). هذا فعل على مرجع مسمّى، لا أمر لوحة عام. إلغاء (Cancel) لا يغيّر العلاقة؛ لا تختَر عدم تتبُّع أي فرع (Track Nothing) هنا.
- نفّذ فحوص T3 وT4. اترك main مسحوبًا والميزة موجودة محليًا دون نشر. لا تضغط Push أو Pull أو Force Push… أو حذفًا بعيدًا لإكمال الاتصال.
الخيارات العادية معطلة: تعديل الإيداع الأخير (Amend Previous Commit)، وتخطّي الخطّافات (Skip Hooks)، وإضافة Signed-off-by (Add Signed-off-by)، ومؤلف مختلف (Different Author)، والدفع بعد الإيداع (Push After Commit)، والسماح بإيداع فارغ (Allow Empty Commit)؛ دون مؤلفين مشاركين. انتظر نجاح الإيداع ولا ترسله مرتين.
في الطرفية
الأوامر داخل المشروع المعزول gittree-features، لا أي مستودع مصدر. أفعال الطرفية والتطبيق بدائل؛ لا تُعد عملية نجحت بالفعل.
T1 — الوثيقة وتهيئة main وحده في النسخة المجردة
بعد حفظ الوثيقة على main:
git switch --quiet main
git add -- docs/remotes.md
git commit --quiet -m "docs: record remotes-and-upstreams practice"
git clone --quiet --bare --single-branch --branch main --no-local . ../gittree-features-origin.gitنجحت الأوامر بصمت. تنشئ النسخة وجهة جديدة لفرع main وحده، ولا تضيف origin إلى الأصل. يتجنب --no-local اختصار ربط ملفات الكائنات محليًا. لا أمر دفع في هذه التهيئة.
إذا أودع التطبيق الوثيقة، فتجاوز أول ثلاثة أوامر ولا تنشئ إيداعًا مكررًا.
T2 — العنوان ثم الإضافة والجلب والتتبُّع
ORIGIN_URL="$(node --input-type=module -e "import path from 'node:path'; import {pathToFileURL} from 'node:url'; console.log(pathToFileURL(path.resolve('../gittree-features-origin.git')).href);")"
printf '%s\n' "$ORIGIN_URL"يخرج عنوان file فعليًا ينتهي بـ /gittree-features-origin.git. يختلف جذر المسار حسب الجهاز؛ file://<lab-root>/gittree-features-origin.git شرح فقط، لا خرج طرفية مختلق أو عنوان حرفي للصق. ORIGIN_URL متغير shell لا بيانات اعتماد.
git remote add origin "$ORIGIN_URL"
git config --get remote.origin.fetch
git for-each-ref --format='%(refname)' refs/remotes/originالإضافة صامتة. خرج استعلام قاعدة الجلب:
+refs/heads/*:refs/remotes/origin/*لا يخرج استعلام المراجع الأخير شيئًا؛ لم تجلب الإضافة الفروع.
git fetch --quiet origin
git branch --set-upstream-to=origin/main mainنجح الجلب بصمت، ثم خرج التتبُّع الفعلي:
branch 'main' set up to track 'origin/main'.T3 — إثبات النهاية في الأصل
git symbolic-ref --short HEAD
git rev-parse --abbrev-ref 'main@{upstream}'
git rev-list --left-right --count main...origin/main
git log -1 --format=%s origin/main
git rev-list --count main
git status --shortخرج أول خمسة استعلامات بالترتيب:
main
origin/main
0 0
docs: record remotes-and-upstreams practice
6الحالة القصيرة الأخيرة خالية، والخروج 0. يفصل Tab الصفرين: الإيداعات الخاصة بـ main والخاصة بـ origin/main. لا يعني اتفاق الطرفين أن معرفتك ستظل حديثة دون جلب.
T4 — المستودع المجرد مقابل السجل المحلي
git --git-dir=../gittree-features-origin.git rev-parse --is-bare-repository
git --git-dir=../gittree-features-origin.git for-each-ref --format='%(refname)' refs/heads
git ls-remote --heads origin refs/heads/feature/pricing-cards
git config --get branch.feature/pricing-cards.remoteالأول true، والثاني refs/heads/main، والثالث صامت بخروج 0: لم يُنشر فرع الميزة. الرابع صامت بخروج 1 لغياب إعداد تتبُّع الميزة؛ هذا الغياب المتوقع ليس فشل جلب.
احسم الأطراف الثلاثة مستقلًا:
git rev-parse refs/heads/main
git rev-parse refs/remotes/origin/main
git --git-dir=../gittree-features-origin.git rev-parse refs/heads/mainتتفق SHAs الحقيقية الثلاثة. لا تستبدلها بالرمز التعليمي H6.
النتيجة
حيث تنتهي: main مسحوب وله ستة إيداعات، وآخرها docs/remotes.md وحده. الوجهة المجردة المحلية تضم main عند H6 نفسه. الأصل يملك origin ومرجع origin/main المجلوب، وmain يتتبَّعه. العمل والفهرس خاليان مع احتمال وجود dist المتجاهَل. الميزة المحلية عند F1 دون فرع متتبَّع أو فرع في الوجهة. لا دمج أو سحب أو مشروع استضافة أو حساب أو CI.
أخطاء شائعة
- اعتبار origin خادمًا خاصًا داخل Git بدل اسم محلي.
- توقع إنشاء الوجهة أو جلبها بمجرد إضافة مستودع بعيد (Add Remote).
- إدخال مسار عارٍ بدل عنوان file في حقل التطبيق.
- استخدام بعيد عمل حقيقي أو عنوان يحمل رمز وصول أو مجلد موجود مسبقًا.
- إيداع الوثيقة على الميزة بدل main.
إن حدث خطأ
قبل الجلب، اختُبر في إعادة منفصلة:
git -c advice.setUpstreamFailure=false branch --set-upstream-to=origin/main mainstderr الفعلي، خروج 128:
fatal: the requested upstream branch 'origin/main' does not existلم يتحرك الطرف أو العمل. بحسب مصدر التطبيق (دون تصوير) لا تتوفر في GitTree خيارات مجلوبة ويُعطّل تتبُّع (Track) مع لا توجد فروع تتبُّع بعيدة بعد. اجلب أولًا. (There are no remote-tracking branches yet. Fetch first.) لا تحوّل الرسالة الأصلية إلى حوار تطبيق مزيف. اجلب البعيد المقصود ثم عيّن origin/main عمدًا. في هذا الدرس يكون ذلك بـ جلب الكل (Fetch All).
إذا فشل المسار أو الإذن، ألغِ وافحص تحرير المستودع البعيد… (Edit Remote…) والوجهة الفعلية. لا تستخدم دفعًا قسريًا أو تعطيل الحماية. إذا وجد origin مسبقًا فافحصه بدل استبداله أو إزالته بلا مراجعة. إزالة إعداد بعيد محلية ولا تحذف مستودع الوجهة، وليست مطلوبة هنا.
اختبر فهمك
أجب عن كل سؤال ثم اقرأ السبب. الأسئلة المعلَّمة «مطلوب» تُحتسب لإكمال الدرس.
0 من 6 صحيحة
أجب عن الأسئلة المطلوبة إجابة صحيحة لتكمل الدرس.
جرى التحقق في هذا المتصفح.
تدريب
اشرح غياب origin/main مباشرةً بعد الإضافة. في نسخة منفصلة حاول تعيينه قبل الجلب، ثم اجلب وعيّنه بنجاح. أثبت ثبات SHA لـ main وكامل بايتات index.html خلال تغييرات الإعداد. في الأصل تحقق من اتفاق main والطرف المجلوب وغياب الميزة من الوجهة.
تأكيد منك أنت: لا يستطيع الموقع رؤية جهازك.
لإكمال الدرس، أجب عن الأسئلة المطلوبة إجابة صحيحة وأكّد تنفيذ التمرين العملي.
خلاصة
- يحفظ البعيد عنوانًا، ويجلب Fetch المراجع، وتختار علاقة التتبُّع فرعًا.
- origin/main معرفة محلية مجلوبة لا فرع الخادم نفسه.
- لم ينشر الاتصال الميزة أو يغيّر صفحتها.
ذو صلة
المصطلحات الجديدة
Remote — مستودع بعيد؛ remote-tracking ref — مرجع تتبُّع بعيد؛ upstream — الفرع المتتبَّع؛ bare repository — مستودع مجرد؛ fetch — جلب؛ transport — وسيلة نقل.
نص الفيديو
ترجمة التعليق الصوتي الإنجليزي للفيديو، مقطعًا بعد مقطع.
اعرض النص
- صِل بعيدًا، ثم اختر الفرع المتتبَّع عمدًا.
- الميزة موجودة محليًا ولم تُنشر.
- عطّل الجلب الخلفي في مستودع التسجيل هذا وحده.
- بدّل إلى main قبل كتابة وثيقة النقل.
- احفظ الوثيقة كاملة دون مسارات الجهاز أو بيانات اعتماده.
- جهّز وثيقة النقل على main، لا على الميزة.
- تضيف الوثيقة سادس إيداع على main.
- أعدّ نسخة مجردة مستقلة من main للنقل المحلي.
- تضم الوجهة main، لا فرع الميزة.
- الأصل والوجهة المجردة مستودعان منفصلان.
- ولّد عنوان file للوجهة المحلية المقصودة.
- حفظ العنوان لا يجلب فروعًا ولا يرفع الميزة.
- افتح حوار البعيد في المستودع الأصلي.
- سمّه origin وتحقق من الوجهة كاملة.
- أُعدّ البعيد، ولم يُجلب فرعه بعد.
- توجد قاعدة الجلب واستعلام مرجع التتبُّع خالٍ.
- يفشل اختيار المتتبَّع الغائب دون تحريك main.
- هل يغني اختيار المتتبَّع عن الجلب؟ لا.
- اجلب main البعيد دون تبديل فرعك الحالي.
- origin/main سجل محلي مجلوب لديك.
- الجلب ليس دمجًا أو إعادة تأسيس أو استبدال الصفحة.
- اختر العلاقة لفرع main المحلي المسمّى.
- اختيار القيمة وحده ليس تأكيدًا للعلاقة.
- أكّد متتبَّع main دون تحريك إيداعه.
- تحقّق من main ومتتبَّعه واتفاق الطرفين وخلو العمل.
- غياب الميزة من الخادم لا يعني فقدانها محليًا.
- العنوان والسجل المجلوب وإعداد التتبُّع أشياء مختلفة.
- صحّح اختيار المتتبَّع دون إعادة تعيين التاريخ.
- تحقّق من الأصل والخادم كلًّا على حدة قبل المتابعة.
- اشرح لماذا احتاج المرجع الغائب جلبًا، لا دفعًا.
- البعيد المحلي المجرد ليس مشروع استضافة أو مسار CI.
- اجلب لاحقًا تحديث زميل مع إبقاء ملفاتك دون تغيير.