كيفية استخدام Git وسير العمل في Git: دليل عملي للمبتدئين والمحترفين

دقائق القراءة: 12

مقدمة: لماذا يعد Git مهارة أساسية لأي مطور؟

يُجمع معظم العاملين في تطوير البرمجيات على أن تعلم Git لم يعد خياراً ثانوياً، بل أصبح من المهارات الأساسية لأي شخص يعمل ضمن فريق تقني أو يدير مشروعاً برمجياً باحتراف. ومع ذلك، فالحقيقة أن التعامل مع Git قد يبدو معقداً في البداية، خصوصاً عند الانتقال من الحفظ النظري للأوامر إلى فهم طريقة عملها فعلياً داخل المشروع.

أفضل طريقة لاكتساب هذه المهارة ليست الغرق في التفاصيل منذ اليوم الأول، بل البدء باستخدام الأداة في مواقف عملية حقيقية. ومع الوقت، تصبح المفاهيم مثل الفروع، وعمليات الدمج، ورفع التعديلات، ومزامنة المستودعات أكثر وضوحاً وسهولة.

في هذا الدليل العملي، سنتدرج خطوة بخطوة لبناء فهم متين لكيفية استخدام Git والتعاون عبر GitHub، مع شرح المفاهيم المهمة عند الحاجة، دون تعقيد غير ضروري.

دليل عملي لاستخدام Git وGitHub وإدارة سير العمل البرمجيرسم توضيحي يعبر عن الفروع والتنقل داخل Git Workflow

ماذا ستتعلم في هذا الدليل؟

  • تثبيت Git وإعداد حساب GitHub
  • إنشاء مستودع جديد على GitHub
  • نسخ المشروع محلياً باستخدام git clone
  • فهم الفروع في Git
  • فحص حالة المشروع عبر git status
  • إنشاء أول commit ورفعه إلى GitHub
  • استخدام منطقة التجهيز staging area
  • قراءة الفروقات عبر git diff
  • التعاون الجماعي باستخدام الفروع وطلبات السحب Pull Request
  • تحديث النسخة المحلية باستخدام git fetch وgit pull
  • حل تعارضات الدمج merge conflicts

كيفية تثبيت Git وإعداد حساب GitHub

قبل البدء، تحتاج إلى تجهيز بيئة العمل الأساسية:

  1. تثبيت Git على جهازك.
  2. إنشاء حساب على GitHub أو استخدام خدمة مشابهة مثل GitLab أو Bitbucket.
  3. إعداد مفتاح SSH حتى تتمكن من رفع التعديلات من جهازك إلى المستودع البعيد بأمان.

فائدة مفتاح SSH أنه يثبت لهوية المنصة أن من يقوم بعملية الرفع هو المستخدم المصرح له فعلاً، مما يجعل العمل أكثر أماناً وأسهل من الاعتماد على إدخال بيانات الدخول في كل مرة.

إنشاء مستودع جديد على GitHub

بعد تسجيل الدخول إلى GitHub، أنشئ مستودعاً جديداً بالضغط على زر New repository. بعد ذلك اختر:

  • اسم المستودع
  • ما إذا كان عاماً Public أو خاصاً Private
  • إضافة ملف README اختيارياً

ثم اضغط على Create repository.

واجهة إنشاء مستودع جديد على GitHubإعدادات تهيئة مستودع GitHub جديد

نسخ المستودع محلياً باستخدام git clone

عند إنشاء المستودع، تأتي الخطوة التالية وهي تنزيل نسخة محلية من المشروع إلى جهازك. يتم ذلك باستخدام الأمر git clone:

$ git clone git@github.com:johnmosesman/practical-git-tutorial.git
Cloning into 'practical-git-tutorial' ...
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (6/6), done.

هذا الأمر يقوم بتنزيل ملفات المشروع وبياناته الوصفية إلى مجلد جديد داخل المسار الحالي. بعد ذلك انتقل إلى المجلد:

$ cd practical-git-tutorial/
/practical-git-tutorial (main)$

ظهور (main) في الطرفية يعني أنك تعمل حالياً على الفرع الرئيسي المسمى main.

ما هي الفروع في Git؟

