في هذا الموضوع سأحاول أن اشرح برنامج git بشكل موجز، البرنامج ضخم وذو إمكانات كثيرة اجهل جلها لكن تعلمت بعض الأساسيات التي أود مشاركتكم بها. البرنامج كان فكرة وتطوير “لينوس تورفالدز” مخترع نواة اللينكس حيث كانت الأدوات البديلة المفتوحة وقتها لا تفي بمتطلبات مشروع ضخم مثل نواة اللينكس وكانو يستخدمون تطبيق مغلق وغير مجاني.
في البداية أريد أن أوضح أن git ليس github و github عبارة عن تطبيق ويب يعتمد على git ويوفر مساحة تخزينية للمشاريع. وتستطيع عمل مشاريعك وادارتها على خادمك الخاص او خادم الشركة باستخدام git دون الحاجة لgithub.
توجد عدد من الواجهات الرسومية للتعامل مع git إما تطبيقات مستقلة أو مدمجة في تطبيقات البرمجة IDE لكن من تجربتي لا يوجد تطبيق رسومي شامل وتحتاج بين الفينة والأخري لاستخدام الأمر git من سطر الأوامر لتنفيذ مهام معينة.
الفكرة الاساسية من git
ملفات التطبيق تكون محفوظة محليا على جهاز المطور (كل مطور) والتعديلات لا تعتبر نهائية إلى بعد أن تعمل لها commit، وتلك العملية تنفذ محليا كذلك ويحتفظ جهاز المطور على الإصدارات السابقة قبل عملية ال commit لكي يستطيع الرجوع لها.
إذا رغب المطور في رفع التعديلات للخادم لكي تحفظ بشكل نهائي او ليراها باقي المطورين فان يقوم بعملية الرفع او الدفع push. في تلك الحالة يتم رفع التغييرات ودمجها مع ملفات الخادم. في حال وجود تعارض كون احد المطورين قد قام برفع ملفات مسبقا فيها تغييرات تتعارض مع التغيرات الجديدة فان الخادم سيرفض عملية الرفع الجديدة وينبه المطور عن نقاط التعارض ويطلب منه إصلاحها ثم رفع الطلب مرة اخرى.
إذا أراد احد المطورين سحب التحديثات الأخيرة من الخادم إلى جهازه محليا فانه يقوم بعملية السحب pull حيث يرسل الخادم الملفات المعدلة منذ اخر عملية سحب قام بها هذا المطور. قد يحصل تعارض كذلك أثناء عملية السحب في حال أن المطور قد قام بعمل تعديلات محلية ولم يرفعها للخادم وكان احد الملفات المسحوبة هو نفس الملف المعدل محليا فهنا يطلب التطبيق من المطور أن يقوم بعملية الدمج merge بحيث يراجع المطور التغييرات ويعدلها بما بناسب (بعض التطبيقات الرسومية تجعل عملية الدمج سهلة جدا)
- الشرح السابقة يخص المطوريين الذين لديهم صلاحيات التعديل على نفس المشروع، لكن من نقاط القوة في نظام git هي امكانية مساهمة الغير في تطوير المشاريع المفتوحة.
المساهمة في المشاريع المفتوحة
في المشاريع المفتوحة التي تستخدم نظام القت مثل المشاريع على موقع github او نواة اللينكس او KDE فإن الجميع لديهم صلاحيات القراءة وتستطيع نسخ المشروع لجهازك باستخدام امر الاستنساخ clone مع رابط المشروع
1 | $ git clone <رابط_المشروع> |
فيقوم بنسخ ملفات المشروع لجهازك في مجلد بالاسم الافتراضي (يمكنك تحديد اسم اخر إذا أردت)
- رابط مشاريع القتهب تجده موجود على نفس صفحة المشروع
و إذا أردت لاحقا تحديث ملفات المشروع فكل ما عليك هو سحب الملفات الجديدة بالأمر pull، قم بالدخول لمجلد المشروع الأساسي (ليس المجلدات الفرعية) ثم نفذ
1 | $ git pull |
وتستطيع تعديل الملفات (لأنها محلية) لكن لا تستطيع رفعها للخادم لأنك لا تملك صلاحيات كتابة. فالحل هو أن تقوم بإنشاء نسخة خاصة بك على الخادم وتسمى تشعُّب fork بحيث تكون خاصة بك وتستطيع الكتابة عليها لكنها ليست مرتبطة بالنسخة الرئيسة وتحتاج أن تقوم بتحديثها بنفسك إذ هي مرتبطة بملفاتك المحلية. المشروع الرئيسي يسمى upstream و مشروعك على الخادم يسمى origin وكلاهما يعتبر remote وملفاتك المحلية local
فعندما تقوم بعمل fork على القتهب فهو يقوم بإنشاء مشروع جديد ونسخ ملفات المشروع الرئيسي له دون أن يتأثر المشروع الرئيسي والتعديلات والحذف التي تقوم بها كلها على مشروعك فقط. بعد عملية التشعب fork تقوم بنسخ الملفات محليا كما فعلنا في السابق لكن الآن المشروح موجود تحت حسابك وليس حساب المطور الأساسي:
1 | $ git clone <رابط_نسختك> |
لتحديث ملفات مشروعك لاحقا على الخادم ليطابق المشروع الأساسي في حال تم تحديثه تقوم بسحب التعديلات من المشروع الأساسي ثم رفعها لمشروعك على الخادم:
1 | $ git pull <رابط_المشروع_الأساسي> master |
كلمة master تدل على الفرع الرئيسي وبالإمكان استخدام فروع اخرى
الفروع
كل مشروع يحتوي على فرع واحد على الأقل وهو الفرع الرئيسي ويسمى غالبا master لكن الكثير من المشاريع تحتوي على عدة فروع مثلا فرع أساسي للكود المستقر وفرع للتطوير develop و فروع اخرى لتجارب المطورين أو اختبارات مؤقتة أو حالات خاصة. والتنقل بين الفروع محليا يكون باستخدام أمر checkout
1 | $ git checkout master |
فتستطيع عمل تغييرات ثم دمجها في فرع التطوير ثم الانتقال لفرع الرئيس وستختفي التغييرات لان تلك التغييرات دمجت فقط في فرع التطوير.
طريقة تقديم تغييراتك للمشروع الرئيسي
لنفرض انك تريد المساهمة في مشروع تطبيق تعلم العربية للاندرويد:
https://github.com/fduraibi/FunWithArabic_Android
http://aosus.org/t/topic/275
- قم في البداية بعمل fork من خلال القيتهب وسينشيء نسخة بنفس اسم المشروع لكن تحت حسابك انت
- قم بعمل نسخة محلية clone لنسختك انت (ستجد الرابط في نفس صفحة نسختك باسم حسابك وليس حساب المشروع الرئيسي)
- ا ذا أردت التعديل فالأفضل إنشاء فرع جديد وليكن اسم الفرع يدل على التعديل أو الإضافة لتسهل عليك إدارتها لاحقا مثلا أردت إصلاح علة في فتح قاعدة البيانات فقم بإنشاء فرع محلي كالتالي:
1 | $ git checkout -b patch_fix_db |
هذا الامر سينشي فرع باسم patch_fix_db وسيتحول لذلك الفرع. لمعرفة الفروع الموجودة في المشروع المحلي وأي منها مفعل اكتب التالي
1 | $ git branch |
ستكون المخرجات كالتالي (في حال لا يوجد سوى فرعك الجديد مع الفرع الرئيسي)
1 | master |
- علامة النجمة
*
تدل على ان هذا الفرع هو المفعل حاليا
للانتقال لفرع اخر موجود مسبقا قم بالتالي:
1 | $ git checkout <اسم_الفرع> |
لحذف فرع محلي:
1 | $ git branch -d <اسم_الفرع> |
لنفرض انك أنشأت فرع patch_fix_db وقمت بتعديل الملفات وتريد ان ترى حالة التغييرات فنفذ الامر التالي:
1 | $ git status |
صورة لخرج الامر (وتجد تعليمات من git توضح طريقة تنفيذ الأوامر الافتراضية):
الملفات باللون الاحمر تعني انها جديدة او معدلة ولم تدرج بعد. الملف في الاعلى ملف متابع وموجود من الاصل لكن تم تعديله ولم يدرج التعديل. الملفين في الأسفل (ملف ومجلد) ملفات جديدة وغير متابعة من الأساس أي أنها ليست موجودة في الأصل.
يتم إضافة الملفات بالأمر add، فانا أريد إضافة الملف المعدل لكن لا أريد إضافة الملفيين الاخريين (لانهما مؤقتين فقط او اي سبب اخر)
1 | $ git add FunWithArabic_app/src/main/java/net/fadvisor/funwitharabic/DataBaseHelper.java |
- امر git ذكي ويمكن استخدام رز tab لاستكمال اسم الملف المعدل، ضغط رز tab سيقوم بعرض الملفات المعدلة فقط.
الناتج بعد اضافة الملف:
نجد ان الملف تحول للون الأخضر فنحتاج بعدها الى اعتماد التعديل بالامر commit
1 | $ git commit |
ذلك الامر سيطلب منك كتابة شرح او تعليل تبين فيه مالذي قمت به في هذا التعديل، الشرح سيظهر في القيتهب، اضغط حرف i ثم اكتب الشرح وبعد الانتهاء اضغط زر الهروب Esc
ثم اكتب **wq:**
للحفظ والخروج (مثل التعامل مع برنامج vi او vim)
الآن قم برفع التغييرات لمشروعك على خادم القتهب (سيتم إنشاء فرع بنفس الاسم المدخل إذا لم يكن موجودا على الخادم):
1 | $ git push origin patch_fix_db |
- سيطلب منك ادخال اسم المستخدم وكلمة السر الخاصة بالقتهب
قم بزيارة مشروعك على القتهب وسترى التالي في الجزء العلوي من الصفحة:
قم بالضغط على زر Compare & pull request وسيقوم بعرض الاختلاف بين تعديلاتك وبين الأصل وسيطلب منك كتابة شرح للتعديل (سيتم استخدام الشرح الذي كتبته في السابق لكن تستطيع تعديله والزيادة عليه إن أردت) عندما تنتهي من التعديل اضغط على زر Create pull request هنا انتهى دورك تقريبا حيث سيفتح طلب التعديل في المشروع الأساسي ويبقى دور من لهم صلاحيات في المشروع الأساسي في مراجعة عملك وقبوله أو رفضه أو أن يطلبو منك تبرير أو تعديل في حال التعارض مع تعديلات اخرى.
- لو قمت بتعديلات تحت نفس الفرع لاحقا فإنها ستدرج مباشرة مع الطلب القائم لذلك إذا كانت التعديلات الجديدة ليس لها علاقة بالتعديل السابق بل تخص علة أو إضافة جديدة فقم بإنشاء فرع جديد لها.
في حال قمت بتعديل لملف معين ثم أردت إلغاء التعديلات والعودة للنسخة الأصلية قبل أن تقوم بعمل commit فقم بالتالي:
1 | $ git checkout -- <اسم_الملف> |
لإلغاء جميع التغييرات:
1 | $ git checkout -- . |
لحذف فرع من على الخادم:
1 | $ git push origin :<اسم_الفرع> |