مقدمة شاملة في Git وGitHub
في عصر تطوير البرمجيات الحديث، أصبح نظام التحكم في الإصدارات Git ضرورة لا غنى عنها لكل مطور محترف. يوفر Git القدرة على تتبع كل تغيير يطرأ على الكود المصدري، مما يسمح للمطورين بالعودة إلى أي نقطة في تاريخ المشروع واستعادة الملفات المحذوفة أو المعدّلة. تم إنشاء Git عام 2005 بواسطة لينوس تورفالدز، مبتكر نظام Linux، ليكون نظاماً موزعاً سريعاً وفعالاً لإدارة المشاريع من أي حجم.
GitHub هو المنصة السحابية الرائدة لاستضافة مستودعات Git، ويستخدمه أكثر من 100 مليون مطور و4 ملايين مؤسسة حول العالم. يوفر GitHub واجهة ويب سهلة الاستخدام مع أدوات متقدمة للتعاون تشمل Pull Requests ومراجعة الكود وإدارة المشاريع والتكامل المستمر عبر GitHub Actions.
تثبيت وإعداد بيئة Git
التثبيت على الأنظمة المختلفة
# التثبيت على Ubuntu/Debian
sudo apt update && sudo apt install git-all
# التثبيت على CentOS/Fedora
sudo dnf install git-all
# التثبيت على macOS
brew install git
# أو تنزيل المثبّت من git-scm.com
# التحقق من نجاح التثبيت
git --version
# git version 2.43.0
الإعداد الأولي الضروري
بعد تثبيت Git، يجب إعداد هويتك التي ستظهر في كل commit تنشئه. هذه الإعدادات تُخزّن في ملف ~/.gitconfig وتُطبّق على جميع المستودعات:
# إعداد الاسم والبريد الإلكتروني (إلزامي)
git config --global user.name "محمد أحمد"
git config --global user.email "mohammed@example.com"
# إعداد المحرر الافتراضي
git config --global core.editor "code --wait"
# إعداد اسم الفرع الافتراضي
git config --global init.defaultBranch main
# تفعيل الألوان في الطرفية
git config --global color.ui auto
# إعداد أداة حل التعارضات
git config --global merge.tool vscode
# عرض جميع الإعدادات
git config --list --show-origin
المفاهيم الجوهرية في Git
نظام العمل ثلاثي المراحل
يعتمد Git على ثلاث مناطق عمل أساسية يجب فهمها بعمق قبل البدء بالاستخدام الفعلي:
- Working Directory (دليل العمل): هو المجلد الفعلي على جهازك حيث تعدّل الملفات. عندما تفتح مشروعك في المحرر وتبدأ بكتابة الكود، فأنت تعمل في هذه المنطقة. الملفات هنا يمكن أن تكون في ثلاث حالات: غير متتبعة (Untracked) أو معدّلة (Modified) أو غير معدّلة (Unmodified)
- Staging Area (منطقة التجهيز): تُعرف أيضاً بالفهرس (Index)، وهي المنطقة الوسيطة التي تجمّع فيها التغييرات التي تريد تضمينها في الـ commit التالي. هذا يمنحك تحكماً دقيقاً في ما يدخل كل commit بدلاً من حفظ جميع التغييرات دفعة واحدة
- Repository (المستودع): قاعدة بيانات Git التي تخزّن تاريخ جميع اللقطات (commits). ينقسم إلى المستودع المحلي (في مجلد .git) والمستودع البعيد (على GitHub أو خوادم أخرى)
إنشاء مستودع وبدء التتبع
# إنشاء مستودع جديد من الصفر
mkdir my-project
cd my-project
git init
# استنساخ مستودع موجود من GitHub
git clone https://github.com/user/repo.git
# استنساخ فرع محدد فقط
git clone -b develop --single-branch https://github.com/user/repo.git
# استنساخ بعمق محدود (للمستودعات الكبيرة)
git clone --depth 1 https://github.com/user/repo.git
العمليات اليومية الأساسية
تتبع التغييرات وإنشاء اللقطات
تمثل اللقطة (Commit) حالة المشروع في لحظة زمنية محددة. كل commit يحتوي على معرّف فريد (SHA-1 hash) ورسالة وصفية ومعلومات عن المنشئ والتاريخ:
# فحص حالة الملفات
git status
git status -s # عرض مختصر
# إضافة ملفات إلى منطقة التجهيز
git add index.html # ملف محدد
git add src/ # مجلد كامل
git add "*.js" # نمط محدد
git add -A # جميع التغييرات
git add -p # إضافة تفاعلية (جزء من ملف)
# إنشاء commit
git commit -m "feat: إضافة صفحة تسجيل الدخول"
# إضافة وcommit في خطوة واحدة (للملفات المتتبعة فقط)
git commit -am "fix: إصلاح خطأ في التحقق من البريد"
# تعديل آخر commit (الرسالة أو إضافة ملفات)
git commit --amend -m "رسالة محدّثة"
git add forgotten-file.js
git commit --amend --no-edit
استعراض التاريخ والتغييرات
# عرض سجل الـ commits
git log
git log --oneline # سطر واحد لكل commit
git log --oneline --graph --all # رسم بياني للفروع
git log --since="2024-01-01" # حسب التاريخ
git log --author="محمد" # حسب المؤلف
git log -n 5 # آخر 5 commits
git log -- src/app.js # تاريخ ملف محدد
# عرض الفروقات
git diff # تغييرات غير مجهّزة
git diff --staged # تغييرات مجهّزة
git diff HEAD~3..HEAD # آخر 3 commits
git diff branch1..branch2 # بين فرعين
# البحث في تاريخ التغييرات
git log -S "functionName" # البحث عن نص محدد
git blame filename.js # من عدّل كل سطر
إدارة الفروع باحتراف
تُعد الفروع (Branches) من أقوى ميزات Git وأكثرها استخداماً. الفرع هو ببساطة مؤشر خفيف لـ commit معين، مما يجعل إنشاء الفروع والتنقل بينها عملية سريعة للغاية مقارنة بأنظمة التحكم في الإصدارات الأخرى:
# إدارة الفروع
git branch # عرض الفروع المحلية
git branch -a # عرض جميع الفروع
git branch -v # مع آخر commit
# إنشاء والتنقل
git branch feature-auth # إنشاء فرع
git checkout feature-auth # الانتقال إليه
git checkout -b feature-auth # إنشاء + انتقال
git switch -c feature-auth # الطريقة الحديثة
# إعادة التسمية والحذف
git branch -m old-name new-name # إعادة تسمية
git branch -d feature-done # حذف (آمن)
git branch -D feature-abandoned # حذف إجباري
# حذف فرع بعيد
git push origin --delete feature-done
استراتيجيات دمج الفروع
هناك عدة طرق لدمج التغييرات من فرع إلى آخر، ولكل طريقة مزاياها:
# الدمج العادي (Merge)
git checkout main
git merge feature-auth
# الدمج مع إنشاء commit دمج دائماً
git merge --no-ff feature-auth
# إعادة البناء (Rebase) - تاريخ خطي نظيف
git checkout feature-auth
git rebase main
git checkout main
git merge feature-auth # Fast-forward merge
# Rebase تفاعلي لتنظيف الـ commits
git rebase -i HEAD~5
# الأوامر المتاحة:
# pick = الإبقاء
# squash = دمج مع السابق
# reword = تغيير الرسالة
# edit = تعديل
# drop = حذف
# Cherry-pick: نقل commit محدد
git cherry-pick abc1234
حل تعارضات الدمج
تحدث تعارضات الدمج عندما يعدّل مطوران نفس الأسطر في نفس الملف. إليك كيفية التعامل معها خطوة بخطوة:
# عند حدوث تعارض أثناء الدمج
git merge feature-branch
# CONFLICT (content): Merge conflict in app.js
# فتح الملف المتعارض:
<<<<<<< HEAD
const apiUrl = "/api/v2/users";
=======
const apiUrl = "/api/v1/users";
>>>>>>> feature-branch
# اختر الكود الصحيح أو ادمج التغييرات
const apiUrl = "/api/v2/users"; # اخترنا النسخة الأحدث
# بعد حل جميع التعارضات
git add app.js
git commit -m "merge: حل تعارض في مسار API"
# إلغاء عملية الدمج إن أردت
git merge --abort
العمل مع المستودعات البعيدة
إدارة الـ Remotes
# إضافة مستودع بعيد
git remote add origin git@github.com:user/repo.git
# عرض المستودعات البعيدة
git remote -v
# تغيير عنوان المستودع البعيد
git remote set-url origin git@github.com:user/new-repo.git
# إضافة مستودع upstream (للمشاريع المنسوخة fork)
git remote add upstream https://github.com/original/repo.git
المزامنة مع المستودع البعيد
# رفع التغييرات
git push origin main
git push -u origin main # تعيين الفرع الافتراضي
git push --force-with-lease # force push آمن
git push origin --tags # رفع العلامات
# جلب التحديثات
git fetch origin # جلب دون دمج
git pull origin main # جلب + دمج
git pull --rebase origin main # جلب + rebase
# مزامنة Fork مع المشروع الأصلي
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
سير عمل Pull Requests
تُعد Pull Requests القلب النابض للتعاون على GitHub. إليك سير العمل الاحترافي الكامل:
- إنشاء فرع: أنشئ فرعاً وصفياً من develop أو main مثل
feature/user-profileأوfix/login-validation - العمل والـ Commits: نفّذ التغييرات مع commits صغيرة ومركّزة تتبع معيار Conventional Commits
- رفع الفرع: ارفع فرعك إلى GitHub باستخدام
git push origin feature/user-profile - فتح PR: أنشئ Pull Request مع عنوان واضح ووصف تفصيلي يشمل ما تم تغييره ولماذا وكيفية اختباره
- مراجعة الكود: يراجع أعضاء الفريق الكود ويتركون تعليقات واقتراحات للتحسين
- معالجة الملاحظات: عدّل الكود بناءً على المراجعة وارفع commits إضافية
- الاختبارات: تأكد من نجاح جميع اختبارات CI/CD التلقائية
- الدمج: بعد الموافقة، ادمج PR باستخدام Squash and merge أو Rebase and merge حسب سياسة الفريق
Git Stash وإدارة العمل المؤقت
عندما تحتاج للتبديل بين الفروع لمعالجة مشكلة عاجلة دون فقدان عملك الحالي:
# حفظ التغييرات الحالية مؤقتاً
git stash
git stash save "وصف للتغييرات"
git stash push -m "عمل على صفحة الدفع"
# حفظ مع الملفات غير المتتبعة
git stash -u
# عرض المحفوظات
git stash list
# استعادة التغييرات
git stash pop # استعادة وحذف
git stash apply # استعادة مع الإبقاء
git stash apply stash@{2} # استعادة محفوظة محددة
# عرض محتوى محفوظة
git stash show -p stash@{0}
# حذف المحفوظات
git stash drop stash@{0}
git stash clear # حذف الكل
التراجع واستعادة الحالات السابقة
يوفر Git عدة طرق للتراجع عن التغييرات حسب المرحلة التي وصلت إليها:
# التراجع عن تعديلات في مجلد العمل
git restore filename.js
git checkout -- filename.js # الطريقة القديمة
# إزالة من منطقة التجهيز
git restore --staged filename.js
git reset HEAD filename.js # الطريقة القديمة
# التراجع عن commits
git reset --soft HEAD~1 # إبقاء التغييرات في staging
git reset --mixed HEAD~1 # إبقاء التغييرات في working dir
git reset --hard HEAD~1 # حذف التغييرات نهائياً
# إنشاء commit عكسي (آمن للمشاركة)
git revert abc1234
git revert HEAD~2..HEAD # عكس عدة commits
# استعادة ملف من commit قديم
git checkout abc1234 -- filename.js
git restore --source=abc1234 filename.js
GitHub Actions والتكامل المستمر
يوفر GitHub Actions نظام CI/CD مدمجاً يسمح بأتمتة البناء والاختبار والنشر مباشرة من المستودع:
# .github/workflows/ci.yml
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20]
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
- run: npm ci
- run: npm test
- run: npm run build
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- run: npm ci && npm run build
- name: Deploy
run: echo "Deploying to production..."
ملف .gitignore الشامل
# بيئة التطوير
.env
.env.local
.env.*.local
# تبعيات المشروع
node_modules/
vendor/
bower_components/
# ملفات البناء
dist/
build/
.next/
out/
# ملفات النظام
.DS_Store
Thumbs.db
*.swp
# محررات الكود
.vscode/settings.json
.idea/
*.sublime-workspace
# سجلات وتخزين مؤقت
*.log
npm-debug.log*
.cache/
.tmp/
# اختبارات
coverage/
.nyc_output/
أفضل الممارسات للعمل الجماعي
- اتبع Conventional Commits: استخدم بادئات مثل feat: و fix: و docs: و refactor: و test: و chore: لتنظيم رسائل الـ commits وتسهيل إنشاء سجل التغييرات تلقائياً
- فعّل حماية الفروع: اشترط مراجعة PR واحدة على الأقل ونجاح اختبارات CI قبل السماح بالدمج في main
- اكتب وصفاً تفصيلياً لكل PR: اشرح ماذا تغيّر ولماذا وكيف يمكن اختباره مع لقطات شاشة إن أمكن
- استخدم Issues لتتبع المهام: ربط كل PR بـ Issue محدد لتوثيق سبب التغيير والمتطلبات
- حافظ على commits صغيرة ومركّزة: كل commit يجب أن يمثل تغييراً منطقياً واحداً يمكن فهمه ومراجعته بسهولة
- لا تعمل مباشرة على main: دائماً أنشئ فرعاً جديداً لأي تغيير مهما كان صغيراً
- نظّف الفروع المدمجة: احذف الفروع بعد دمجها للحفاظ على نظافة المستودع
مشروع تطبيقي شامل
لنطبق جميع المفاهيم في مشروع واقعي لبناء موقع ويب مع سير عمل احترافي كامل باستخدام Git و GitHub:
# المرحلة 1: تهيئة المشروع
mkdir portfolio-website && cd portfolio-website
git init
npm init -y
mkdir -p src/{css,js,images,components} tests docs
touch src/index.html src/css/main.css src/js/app.js README.md .gitignore
# إعداد .gitignore
echo "node_modules/\n.env\ndist/\n*.log\n.DS_Store" > .gitignore
# الـ commit الأول
git add -A
git commit -m "chore: تهيئة المشروع مع الهيكل الأساسي"
# المرحلة 2: ربط بـ GitHub
git remote add origin git@github.com:username/portfolio.git
git push -u origin main
# المرحلة 3: إنشاء فرع develop
git checkout -b develop
git push -u origin develop
# المرحلة 4: العمل على ميزة
git checkout -b feature/responsive-header
# ... تطوير الـ Header ...
git add src/css/main.css src/js/app.js
git commit -m "feat: إنشاء شريط تنقل متجاوب مع قائمة هامبرغر"
git push origin feature/responsive-header
# المرحلة 5: إنشاء PR على GitHub ومراجعة الكود
# المرحلة 6: دمج PR وحذف الفرع
git checkout develop
git pull origin develop
git branch -d feature/responsive-header
أدوات Git المتقدمة
Git Bisect: البحث عن مصدر الخطأ
عندما تكتشف خطأ ولا تعرف في أي commit ظهر، يساعدك git bisect على إيجاده باستخدام البحث الثنائي:
# بدء البحث الثنائي
git bisect start
git bisect bad # الـ commit الحالي فيه خطأ
git bisect good abc1234 # آخر commit كان يعمل
# Git سينتقل تلقائياً بين الـ commits
# اختبر كل مرة وأخبر Git بالنتيجة
git bisect good # إذا كان يعمل
git bisect bad # إذا كان فيه خطأ
# عند الانتهاء
git bisect reset
# البحث التلقائي باستخدام script
git bisect start HEAD abc1234
git bisect run npm test
Git Worktree: العمل على فروع متعددة
يسمح Git Worktree بفتح عدة فروع في مجلدات منفصلة دون الحاجة للتبديل بينها، وهو مفيد جداً عندما تحتاج للعمل على إصلاح عاجل أثناء تطوير ميزة جديدة:
# إنشاء worktree لفرع موجود
git worktree add ../hotfix-branch hotfix/urgent-fix
# إنشاء worktree مع فرع جديد
git worktree add -b feature/new-feature ../new-feature
# عرض جميع worktrees
git worktree list
# حذف worktree بعد الانتهاء
git worktree remove ../hotfix-branch
Git Hooks المتقدمة مع Husky
# تثبيت Husky و lint-staged
npm install -D husky lint-staged
npx husky install
# إضافة hook لما قبل commit
npx husky add .husky/pre-commit "npx lint-staged"
# إعداد lint-staged في package.json
# "lint-staged": {
# "*.js": ["eslint --fix", "prettier --write"],
# "*.css": ["stylelint --fix"],
# "*.{json,md}": ["prettier --write"]
# }
# إضافة hook لرسائل commit
npx husky add .husky/commit-msg "npx commitlint --edit"
ملخص المهارات المكتسبة
- تثبيت وإعداد Git بشكل احترافي على جميع أنظمة التشغيل
- فهم نظام العمل ثلاثي المراحل والتنقل بين المناطق بمهارة
- إتقان العمليات اليومية: add, commit, push, pull, fetch
- إدارة الفروع باحتراف واستخدام استراتيجيات merge و rebase
- حل تعارضات الدمج بثقة وكفاءة
- التعاون عبر Pull Requests ومراجعة الكود على GitHub
- استخدام Git Stash وأدوات التراجع عن التغييرات
- إعداد CI/CD باستخدام GitHub Actions
- تطبيق أفضل ممارسات العمل الجماعي
الخطوة التالية
بعد إتقان أساسيات Git و GitHub المتقدمة، انتقل إلى تعلم Git Flow و Trunk-Based Development كاستراتيجيات لإدارة الفروع في الفرق الكبيرة. استكشف GitHub Actions بعمق لبناء خطوط أنابيب CI/CD متكاملة تشمل الاختبار التلقائي والنشر المستمر. ابدأ بالمساهمة في مشاريع مفتوحة المصدر على GitHub لاكتساب خبرة عملية حقيقية في التعاون مع فرق عالمية.