الفرع branch هو نسخة مستقلة من المشروع عند نقطة زمنية معينة. يمكنك إجراء تغييرات عليها دون التأثير في الفروع الأخرى. هذه الفكرة أساسية جداً في العمل الجماعي، لأنها تسمح لكل مطور بالعمل على مهمة محددة بمعزل عن بقية التعديلات.

تخيل أنك تكتب كتاباً، حينها يمكن أن تكون لديك الفروع التالية:

  • main
  • table-of-contents
  • chapter-1
  • chapter-2

يبقى الفرع main هو النسخة الأساسية المستقرة، بينما تستخدم الفروع الأخرى لتطوير أجزاء محددة ثم دمجها لاحقاً.

قد ترى أحياناً الفرع باسم master بدلاً من main في بعض المشاريع القديمة، ولا يوجد فرق وظيفي جوهري بينهما، وإنما هو اختلاف في التسمية فقط.

فحص حالة المشروع باستخدام git status

من أكثر الأوامر استخداماً في Git الأمر git status لأنه يعطيك نظرة سريعة على حالة المشروع:

(main)$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean

هذا الإخراج يخبرك بثلاثة أمور مهمة:

  • أنت تعمل على الفرع main.
  • نسختك المحلية متطابقة مع النسخة البعيدة origin/main.
  • لا توجد تغييرات محلية غير محفوظة في السجل.

ما المقصود بـ origin؟

origin هو الاسم الافتراضي للمستودع البعيد الذي تم نسخ المشروع منه. وغالباً ما يكون مستودعك على GitHub. يمكنك التحقق من ذلك عبر:

(main)$ git remote -v
origin  git@github.com:johnmosesman/practical-git-tutorial.git (fetch)
origin  git@github.com:johnmosesman/practical-git-tutorial.git (push)

بهذا تعرف أن جهازك المحلي مرتبط بمستودع بعيد اسمه origin، وأنه يمثل المصدر المرجعي للمشروع.

إنشاء أول تعديل وحفظه في Git

لننشئ ملفاً جديداً ونجري عليه أول تعديل:

(main)$ touch chapter-1.txt
(main)$ echo "Chapter 1 - The Beginning" >> chapter-1.txt
(main)$ cat chapter-1.txt
Chapter 1 - The Beginning

إذا فحصنا الحالة الآن:

(main)$ git status
On branch main
Your branch is up to date with 'origin/main'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	chapter-1.txt

nothing added to commit but untracked files present (use "git add" to track)

الملف يظهر ضمن Untracked files، أي أن Git يراه موجوداً لكنه لا يتابعه بعد.

إضافة الملف إلى التتبع باستخدام git add

(main)$ git add chapter-1.txt

يمكنك أيضاً استخدام git add . لإضافة جميع التغييرات داخل المجلد الحالي.

بعد ذلك تصبح التغييرات جاهزة للتثبيت في السجل:

(main)$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   chapter-1.txt

تنفيذ أول commit

الـ commit يمثل وحدة عمل مكتملة منطقياً. بدلاً من حفظ كل ضغطة مفتاح، أنت تحفظ مرحلة ذات معنى يمكن الرجوع إليها لاحقاً. لتنفيذ ذلك:

(main)$ git commit -m "New chapter 1 file with chapter heading"
[main a8f8b95] New chapter 1 file with chapter heading
 1 file changed, 1 insertion(+)
 create mode 100644 chapter-1.txt

من أفضل الممارسات كتابة رسالة واضحة تشرح ما الذي تغير ولماذا. الرسائل الجيدة توفر وقتاً كبيراً عند مراجعة السجل لاحقاً.

استعراض السجل باستخدام git log

(main)$ git log

يعرض هذا الأمر جميع عمليات commit السابقة بترتيب زمني عكسي. ولكل عملية معرف فريد يعرف باسم SHA، وهو بصمة رقمية تميز كل نقطة في تاريخ المشروع.

رفع أول commit إلى GitHub

بعد إنشاء commit محلياً، ما زال GitHub لا يعرف شيئاً عنه. لرفع التعديلات إلى المستودع البعيد استخدم:

(main)$ git push origin main

هذا يعني: ادفع التغييرات من الفرع المحلي main إلى الفرع البعيد main داخل origin.

بعد نجاح العملية، يصبح المستودع البعيد محدثاً، ويمكن لبقية أعضاء الفريق جلب تلك التعديلات والعمل عليها.

