ثمّة نسختان من git تبدوان شبه غير مترابطتين.
الأولى هي git بوصفه تراجعًا لمشروع كامل — تعمل commit كلما تقدّمت، فيمكن استعادة أيّ حالة سابقة بدقّة. تلك النسخة فردية، تعيش كليًا على جهازك، وهي سبب كون السماح لوكيل بتعديل ملفاتك أمرًا معقولًا أصلًا. وتجدها في الـ version control (git)، وإن كنت تعمل وحدك فهي حقًّا كل ما تحتاجه.
أمّا النسخة الثانية فتبدأ في اللحظة التي يعتمد فيها شخص آخر على المشروع. هنا لا يكون التغيير شيئًا تصنعه فحسب؛ بل شيئًا تُنزِله — معزولًا في مكان آمن، ومقترَحًا لا مفروضًا، ومراجَعًا، ثم مطويًّا عن قصد. ستّ حركات إضافية، وهذه الصفحة هي كلها.
ويستحقّ توزيع الأدوار أن يُقال في البداية، لأنه ما يجعل هذا في المتناول: Claude ينفّذ كل أمر git؛ وكل قرار حكم لك أنت. أهذا commit واحد أم اثنان؟ أهذه الرسالة صادقة؟ أهذا جاهز لأن يصير علنيًا؟ أالمراجع محقّ؟ لا شيء من ذلك آليّات، ولا شيء منه قابل للتفويض.
1. أنشئ branch
الـ branch نسخة رخيصة قابلة للرمي من المشروع كله، تجرّب فيها دون أن تمسّ النسخة التي يعتمد عليها الجميع.
هو «حفظ باسم» قبل أن تبدأ التعديل بجرأة، إلا أنه فوري ومجاني. النسخة الرئيسية — واسمها main — تبقى تعمل تمامًا كما كانت. وbranchك كون موازٍ. فإن نجحت التجربة طويتها عائدًا؛ وإن انحرفت حذفت الـ branch وكأنه لم يكن.
أنشئ branch لإصلاح نموذج التواصل
make a branch for the contact form fix
هذه هي شبكة الأمان تحت كل ما في هذه الصفحة، وهي ما يجعل «دع Claude يجرّب» تعليمةً معقولة لا متهوّرة. فعلى branch يمكنك أن تدع Claude يحاول شيئًا جريئًا — إعادة هيكلة كبيرة، أو إعادة كتابة محفوفة — وإن تحوّل الأمر إلى فوضى فلست تفكّ كل تغيير بعناية. بل تهجر الـ branch. وmain لم يرَ شيئًا من ذلك. الـ branch امتصّ الفوضى كلها.
والكلمة الوحيدة التي تستحقّ أن تستقرّ في ذهنك هي main: الجذع، والنسخة التي تُعدّ حقيقية. وكل ما عداها متدلٍّ منها، ينتظر إمّا أن ينضمّ وإمّا أن يُرمى.
2. commit لفكرة واحدة في كل مرة
إن تُرك وشأنه، سيسعد Claude بحزم كل ما لمسته بعد الظهر في commit واحد. قاوم ذلك.
الـ commit الجيّد تغيير متماسك واحد. فصول في كتاب، لا تفريغ يوميات يومي.
والسبب ليس الترتيب بل تراجعك أنت. فالتراجع عن commit نظيف فقط إن كان ذلك الـ commit شيئًا واحدًا. اخلط إصلاح نموذج التواصل مع إعادة صياغة عنوان لا صلة لها، وحين يتبيّن بعد أسبوع أن إعادة الصياغة خاطئة لن تستطيع إزالتها دون أن ترمي معها إصلاح الخلل الراكب إلى جانبها.
أنت تضع الحدّ؛ وClaude يتولّى التجهيز:
اعمل commit لإصلاح نموذج التواصل فقط — واترك إعادة صياغة العنوان لـ commit منفصل
commit just the contact form fix — leave the headline reword for a separate commit
ثم ألقِ نظرة على الرسالة التي يصوغها. الرسالة الجيّدة تقول ما تغيّر ولماذا، في جملة يسرّك أن يقرأها غريب بعد ستة أشهر: «ارفض رسائل التواصل ذات الاسم الفارغ بدل إسقاطها بصمت.» وClaude يكتب هذه أفضل ممّا يكلّف معظم الناس أنفسهم عناءه. ومهمّتك أن تتأكّد فقط أنها صادقة وكاملة، لأنك أنت من يعرف ما فعلتَه فعلًا.
الشيء الذي يجب ألّا يبلغ commit أبدًا
هذا يستحقّ قسمًا خاصًّا لا هامشًا، لأنه الخطأ الوحيد في هذه الصفحة الذي لا يمكنك التراجع عن عواقبه.
الـ secrets لا مكان لها في git. ملفات .env، وAPI keys، وكلمات المرور، وaccess tokens، وروابط database تحمل بيانات اعتماد — أيّ شيء ما كنت لتلصقه في محادثة علنية.
تاريخ git دائم بحكم التصميم. والـ secret الذي يقع في commit يبقى فيه إلى الأبد، حتى لو حذف الـ commit التالي مباشرةً ذلك الملف. وبعد دفعه، عليك أن تفترض أن أحدهم يملكه.
هذا هو الخطر كله: الآليّة التي تجعل git جديرًا بالثقة — أن لا شيء يُفقَد حقًّا — هي بعينها ما يجعل الـ secret المدفون في commit غير قابل للاسترداد. فحذفه لاحقًا يزيله من الحالة الراهنة، لا من التاريخ.
والحماية ملف اسمه .gitignore يسرد ما ينبغي ألّا يتتبّعه git أبدًا. ولست مضطرًّا إلى كتابته من الذاكرة. قبل أول commit في مشروع جديد، اسأل:
هل هنا أيّ شيء لا ينبغي أن يدخل git؟ أنشئ .gitignore إن كان الأمر كذلك.
is anything here that shouldn't go into git? Set up a .gitignore if so.
وإن كان شيء قد أفلت سلفًا: لا تلجأ إلى جراحة التاريخ أولًا. دوِّر بيانات الاعتماد — أبطِل القديمة وأصدِر جديدة — لأن تلك هي الخطوة التي تجعل الأمر غير مؤذٍ فعلًا، وهي تنفع سواء استنسخ أحد الـ repository أم لا. أمّا تنظيف التاريخ فثانٍ واختياري.
3. الـ push — الخطّ بين الخاص والعلني
وهنا ما يفاجئ الجميع تقريبًا: كل commit عملته حتى الآن خاصّ. موجود على حاسوبك ولا مكان غيره. زميلك لا يراه. وجهاز ثانٍ تملكه أنت لا يراه.
هناك نسختان من المشروع: نسختك (local) والنسخة المشتركة على GitHub (الـ remote). الـ commits تتراكم محليًا؛ وpush يرسلها إلى الـ remote، وpull يجلب إليك ما عند الآخرين.
ادفع هذا الـ branch
push this branch
الـ push باب من نوع مختلف عن الـ commit. فالـ commit المحلي ملكك تمامًا — أعِد كتابته، أو احذفه، فلم يره أحد. أمّا حين تبلغ commits النسخة المشتركة فيستطيع الآخرون سحبها والبناء فوقها والاعتماد عليها، ولا يمكنك أن تعيد الجرس إلى صمته بنظافة. إنه one-way door، ويستحقّ نصف الثانية من الانتباه الذي يستحقّه أيّ one-way door.
وهو أيضًا بالضبط سبب كون الـ secret المدفوع مكشوفًا لا محرجًا فحسب.
ولا شيء من هذا يجعل الـ push خطرًا — ستفعله باستمرار. لكن لا شيء يغادر جهازك حتى تأمر أنت، ومعرفة أن الصمت يعني ما زال خاصًّا هي نصف النموذج.
4. افتح pull request
الـ branch لديك على GitHub الآن، لكنه جانبًا. وmain ما زال بلا تغييراتك. كان بإمكانك أن تدمج branchك مباشرةً. أمّا في مشروع فيه أشخاص آخرون فلا تفعل.
الـ pull request يقول: هذا تغييري، راجعوه قبل أن يدخل المشروع الحقيقي.
والاسم يُقرأ معكوسًا — فأنت تطلب من المشروع أن يسحب branchك. وهو عمليًا صفحة تعرض الـ diff الخاص بك، ووصفًا يشرح التغيير، ومساحة ليعلّق الناس، كل ذلك قبل أن يُدمج شيء.
وما يمنحك إياه فوق الدمج الذاتي أمران: توقّف متعمَّد للمراجعة، وسجلّ دائم لـ سبب حدوث التغيير.
افتح pull request لهذا الـ branch
open a pull request for this branch
يقرأ Claude كل commit على الـ branch، ويكتب العنوان والوصف، ويفتح الـ PR، ويسلّمك الرابط. ولاحظ العلاقة بين نوعَي الكتابة هنا: رسائل الـ commit تشرح كل خطوة على حدة؛ أمّا وصف الـ PR فيتراجع إلى الوراء ليشرح التغيير كله دفعةً واحدة — ماذا يفعل، ولماذا لزم، وما ينبغي أن يعرفه المراجع قبل أن ينظر. اقرأه قبل أن يخرج. فأنت من يعرف أهو جاهز فعلًا.
5. تعامل مع المراجعة
يراجعه أحدهم — زميل، أو فحص آلي، وأحيانًا Claude نفسه في جولة مراجعة — ويترك تعليقات. قد يسرّب هذا ذاكرة. أعِد تسمية هذا للوضوح. ينقصك اختبار هنا. ولكثير من الناس، هذا هو الجزء الذي يبدو حكمًا.
وليس كذلك. تعليق المراجعة مجرّد نوع آخر من الـ prompt.
عالِج تعليقات المراجعة على هذا الـ PR
address the review comments on this PR
لا تبدأ من جديد ولا تفتح PR جديدًا. التغييرات تذهب على الـ branch نفسه؛ تعمل commit وتدفع، فيلتقط الـ pull request المفتوح الـ commits الجديدة تلقائيًا. يتحدّث في مكانه.
لكن لا تتخطَّ الحكم. ليس كل تعليق صحيحًا. فقد يخطئ المراجع. وقد يسيء Claude قراءة ما يطلبه التعليق. التعليق جزء من نقاش، وأنت تقرّر أيّها تنفّذ وأيّها تعترض عليه معلّلًا. و*«التقاط موفّق، أُصلح»* و*«أبقيتها كما هي لأن الحالة الفارغة تُعالَج قبل هذا الموضع»* كلاهما جواب كامل ومهني. والتجاهل الصامت هو الخيار السيّئ الوحيد، لأن الخلاف يعود حينها عند الدمج.
6. ادمج، ثم احذف الـ branch
يوافق المراجع. تدمج الـ pull request، والآن صار في main أخيرًا التغيير — مراجَعًا ومسجَّلًا ومرتبطًا بالنقاش الذي أنتجه. وقد أدّى الـ branch عمله، فتحذفه.
وإن كان الـ branchان قد غيّرا الأسطر نفسها، فسيبلّغ git عن merge conflict بدل أن يخمّن. يبدو ذلك منذرًا وليس كذلك؛ هو امتناع git عن اتخاذ قرار ليس قراره. الصق الـ conflict عند Claude واسأله ماذا كان يحاول كل طرف — فشرح النيّة خلف تعديلين متنافسين هو بالضبط نوع القراءة التي يبرع فيها.
الحلقة كلها، على تغيير حقيقي واحد
الخلل: نموذج التواصل يُسقط رسالة بصمت حين يترك الزائر حقل الاسم فارغًا. handleContact لا يحفظ شيئًا ولا يعلم الزائر بذلك أبدًا.
- أنشئ branch. «أنشئ branch لإصلاح نموذج التواصل.» و
main— النسخة العاملة الآن — سليم مهما حدث بعد ذلك. - أصلِح واعمل commit لفكرة واحدة. يصلح Claude
handleContact. وتعمل commit لـ ذلك فقط — لا للخطأ المطبعي غير المتّصل الذي لمحته أيضًا في صفحة «عنّا». - افحص الرسالة. «ارفض رسائل التواصل ذات الاسم الفارغ بدل إسقاطها بصمت.» صادقة، ومحدودة النطاق، وتشرح السبب. جيّدة.
- ادفعه. صار عملك على GitHub. ولم يُقترح شيء بعد؛ أنت فقط أخرجته من حاسوبك المحمول.
- افتح الـ PR. يكتب Claude الوصف. وتتأكّد أنت أنه صادق. وصار اقتراحًا يراه الجميع.
- تعامل مع المراجعة. يلاحظ مراجع أن الإصلاح يرفض الاسم الفارغ لكنه ما زال يمرّر بريدًا فارغًا. يعدّل Claude، وتدفع أنت، فيتحدّث الـ PR ذاتيًا. وقد وافقت على أن الالتقاط صحيح — ولو لم توافق لقلت ذلك في الخيط.
- ادمج ونظّف. موافَق عليه، ومدموج، والـ branch محذوف. انتهى.
انظر إلى ذلك. لا خطوة واحدة كانت ذكية. الـ branch جملة. والـ commit جملة. وفتح الـ PR جملة. ومنفردةً، لا شيء منها يبهر أحدًا.
أمّا مجتمعةً فهي الفرق بين أن تأمل أن التغيير آمن للإطلاق وأن تعرف ذلك: معزولًا على branch، ومقسَّمًا إلى commits نظيفة، ومقترَحًا للمراجعة، ومدموجًا عن قصد. والانقسام يصمد حتى النهاية — Claude نفّذ كل أمر، وكل قرار احتاج إلى إنسان مرّ بك أنت.