٥، ١٠، رعاية مشروع
— تطبيق الرقع من البريد
إذا وصلتك رقعة من البريد الشابكي وتريد دمجها في مشروعك، فعليك تطبيقها في فرع موضوع حتى تنظر فيها.
في جت أمران لتطبيق الرقع الآتية من البريد: git apply للرقع المجردة، و git am للرقع بالصيغة البريدية.
أمر تطبيق الرقع المجردة apply
إذا وصلتك رقعة ناتجة من برنامج git diff أو إحدى نسخ برنامج diff اليونكسي (وهذا ليس مستحَبًّا؛ انظر الفصل التالي)، فيمكنك تطبيقها بأمر git apply.
بفرض أنك حفظها في ملف /tmp/patch-ruby-client.patch، يمكنك تطبيقها هكذا:
$ git apply /tmp/patch-ruby-client.patch
هذا يعدّل ملفات مجلدك الحالي.
يكاد هذا يطابق تنفيذ أمر patch -p1 لتطبيقها، لكن أمر جت شكاك وصارم فيقبل تطابقات جزئية أقل مما يقبل أمر patch.
وإنه يتعامل مع إضافة الملفات وحذفها ونقلها، إذا كانت موصوفة بصيغة فروقات جت (git diff). وهذا لا يفعله patch.
وآخر فرق هو أن أمر جت git apply إما يطبق الرقعة كلها وإما يتراجع عنها كلها. لكن patch يستطيع تطبيق الرقع جزئيا، فيترك ملفاتك في حالة غريبة.
فعموما أمر جت حريص ومحافظ أكثر من أمر patch.
ولن يصنع لك إيداعًا؛ بعد تنفيذ أمر تطبيق الرقع المجردة من جت، عليك تأهيل التغييرات بنفسك وإيداعها.
يمكنك كذلك أن تستعمله للتحقق أن الرقعة ستطبق بنظافة قبل تطبيقها فعلًا؛ نفّذ git apply --check على ملف الرقعة:
$ git apply --check 0001-see-if-this-helps-the-gem.patch
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
إذا لم يعطك ناتجًا، فيمكن تطبيق الرقعة بنظافة. وإن فشل التحقق، فهذا الأمر كذلك ينهي تنفيذه بقيمة خروج غير الصفر، حتى تستعمله في البُريمجات إن أردت.
أمر تطبيق الرقع البريدية am
إذا كان المساهم يستخدم جت وكان لطيفًا واستعمل أمر تنسيق الرقع git format-patch لإنشاء رقعته، فإن مهمتك أيسر لأن الرقعة تحوي لك معلومات المؤلف ورسالة الإيداع.
فإذا استطعت أن تحُثّ مساهميك على استعمال أمر تنسيق الرقع من جت بدلًا من أمر الفروق (git diff، أو diff اليونكسي)، فافعل.
فلا تستعمل أمر تطبيق الرقع المجردة git apply إلا للرقع الأثرية وأشباهها.
لتطبيق رقعة أنشأها أمر تنسيق الرقع format-patch، استعمل أمر تطبيق الرقع البريدية git am. (اسمه am لأنه لتطبيق (“apply”) سلسلة من الرقع من صندوق بريد شابكي (“mailbox”).)
ونظريا، git am صُمِّم ليقرأ ملف mbox، وهو صيغة نصية ميسورة لتسجيل رسالة أو عدة رسائل بريدية في ملف نصي واحد.
وتشبه هذا:
From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
From: Sameera Samara <sameera@example.com>
Date: Sun, 6 Apr 2008 10:17:23 -0700
Subject: [PATCH 1/2] Add limit to log function
Limit log functionality to the first 20
هذا أول ناتج أمر تنسيق الرقع الذي رأيته في فصل المساهمة السابق. وهو أيضا موافق لصيغة mbox.
فإذا أرسل إليك أحدٌ رقعةً كما ينبغي: بأمر إرسال البريد git send-email، ونزّلتَ هذه الرسالة بصيغة mbox، فيمكنك إذًا أن تنفذ git am على هذا الملف، وسيبدأ في تطبيق جميع الرقع التي يجدها فيه.
وإذا كان تطبيق عميل بريدك يستطيع حفظ عدة رسائل بصيغة mbox، فتستطيع حفظ سلسلة كاملة من الرقع في ملف واحد ثم تنفيذ أمر تطبيق الرقع البريدية git am عليه لتطبيقها واحدةً واحدة.
وإذا رفع أحدٌ ملف الرقعة المصاغ بأمر تنسيق الرقع، إلى نظام متابع علل أو نحوه، فتستطيع حفظ الملف إلى جهازك وتنفيذ أمر تطبيق الرقع البريدية عليه:
$ git am 0001-limit-log-function.patch
Applying: Add limit to log function
نرى أن الرقعة طبّـقت بنظافة وأنشئ لك إيداعًا جديدًا.
أخذ جت معلومات المؤلف من خانة المرسِل (From:) وخانة التاريخ (Date:) اللذين في ترويسة البريد، وأنشأ رسالة الإيداع من عنوان البريد (Subject:) ومن الجزء السابق للرقعة في متن البريد (“body”).
مثلا إذا كانت هذه الرقعة هي المثال الذي ذكرناه عن صيغة mbox قبل قليل، فإن إيداعها سيكون مثل هذا:
$ git log --pretty=fuller -1
commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0
Author: Sameera Samara <sameera@example.com>
AuthorDate: Sun Apr 6 10:17:23 2008 -0700
Commit: Scott Chacon <schacon@gmail.com>
CommitDate: Thu Apr 9 09:19:06 2009 -0700
Add limit to log function
Limit log functionality to the first 20
معلومات المودِع (Commit) تبيّن الذي طبّـق الرقعة ومتى طبّـقها.
ومعلومات المؤلف (Author) تبين الذي صنع التعديلات نفسها وأنشأ الرقعة، ومتى أنشأها.
لكن من الوارد ألا تطبق الرقعة بنظافة. ربما تفرّق فرعك الرئيس وشطّ بعيدًا عن الفرع الذي بُنيت الرقعة عليه. وربما تعتمد هذه الرقعة على رقعةٍ أخرى لم تطبّـقها بعد. فعندئذٍ سيفشل أمر التطبيق وسيسألك ماذا تريد أن تفعل:
$ git am 0001-see-if-this-helps-the-gem.patch
Applying: See if this helps the gem
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
Patch failed at 0001.
When you have resolved this problem run "git am --resolved".
If you would prefer to skip this patch, instead run "git am --skip".
To restore the original branch and stop patching run "git am --abort".
وهو يضع لك علامات التنازع في أي ملف فيه مشكلة، تمامًا مثلما الحال عند النزاع أثناء الدمج أو إعادة التأسيس.
وتحله بالطريقة نفسها: تحرر الملفات لحل النزاع، وتأهّلها، ثم تنفذ git am --resolved للانتقال إلى الرقعة التالية.
$ (أصلح الملف)
$ git add ticgit.gemspec
$ git am --resolved
Applying: See if this helps the gem
وإذا أردت أن يحاول جت حل النزاع ببعض الذكاء، فأعطه الخيار -3، الذي يجعله يحاول إجراء دمجٍ ثلاثي.
لا يفترض جت هذا الخيار لأنه لا يعمل إن لم يكن في مستودعك الإيداع الذي تقول الرقعة أنها مبنية عليه.
إذا كان لديك ذلك الإيداع (أي أن الرقعة مبنية على إيداع عمومي) فإن الخيار -3 عموما يجعل جت أذكى كثيرا عند تطبيق رقعة فيها نزاع:
$ git am -3 0001-see-if-this-helps-the-gem.patch
Applying: See if this helps the gem
error: patch failed: ticgit.gemspec:1
error: ticgit.gemspec: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.
في حالتنا هذه، بغير الخيار -3 فإن الرقعة كانت ستكون «متنازِعة».
لكن بالخيار -3 استطاع جت تطبيقها بنظافة.
إذا كنت تطبق عددًا من الرقع من ملف mbox، فيمكنك تطبيقها تفاعليًّا، ليقف الأمر قبل كل رقعة ليسألك إذا ما كنت تريد تطبيقها؛ هذا بالخيار --interactive أو اختصاره -i:
$ git am -3 -i mbox
Commit Body is:
--------------------------
See if this helps the gem
--------------------------
Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all
هذا جميل إذا كان لديك عددٌ من الرقع المحفوظة، لأنك عندئذٍ تستطيع رؤية الرقعة أولا إن لم تتذكرها، وكذلك ألا تكرر تطبيقها إذا كنت قد فعلت سابقًا.
عندما تفرغ من تطبيق كل الرقع وتودِعها في فرع الموضوع، ابدأ في النظر فيما إذا كنت تريد دمجها في فرعٍ طويل العمر، وكيف.