إضافة تعديل جديد إلى ملف موجود

لنضف سطراً جديداً إلى الملف نفسه:

(main)$ echo "It was the best of times, it was the worst of times" >> chapter-1.txt
(main)$ cat chapter-1.txt
Chapter 1 - The Beginning
It was the best of times, it was the worst of times

إذا فحصنا الحالة:

(main)$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   chapter-1.txt

no changes added to commit (use "git add" and/or "git commit -a")

هنا يخبرك Git أن لديك تغييرات محلية لم تُنقل بعد إلى منطقة التجهيز.

ما هي منطقة التجهيز staging area؟

منطقة التجهيز مرحلة وسيطة بين ملفاتك المعدلة وبين تنفيذ commit. فائدتها كبيرة لأنها تمنحك تحكماً دقيقاً في تحديد ما الذي تريد تضمينه في الحفظ وما الذي تريد تأجيله.

(main)$ git add .
(main)$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   chapter-1.txt

الآن أصبحت التغييرات جاهزة للتثبيت. لكن يمكن أيضاً تعديل الملف مرة أخرى بعد إضافته إلى staging area، وهنا تظهر قوة Git في الفصل بين التغييرات المجهزة وغير المجهزة.

(main)$ echo "New file contents" > chapter-1.txt
(main)$ cat chapter-1.txt
New file contents
(main)$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   chapter-1.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   chapter-1.txt

هذا يعني أن لديك إصداراً من التغييرات داخل staging area، وإصداراً أحدث ما زال فقط داخل مساحة العمل المحلية.

عرض الفروقات باستخدام git diff

لفهم ما الذي تغير فعلياً، استخدم git diff:

(main)$ git diff
diff --git a/chapter-1.txt b/chapter-1.txt
index 0450d87..4cbeaee 100644
--- a/chapter-1.txt
+++ b/chapter-1.txt
@@ -1,2 +1 @@
-Chapter 1 - The Beginning
-It was the best of times, it was the worst of times
+New file contents

الأسطر التي تبدأ بـ - تم حذفها، والأسطر التي تبدأ بـ + تمت إضافتها. هذا العرض مفيد، لكنه قد يصبح مرهقاً في المشاريع الكبيرة، لذلك يفضّل كثير من المطورين استخدام أدوات رسومية مثل GitHub Desktop أو غيرها لقراءة الفروقات بسهولة أكبر.

عرض التغييرات المجهزة في أداة رسومية لإدارة Gitعرض التغييرات غير المجهزة في مقارنة ملفات Git

إذا أردت التخلص من التغييرات غير المجهزة والعودة إلى آخر حالة محفوظة:

(main)$ git restore .

وبعدها يمكنك تنفيذ commit للتغييرات المجهزة فقط:

(main)$ git commit -m "Added the intro line to chapter 1"
[main f5b6e2f] Added the intro line to chapter 1
 1 file changed, 1 insertion(+)

ثم رفعها:

(main)$ git push origin main

لماذا يُفضّل عدم العمل مباشرة على الفرع main؟

في المشاريع الفردية الصغيرة قد يكون ذلك مقبولاً، لكن في بيئات العمل الاحترافية يُنصح بعدم تعديل الفرع main مباشرة. السبب أن هذا الفرع يمثل النسخة المرجعية المستقرة للمشروع، وأي خطأ فيه قد يؤثر على جميع أعضاء الفريق.

لهذا السبب تعتمد الفرق التقنية على ما يسمى feature branches، أي فروع مخصصة لكل ميزة أو إصلاح أو تجربة مستقلة.

إنشاء فرع ميزة جديد باستخدام git checkout -b

لننشئ فرعاً جديداً للعمل على الفصل الثاني:

(main)$ git checkout -b chapter-2
Switched to a new branch 'chapter-2'

الآن أصبحت التعديلات الجديدة منفصلة عن main. لننشئ ملفاً جديداً ونحفظه:

(chapter-2)$ touch chapter-2.txt
(chapter-2)$ echo "Chapter 2 - The next chapter" >> chapter-2.txt
(chapter-2)$ git add .
(chapter-2)$ git commit -m "Creates chapter 2 and adds the topic sentence"

