أدوات مساحة العمل

قواعد المستودع (.gitcito.json)

كل مشروع يحمل قواعد لا يمكن استنتاجها من الشيفرة. لا تدفع أبداً مباشرة إلى release/*. نطاقات الكوميت هي api وweb وinfra ولا شيء غيرها. تحتاج إلى Node 20 ووحدات فرعية مسحوبة وملف .env منسوخ من .env.example قبل أن يعمل أي شيء. هذه القواعد تعيش في ملف README لا يعيد أحد قراءته، أو في فشل تكامل مستمر، أو في ذهن من قضى هنا أطول وقت.

.gitcito.json هو المكان الذي يكتبها فيه المستودع نفسه كي يتصرف الأداة وفقها. يقع في جذر المستودع، ويُلتزم به مثل أي ملف آخر، ولذلك يسافر مع النسخة: كل من يفتح المشروع يحصل على القواعد نفسها، ومن انضم حديثاً يحصل عليها في يومه الأول لا عند أول دفع مرفوض.

الملف اختياري تماماً. المستودع الذي لا يملكه يتصرف تماماً كما كان.

لست مضطرًا لكتابته يدويًا: تُعطى دردشة المستودع مخطط هذا الملف، فيعود أضف روابط تذاكر لـ JIRA-1234 أو احمِ فروع الإصدار على هيئة إجراء ملف يمكن مراجعته.

تبويب Config في المستودع، مع صفوف الطبيب وأقسام القواعد

أين يُحرَّر

الترس بجانب أدوات الشريط ← Config. هذا المحرر يكتب الملف في شجرة عملك؛ ولا يُحفظ في أي مكان آخر، لذا اعمل له كوميت لمشاركة القواعد مع الفريق.

إن لم يكن للمستودع ملف بعد، يقترح اقرأ المستودع واحداً مما هو موجود أصلاً: .nvmrc أو engines.node، و.gitmodules، وfilter=lfs في .gitattributes، و.env.example بلا .env بجانبه، والفروع التي تحميها محلياً بالفعل، والنطاقات التي استخدمتها آخر 500 عنوان كوميت. لا يُكتب شيء حتى تحفظ. ومن الطرفية يفعل gitcito config init الشيء نفسه (انظر سطر الأوامر).

ما يمكن أن يقوله الملف

{
  "version": 1,
  "protect": ["main", "release/*"],
  "links": {
    "tickets": [
      { "match": "\\b[A-Z][A-Z0-9]+-\\d+\\b", "url": "https://tracker.example.com/browse/$0", "label": "Jira" }
    ]
  },
  "commit": {
    "scopes": ["api", "web", "infra"],
    "ticketFromBranch": true,
    "trailers": ["Refs: {ticket}"]
  },
  "requires": {
    "node": ">=20",
    "hooksPath": ".husky",
    "submodules": true,
    "lfs": true,
    "files": [{ "path": ".env", "from": ".env.example", "why": "عنوان الـ API الأساسي ورمز للتطوير" }]
  },
  "checklist": {
    "push": ["شغّل حزمة اختبارات التكامل على بيئة التجريب"]
  }
}
الحقل ما يفعله
version يجب أن يكون 1. الملف من مخطط أحدث يُتجاهل بالكامل بدل تخمينه.
protect أسماء فروع، و* يطابق أي نص. تُضاف فوق الفروع التي تحميها محلياً — انظر الفروع المحمية.
links.tickets تعبير نمطي وقالب عنوان. $0 هو المطابقة كاملة و$1…$9 مجموعاتها. المطابقات في عناوين الكوميت ومتونها تصبح روابط.
commit.scopes النطاقات التي يعرضها المؤلِّف بدل حقل نصي حر. إعلانها يحوّل أيضاً النطاق غير المعروف في gitcito commit-check من نصيحة أسلوب إلى خطأ.
commit.ticketFromBranch يملأ مفتاح التذكرة من اسم الفرع (feature/ABC-123-thing ← ABC-123) — لكن في مؤلِّف فارغ فقط، ولا يكتب أبداً فوق ما تكتبه.
commit.trailers أسطر تُضاف إلى متن الكوميت. يُملأ {ticket} و{branch}؛ والسطر الذي لا يجد ما يملأ عنصره النائب يُسقط بدل أن يُكتب ناقصاً.
requires.* ما تحتاجه نسخة عاملة. كل مدخل يصبح صفاً في الطبيب أدناه.
checklist.push نص حر يُعرض مرة واحدة في الجلسة قبل أول دفع.

الطبيب

requires هو الجزء الذي يجيب على «استنسخته ولا يعمل». يفحصه Gitcito عند فتح المستودع ويعرض شارة سماعة طبية في شريط الحالة حين يكون هناك خلل. النقر عليها يفتح تبويب Config عند صفوف الطبيب، وافحص مجدداً يعيد تشغيلها.

الفحص ينجح حين يُصلَح بـ
node يحقق node الموجود في PATH المواصفة —
submodules لا وحدة فرعية بلا سحب git submodule update --init --recursive
lfs git-lfs مثبّت والملفات المتتبعة محتوى حقيقي لا نص مؤشر git lfs pull
hooksPath يطابق core.hooksPath المسار المعلن ضبط core.hooksPath
files الملف موجود نسخه من from إن وُجد

حدّان مقصودان. التحذير لا يعني «معطوب» أبداً؛ يعني أن الطبيب لم يستطع تحديد شيء (مواصفة Node غير مقروءة تمرّ بدل اختلاق فشل لا تستطيع التصرف حياله)، والتحذيرات لا تُفشل gitcito doctor في التكامل المستمر. والإصلاح ليس أبداً شيئاً قدّمه الملف: المجموعة أعلاه هي المجموعة كاملة، مغلقة وقت الترجمة. الإعداد يسلّمها قيمة — مساراً للنسخ، قيمة لـ core.hooksPath — لا أمراً.

نسخ ملف لا يكتب فوق شيء أبداً: غياب الملف هو بالضبط سبب وجود ذلك الصف.

الكوميتات

مع إعلان commit.scopes، يعرض زر النطاق في المؤلِّف تلك القائمة بدل حقل حر — وهو الفرق بين feat(renderer) وfeat(rendererr). ويملأ ticketFromBranch و trailers الأجزاء الآلية من الرسالة، بينما يعيد links.tickets تحويل المفاتيح إلى روابط في كل مكان يُعرض فيه الكوميت.

القواعد نفسها تسري خارج النافذة: يقرأ gitcito commit-check هذا الملف، فيفرض خطاف commit-msg والتكامل المستمر ما يقترحه المؤلِّف بالضبط. انظر سطر الأوامر والكوميت.

قائمة ما قبل الدفع

يظهر checklist.push كتأكيد قبل أول دفع في الجلسة، سطراً لكل بند. هذا مكان ما يحتاج فعلاً إلى حكم بشري — هل أبلغ أحد فريق الدعم؟ — لأن Gitcito لا يتحقق منها عنك أبداً. هي تذكيرات لا بوابات: تقرأها وتدفع، أو تلغي. تُعرض مرة واحدة لكل مستودع في كل جلسة، لأن حواراً يظهر مع كل دفع هو حوار لا يقرأه أحد.

لماذا لا يستطيع إيذاءك

يصل الملف مع المستودع، أي ممن كتب المستودع. لذا يُعامل كمحتوى غير موثوق، تماماً كرسالة كوميت:

  • لا شيء فيه يُنفَّذ. لا يوجد حقل يحمل أمراً، وإصلاحات الطبيب قائمة ثابتة.
  • لا يستطيع إلا إضافة قيود. protect اتحاد مع قائمتك المحلية — يستطيع المستودع أن يحمي أكثر مما اخترت، ولا يستطيع أبداً أن يثنيك عن حماية شيء. ولا حقل يُطفئ حارساً.
  • المسارات لا تستطيع مغادرة المستودع. المسارات المطلقة و.. و~ وحروف الأقراص وكل ما يمس .git مرفوضة، ويُعاد فحصها عند النقطة التي يصير فيها النص مساراً حقيقياً.
  • الروابط يجب أن تكون http(s). ولا يُسلَّم غيرها لفاتح الروابط في النظام.
  • كل شيء محدود بسقف — أطوال القوائم والنصوص والأنماط — كي لا يستطيع مستودع عدائي لصق جدار نص في حوار ولا ألف شارة في لوحة.

الحقل الفاسد يُسقط ولا يكون قاتلاً. بقية الملف تبقى سارية، وما أُسقط يُدرج تحت تجاهله Gitcito في تبويب Config مع السبب. الاستثناء الوحيد هو JSON غير صالح أو version غير معروفة، حيث لا شيء يمكن إنقاذه.

ما لا يفعله عمداً

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

انظر أيضاً: إعدادات المستودع · سطر الأوامر · الكوميت · الخطافات و .gitignore

حسّن هذه الترجمة على GitHub