يمكنك الآن مراجعة السجل باستخدام git log لتلاحظ أن الفرع الجديد يملك commit خاصاً به لم يصل بعد إلى الفرع الرئيسي.

سير العمل التعاوني في Git

عند العمل الجماعي، يوجد أكثر من أسلوب لإدخال التعديلات إلى الفرع الرئيسي. أكثر الطريقتين شيوعاً هما:

  1. دمج الفرع محلياً داخل main ثم رفع main إلى المستودع البعيد.
  2. رفع فرع الميزة نفسه إلى GitHub ثم فتح Pull Request ومراجعته ودمجه من خلال المنصة.

الطريقة الثانية أفضل غالباً في الفرق، لأنها تضيف طبقة مراجعة وتدقيق قبل نقل التعديلات إلى المصدر الرئيسي.

دمج فرع في Git باستخدام git merge

إذا أردت دمج فرع chapter-2 محلياً داخل main:

(chapter-2)$ git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

(main)$ git merge chapter-2
Updating f5b6e2f..741822a
Fast-forward
 chapter-2.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 chapter-2.txt

بعد نجاح الدمج، ادفع التغييرات إلى GitHub:

(main)$ git push origin main

ثم احذف الفرع بعد انتهاء مهمته:

(main)$ git branch -d chapter-2

استخدام Pull Request في العمل الجماعي

لننشئ فرعاً جديداً باسم chapter-3:

(main)$ git checkout -b chapter-3
(chapter-3)$ touch chapter-3.txt
(chapter-3)$ echo "Chapter 3 - The End?" >> chapter-3.txt
(chapter-3)$ git add .
(chapter-3)$ git commit -m "Adds Chapter 3"

بدلاً من الدمج المباشر، ارفع الفرع نفسه إلى GitHub:

(chapter-3)$ git push origin chapter-3

عندها ينشئ GitHub فرعاً بعيداً مقابلاً، ويمكنك فتح Pull Request لدمج chapter-3 في main.

واجهة إنشاء طلب سحب Pull Request على GitHub

في صفحة Pull Request ستجد عادة:

  • عنواناً يوضح الهدف من التعديل
  • وصفاً يشرح السياق والقرارات التقنية
  • عرضاً مرئياً للفروقات diff

مقارنة التغييرات داخل Pull Request على GitHub

بعد المراجعة، يمكن دمج الطلب عبر الواجهة:

نجاح دمج Pull Request داخل الفرع الرئيسي في GitHub

تحديث النسخة المحلية بعد الدمج على GitHub

بعد دمج Pull Request على المنصة، لا تتحدث نسختك المحلية تلقائياً. يجب عليك تحديثها يدوياً.

أولاً عد إلى الفرع الرئيسي:

(chapter-3)$ git checkout main

ثم اجلب البيانات الجديدة من المستودع البعيد باستخدام git fetch:

(main)$ git fetch
From github.com:johnmosesman/practical-git-tutorial
   741822a..10630f2  main -> origin/main

هذا الأمر لا يغير ملفاتك مباشرة، وإنما يحدث معلومات المستودع المحلي عن حالة الفروع البعيدة.

رسم يوضح عملية إنشاء Merge Commit بعد دمج Pull Request

بعد ذلك يمكن تنفيذ:

(main)$ git status
Your branch is behind 'origin/main' by 2 commits, and can be fast-forwarded.
(use "git pull" to update your local branch)

الآن استخدم git pull لتطبيق التحديثات:

(main)$ git pull origin main
From github.com:johnmosesman/practical-git-tutorial
 * branch            main       -> FETCH_HEAD
Updating 741822a..10630f2
Fast-forward
 chapter-3.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 chapter-3.txt

عملياً، الأمر git pull يجمع بين git fetch وgit merge. لذلك من المفيد أحياناً استخدام git fetch أولاً لفهم ما تغير قبل تطبيقه.

حل تعارضات الدمج في Git

في كثير من الحالات يستطيع Git دمج التغييرات تلقائياً، لكن عندما يغير شخصان السطر نفسه داخل الملف نفسه، يظهر ما يسمى merge conflict.

لنفترض وجود فرع تعاوني باسم chapter-3-collaboration. يمكنك جلبه محلياً ثم الانتقال إليه:

(main)$ git fetch
From github.com:johnmosesman/practical-git-tutorial
 * [new branch]      chapter-3-collaboration -> origin/chapter-3-collaboration

(main)$ git checkout chapter-3-collaboration
Branch 'chapter-3-collaboration' set up to track remote branch 'chapter-3-collaboration' from 'origin'.
Switched to a new branch 'chapter-3-collaboration'

إذا أجريت تعديلاً على الملف chapter-3.txt ثم حاولت الرفع بينما زميلك رفع تعديلاً آخر قبلك، قد ترى رسالة رفض بسبب أن فرعك المحلي متأخر عن الفرع البعيد:

(chapter-3-collaboration)$ git push origin chapter-3-collaboration
To github.com:johnmosesman/practical-git-tutorial.git
 ! [rejected]        chapter-3-collaboration -> chapter-3-collaboration (non-fast-forward)
error: failed to push some refs to 'git@github.com:johnmosesman/practical-git-tutorial.git'

عندها يجب أولاً سحب التعديلات الجديدة:

(chapter-3-collaboration)$ git pull origin chapter-3-collaboration
From github.com:johnmosesman/practical-git-tutorial
 * branch            chapter-3-collaboration -> FETCH_HEAD
Auto-merging chapter-3.txt
CONFLICT (content): Merge conflict in chapter-3.txt
Automatic merge failed; fix conflicts and then commit the result.

كيف يبدو التعارض داخل الملف؟

<<<<<<< HEAD
Chapter 3 - The End Is Only The Beginning
=======
Chapter 3 - The End But Not The Ending
>>>>>>> 2f6874f650a6a9d2b7ccefa7c9618deb1d45541e
This is a sentence.

يشير الجزء العلوي بعد <<<<<<< HEAD إلى تعديلك الحالي، بينما يشير الجزء السفلي بعد ======= إلى تعديل الطرف الآخر. مهمتك هنا أن تختار أحد السطرين أو تدمجهما يدوياً في صياغة نهائية مناسبة، مع حذف جميع العلامات التي أضافها Git.

مثال على صياغة نهائية بعد الحل:

Chapter 3 - The End Is Not The Ending--But Only The Beginning
This is a sentence.

بعد تعديل الملف وحل التعارض:

(chapter-3-collaboration)$ git add .
(chapter-3-collaboration)$ git commit -m "Merge new title from teammate"

ثم ادفع التغييرات من جديد:

(chapter-3-collaboration)$ git push origin chapter-3-collaboration

بهذا تكون قد أنهيت الدمج بنجاح، وأصبح بإمكان زميلك سحب التعديلات الجديدة إلى جهازه.

نصائح عملية لتقليل تعارضات الدمج

  • اجعل الفروع صغيرة ومحددة المهمة.
  • ادمج التغييرات بوتيرة متقاربة بدلاً من تركها لفترات طويلة.
  • حدّث فرعك بانتظام من الفرع الرئيسي.
  • تواصل مع الفريق عندما تعملون على الملفات نفسها.
  • اكتب رسائل commit واضحة لتسهيل فهم ما جرى.

مراجعة سريعة: كيف تبدأ مهمة جديدة في Git؟

  1. انسخ المشروع باستخدام git clone <URL>.
  2. أنشئ فرعاً جديداً من main عبر git checkout -b <BRANCH_NAME>.
  3. نفذ التعديلات المطلوبة في المشروع.
  4. أضف التغييرات باستخدام git add.
  5. أنشئ commit مناسباً عبر git commit.
  6. ارفع الفرع إلى origin باستخدام git push origin <BRANCH_NAME>.
  7. أنشئ Pull Request واطلب المراجعة.
  8. بعد الدمج، عد إلى main واستخدم git pull لتحديث النسخة المحلية.

الخلاصة التقنية

Git ليس مجرد أداة لحفظ الإصدارات، بل نظام متكامل لإدارة التغيير والتعاون البرمجي باحتراف. فهم أوامر مثل git status وgit add وgit commit وgit push وgit pull وgit merge يمنحك أساساً قوياً للعمل الفردي والجماعي. والأهم من ذلك أن الالتزام بسير عمل منظم يعتمد على الفروع وطلبات السحب يقلل الأخطاء، ويرفع جودة المراجعة، ويحافظ على استقرار المشروع مع نمو الفريق والمنتج.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *