Git: من الأساسيات إلى الاحتراف
في عالم البرمجة الحديث، أصبح نظام التحكم في النسخ (Version Control) أداة لا غنى عنها لكل مطور محترف. وGit، الذي طوره لينوس تورفالدز (مؤسس نواة Linux) في عام 2005، يعتبر المعيار الذهبي في هذا المجال. يستخدمه الملايين حول العالم، من المطورين الفرديين إلى فرق العمل الضخمة في شركات مثل Google وFacebook وMicrosoft.
نظام Git للتحكم في النسخ - الأساس الذي يعتمد عليه ملايين المطورين حول العالم
الجزء الأول: التثبيت والإعداد الأولي
1.1 تثبيت Git على مختلف الأنظمة
الخطوة الأولى هي تثبيت Git على جهازك. العملية تختلف قليلاً حسب نظام التشغيل، لكنها بسيطة في جميع الحالات. إليك الدليل التفصيلي لكل نظام:
🪟 نظام Windows
لتثبيت Git على Windows، انتقل إلى الموقع الرسمي git-scm.com وقم بتنزيل المثبت. أثناء التثبيت، ستظهر لك عدة خيارات. إليك الإعدادات الموصى بها:
- Editor: اختر VS Code أو أي محرر تفضله بدلاً من Vim الافتراضي.
- Branch naming: اترك الإعداد الافتراضي (main).
- PATH environment: اختر "Git from the command line and also from 3rd-party software" لاستخدام Git من أي موجه أوامر.
- SSH: استخدم OpenSSH المدمج.
- HTTPS: استخدم Git Credential Manager لتخزين بيانات الدخول بأمان.
# بعد التثبيت، تأكد من نجاح العملية
git --version
# يجب أن يظهر رقم الإصدار، مثال: git version 2.45.0 تثبيت Git على Windows - خطوات بسيطة لإعداد البيئة
🐧 نظام Linux (Ubuntu/Debian)
على أنظمة Linux، عادة ما يمكنك تثبيت Git عبر مدير الحزم. إليك الأوامر لأنظمة Debian/Ubuntu:
# تحديث قائمة الحزم
sudo apt update
# تثبيت Git
sudo apt install git
# التحقق من التثبيت
git --version 🍎 نظام macOS
على macOS، يمكنك تثبيت Git بعدة طرق. الطريقة الأسهل هي استخدام Homebrew:
# تثبيت Homebrew أولاً (إذا لم يكن مثبتاً)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# تثبيت Git عبر Homebrew
brew install git
# التحقق
git --version 1.2 الإعدادات الأساسية
بعد التثبيت، يجب إعداد Git بمعلوماتك الشخصية. هذه المعلومات ستظهر في كل commit تقوم به، وهي ضرورية للتعاون مع الفريق:
# إعداد الاسم
git config --global user.name "اسمك الكامل"
# إعداد البريد الإلكتروني (استخدم نفس البريد المسجل في GitHub)
git config --global user.email "your.email@example.com"
# التحقق من الإعدادات
git config --list --global لإعداد Git مرة واحدة لجميع المشاريع. إذا أردت إعداداً خاصاً بمشروع محدد، احذف --global ونفذ الأمر داخل مجلد المشروع.
1.3 الإعدادات المتقدمة الموصى بها
إليك مجموعة من الإعدادات التي يحسن ضبطها لتسهيل العمل:
# تلوين مخرجات Git
git config --global color.ui auto
# محرر النصوص الافتراضي
git config --global core.editor "code --wait"
# أداة دمج الفروع الافتراضية
git config --global init.defaultBranch main
# استخدام rebase عند السحب
git config --global pull.rebase true
# ضغط الملفات الكبيرة
git config --global core.compression 9 ️ الجزء الثاني: فهم البنية الأساسية لـ Git
قبل البدء باستخدام الأوامر، من المهم فهم كيف يعمل Git داخلياً. هذا الفهم سيساعدك على استيعاب لماذا تتصرف الأوامر بطريقة معينة، وكيفية حل المشاكل المعقدة.
2.1 مناطق العمل الثلاث
يعمل Git بنظام ثلاث مناطق رئيسية. فهم هذه المناطق هو مفتاح إتقان Git:
Working Directory
مجلد عملك الحالي حيث تقوم بتحرير الملفات. هنا تكتب الكود وتعدل الملفات. أي تغيير هنا لا يتم تتبعه تلقائياً.
Staging Area (Index)
منطقة تحضيرية بين مجلد العمل والمستودع. هنا تختار التغييرات التي تريد تضمينها في الـ commit القادم. تعمل كقائمة مراجعة قبل الحفظ.
Repository (Local)
المستودع المحلي حيث يتم حفظ تاريخ المشروع بالكامل. كل commit يُحفظ هنا مع معلوماته الكاملة. يحتوي على جميع الفروع والتاريخ.
المناطق الثلاث في Git: Working Directory، Staging Area، Repository
2.2 كيف يعمل Git داخلياً
يستخدم Git نموذجاً مختلفاً عن أنظمة التحكم في النسخ الأخرى. بدلاً من تخزين الفروقات بين النسخ، يقوم Git بتخزين "لحظات" (Snapshots) كاملة للمشروع في كل commit. هذا التصميم يجعل العديد من العمليات سريعة جداً.
عند إنشاء commit، يقوم Git بـ:
- حساب hash (SHA-1) لكل ملف في المشروع.
- تخزين المحتوى الفريد في قاعدة بيانات الكائنات.
- إنشاء كائن commit يشير إلى snapshot الحالي.
- ربط commit الجديد بـ commit السابق (parent).
2.3 مصطلحات أساسية يجب معرفتها
🎯 الجزء الثالث: البدء بمشروع جديد
3.1 إنشاء مستودع جديد
هناك طريقتان رئيسيتان للبدء بـ Git: إنشاء مستودع جديد من الصفر، أو نسخ مستودع موجود.
إنشاء مستودع جديد (Init)
لإنشاء مستودع Git في مجلد موجود:
# انتقل إلى مجلد مشروعك
cd path/to/your/project
# إنشاء مستودع Git جديد
git init
# التحقق من إنشاء المجلد المخفي .git
ls -la | grep .git
أمر git init ينشئ مجلداً مخفياً اسمه .git يحتوي على كامل البنية التحتية للمستودع. هذا المجلد هو "عقل" Git، ويحتوي على جميع commits، الفروع، والإعدادات.
3.2 إنشاء ملف .gitignore
ملف .gitignore يخبر Git بتجاهل ملفات ومجلدات معينة. هذا ضروري لمنع ملفات غير ضرورية من الدخول في تاريخ المشروع:
# إنشاء ملف .gitignore
touch .gitignore
# أو استخدم محرر النصوص
code .gitignore محتوى نموذجي لـ .gitignore:
# مجلدات النظام
.DS_Store
Thumbs.db
# مجلدات Node.js
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# ملفات البيئة
.env
.env.local
.env.*.local
# مجلدات البناء
dist/
build/
*.min.js
*.min.css
# محررات النصوص
.vscode/
.idea/
*.swp
*.swo
# ملفات السجلات
*.log
logs/
# ملفات مؤقتة
*.tmp
*.temp gitignore.io لإنشاء ملفات .gitignore جاهزة لأنواع مشاريع مختلفة. فقط اكتب اسم التقنية (Node, Python, Laravel, إلخ) وسيقوم الموقع بإنشاء الملف لك.
3.3 النسخ من مستودع بعيد (Clone)
للانضمام لمشروع موجود أو العمل على كود مفتوح المصدر:
# نسخ مستودع عبر HTTPS
git clone https://github.com/username/repository.git
# نسخ مستودع عبر SSH (موصى به)
git clone git@github.com:username/repository.git
# نسخ مع تحديد اسم المجلد
git clone https://github.com/username/repo.git my-project
# نسخ فرع محدد فقط
git clone --branch develop https://github.com/username/repo.git عملية Git Clone - نسخ المشروع من GitHub إلى جهازك المحلي
💻 الجزء الرابع: دورة العمل اليومية
دورة العمل اليومية في Git تتبع نمطاً متكرراً: تعديل الملفات، إضافتها للمرحلة التحضيرية، ثم عمل commit. هذا القسم يشرح كل خطوة بالتفصيل مع أمثلة عملية.
4.1 التحقق من حالة المشروع (Status)
أول أمر يجب استخدامه قبل أي شيء آخر هو git status. هذا الأمر يخبرك بحالة جميع الملفات:
# عرض الحالة المفصلة
git status
# عرض مختصر
git status -s مخرجات git status -s تستخدم رموزاً مختصرة:
??- ملف جديد غير متابعA- ملف مُضاف للمرحلة التحضيريةM- ملف مُعدّلMM- الملف في المرحلة التحضيرية ومُعدّل مرة أخرىD- ملف محذوفR- ملف أعيد تسميته
4.2 إضافة الملفات للمرحلة التحضيرية (Stage)
المرحلة التحضيرية (Staging) هي ما يميز Git عن غيره. هنا تختار بالضبط ما تريد تضمينه في commit القادم:
# إضافة ملف محدد
git add filename.js
# إضافة جميع الملفات المعدلة والجديدة
git add .
# إضافة جميع الملفات المعدلة فقط (لا يشمل الجديدة)
git add -u
# إضافة ملفات محددة بنمط
git add *.js
git add src/**/*.ts
# إضافة تفاعلية (اختيار أجزاء محددة من ملف)
git add -p
# إزالة ملف من المرحلة التحضيرية
git reset HEAD filename.js 4.3 حفظ التغييرات (Commit)
الـ commit هو لقطة محفوظة من المشروع. كل commit له hash فريد، رسالة وصفية، وتاريخ:
# commit مع رسالة مباشرة
git commit -m "feat: add user authentication module"
# commit سريع للإضافات المعدلة فقط (بدون git add)
git commit -am "fix: resolve login bug"
# تعديل آخر commit
git commit --amend -m "feat: add user authentication module with tests"
# commit مع تفصيل أكثر
git commit -m "feat: add user authentication" -m "This includes:
- Login endpoint
- JWT token generation
- Password hashing
- Unit tests" type(scope): description الأنواع الشائعة:
•
feat: ميزة جديدة•
fix: إصلاح خطأ•
docs: توثيق فقط•
style: تنسيق الكود•
refactor: إعادة هيكلة•
test: إضافة أو تعديل اختبارات•
chore: مهام صيانة
4.4 عرض التاريخ (Log)
لعرض سجل commits مع تفاصيل مختلفة:
# سجل commits الكامل
git log
# سجل مختصر (سطر واحد لكل commit)
git log --oneline
# سجل مع الرسم البياني للفروع
git log --oneline --graph --all
# آخر 10 commits
git log -n 10
# commits منذ تاريخ معين
git log --since="2024-01-01" --until="2024-12-31"
# commits لمؤلف معين
git log --author="username"
# commits تحتوي كلمة في الرسالة
git log --grep="authentication"
# commits في ملف محدد
git log -- path/to/file.js
# إحصائيات commits
git log --stat
# عرض التغييرات في كل commit
git log -p
# تنسيق مخصص
git log --pretty=format:"%h - %an, %ar : %s" عرض رسومي لتاريخ commits والفروع باستخدام git log --graph
الجزء الخامس: الفروع (Branches) - القوة الحقيقية لـ Git
الفروع هي أحد أقوى ميزات Git. تسمح لك بتطوير ميزات جديدة، إصلاح الأخطاء، أو تجربة أفكار دون التأثير على الكود الرئيسي. كل فرع هو مسار تطور مستقل.
5.1 مفهوم الفروع
في Git، الفرع هو مجرد مؤشر (pointer) إلى commit معين. عندما تنشئ فرعاً جديداً، Git لا ينسخ الملفات، بل ينشئ مؤشراً جديداً يشير إلى نفس commit الحالي. هذا يجعل إنشاء الفروع سريعاً جداً (أجزاء من الثانية).
5.2 إنشاء والتبديل بين الفروع
# إنشاء فرع جديد
git branch feature-login
# التبديل لفرع آخر
git checkout feature-login
# أو الطريقة الأحدث (Git 2.23+)
git switch feature-login
# إنشاء فرع والتبديل إليه فوراً
git checkout -b feature-login
# أو
git switch -c feature-login
# إنشاء فرع من commit معين
git checkout -b feature-from-hash a1b2c3d
# عرض جميع الفروع المحلية
git branch
# عرض جميع الفروع (محلية وبعيدة)
git branch -a
# عرض الفرع الحالي
git branch --show-current
# حذف فرع محلي
git branch -d feature-login
# حذف فرع بالقوة (حتى لو لم يُدمج)
git branch -D feature-login
# إعادة تسمية فرع
git branch -m old-name new-name 5.3 دمج الفروع (Merge)
عندما تنتهي من عملك في فرع وتريد دمج تغييراتك مع الفرع الرئيسي:
# التبديل للفرع المستهدف
git checkout main
# أو
git switch main
# سحب آخر التحديثات
git pull origin main
# دمج الفرع
git merge feature-login
# دمج بدون fast-forward (لحفظ تاريخ الفرع)
git merge --no-ff feature-login
# دمج مع squashing (دمج كل commits في واحد)
git merge --squash feature-login 5.4 حل تعارضات الدمج (Merge Conflicts)
التعارضات تحدث عندما يعدل فرعان نفس السطور في نفس الملف. Git يتوقف ويطلب منك الحل يدوياً:
<<<<<<< HEAD
هذا الكود من الفرع الحالي (main)
=======
هذا الكود من الفرع المدمج (feature)
>>>>>>> feature-login لحل التعارض:
- افتح الملف في المحرر.
- ابحث عن علامات التعارض (
<<<<<<<). - اختر الكود الصحيح أو ادمج الاثنين.
- احذف علامات التعارض.
- احفظ الملف.
- أضف الملف:
git add filename - أكمل الدمج:
git commit
# بعد حل التعارضات يدوياً
git add .
git commit -m "fix: resolve merge conflicts"
# أو إلغاء الدمج والعودة للحالة السابقة
git merge --abort 5.5 Rebase: بديل الدمج
الـ rebase يعيد تطبيق commits فرعك على أساس فرع آخر، مما يخلق تاريخاً خطياً أنظف:
# rebase على الفرع الرئيسي
git checkout feature-login
git rebase main
# rebase تفاعلي (لإعادة ترتيب أو تعديل commits)
git rebase -i HEAD~5
# إلغاء rebase جاري
git rebase --abort
# متابعة rebase بعد حل التعارضات
git rebase --continue الفرق بين Git Merge و Git Rebase في عرض التاريخ
🌍 الجزء السادس: العمل مع المستودعات البعيدة
Git موزع بطبيعته، مما يعني أن كل نسخة محلية هي مستودع كامل. لكن التعاون يتطلب مستودعات بعيدة (GitHub, GitLab, Bitbucket). هذا القسم يشرح كيفية التفاعل معها.
6.1 إعداد المستودع البعيد
# إضافة مستودع بعيد
git remote add origin https://github.com/username/repo.git
# عرض المستودعات البعيدة
git remote -v
# تغيير رابط مستودع بعيد
git remote set-url origin https://github.com/username/new-repo.git
# إزالة مستودع بعيد
git remote remove origin
# فحص مستودع بعيد
git remote show origin 6.2 السحب والرفع (Push & Pull)
# رفع الفرع الحالي إلى البعيد لأول مرة
git push -u origin main
# رفع عادي
git push
# رفع فرع محدد
git push origin feature-login
# رفع مع تعيين upstream
git push --set-upstream origin feature-login
# سحب التحديثات ودمجها
git pull
# سحب تحديثات فقط بدون دمج
git fetch
# سحب وتحديث كل الفروع
git fetch --all
# رفع بالقوة (استخدم بحذر!)
git push --force
# أو الأكثر أماناً
git push --force-with-lease
# حذف فرع بعيد
git push origin --delete feature-login 6.3 Pull Requests / Merge Requests
Pull Request (PR) هو طلب لدمج تغييراتك مع فرع آخر (عادة main). هذه العملية أساسية في العمل الجماعي:
- أنشئ فرعاً جديداً للميزة:
git checkout -b feature-login - قم بتطوير الميزة وعمل commits.
- ارفع الفرع:
git push origin feature-login - افتح PR على GitHub/GitLab.
- انتظر مراجعة الفريق (Code Review).
- عالج أي ملاحظات.
- عند الموافقة، يتم الدمج (Merge).
- احذف الفرع:
git branch -d feature-login
• اجعل PR صغيراً ومركزاً على مهمة واحدة.
• اكتب وصفاً واضحاً يشرح التغييرات.
• أضف لقطات شاشة للتغييرات البصرية.
• ربط PR بالتذاكر (Issues/Tickets).
• راجع الكود بنفسك قبل طلب المراجعة.
• ابقَ متجاوباً مع ملاحظات المراجعين.
سير عمل Pull Request على GitHub - التعاون الاحترافي في الفرق
🔧 الجزء السابع: التراجع عن الأخطاء وإصلاح المشاكل
كل مطور يرتكب أخطاء. Git يوفر أدوات قوية للتراجع والإصلاح. هذا القسم يشرح كيفية التعامل مع المواقف الصعبة.
7.1 التراجع عن تغييرات غير محفوظة
# استعادة ملف إلى حالته في آخر commit
git checkout -- filename.js
# أو
git restore filename.js
# استعادة جميع الملفات
git checkout -- .
# أو
git restore .
# إزالة ملفات غير متباعة من مجلد العمل
git clean -n # عرض ما سيُحذف
git clean -f # حذف فعلي
git clean -fd # حذف ملفات ومجلدات 7.2 التراجع عن commits
# التراجع عن آخر commit مع حفظ التغييرات في working directory
git reset --soft HEAD~1
# التراجع مع إبقاء التغييرات في staging
git reset --mixed HEAD~1 # (افتراضي)
# التراجع الكامل وحذف التغييرات
git reset --hard HEAD~1
# إنشاء commit جديد يعكس commit سابق (آمن للتعاون)
git revert <commit-hash>
# التراجع عن revert
git revert --no-commit HEAD 7.3 البحث والتنقيب (Bisect)
أمر git bisect يساعدك في إيجاد commit الذي أدخل خطأً معيناً:
# بدء البحث
git bisect start
# تحديد commit يعرف أنه جيد
git bisect good a1b2c3d
# تحديد commit يعرف أنه سيء
git bisect bad HEAD
# Git سينقلك لمنتصف المسار، اختبر الكود ثم:
git bisect good # إذا كان يعمل
# أو
git bisect bad # إذا كان به خطأ
# كرر حتى يجد Git commit المشكلة
# إنهاء البحث
git bisect reset 7.4 استعادة ملفات محذوفة
# استعادة ملف من commit معين
git checkout <commit-hash> -- filename.js
# أو
git restore --source=<commit-hash> filename.js
# استعادة مجلد كامل
git checkout <commit-hash> -- folder/ ⚡ الجزء الثامن: أدوات متقدمة للمحترفين
8.1 Stash: حفظ مؤقت للتغييرات
Stash يسمح لك بحفظ التغييرات مؤقتاً والعودة لمجالد عمل نظيف:
# حفظ التغييرات مؤقتاً
git stash
# حفظ مع رسالة
git stash save "work in progress on feature"
# عرض كل stashes
git stash list
# استعادة آخر stash
git stash pop
# استعادة دون حذف من القائمة
git stash apply
# استعادة stash محدد
git stash apply stash@2
# حذف stash
git stash drop stash@1
# حذف كل stashes
git stash clear
# إنشاء فرع من stash
git stash branch new-branch stash@0 8.2 Tags: وضع علامات على الإصدارات
# إنشاء tag خفيف
git tag v1.0.0
# إنشاء tag annotated (موصى به)
git tag -a v1.0.0 -m "Release version 1.0.0"
# عرض كل tags
git tag
# عرض تفاصيل tag
git show v1.0.0
# رفع tag للبعيد
git push origin v1.0.0
# رفع كل tags
git push --tags
# حذف tag محلي
git tag -d v1.0.0
# حذف tag بعيد
git push origin --delete v1.0.0 8.3 Cherry-pick: تطبيق commits محددة
# تطبيق commit محدد على الفرع الحالي
git cherry-pick <commit-hash>
# تطبيق عدة commits
git cherry-pick <hash1> <hash2>
# تطبيق نطاق commits
git cherry-pick A..B
# تطبيق دون commit تلقائي
git cherry-pick --no-commit <hash> 8.4 Hooks: أتمتة المهام
Git Hooks هي سكربتات تعمل تلقائياً عند أحداث معينة. إليك مثالاً على pre-commit hook للتحقق من الكود:
# إنشاء pre-commit hook
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/sh
# فحص الكود قبل كل commit
echo "Running pre-commit checks..."
# فحص الـ linting
npm run lint
# تشغيل الاختبارات
npm test
echo "All checks passed!"
EOF
# جعله قابلاً للتنفيذ
chmod +x .git/hooks/pre-commit كيف تعمل Git Hooks في سير العمل - أتمتة المهام المتكررة
🏆 الجزء التاسع: أفضل الممارسات وسير العمل الاحترافي
9.1 Git Flow: منهجية العمل المنظمة
Git Flow هو منهجية شائعة لإدارة الفروع في المشاريع الكبيرة:
main/master
الفرع الرئيسي، يحتوي على كود الإنتاج المستقر. كل commit هنا يجب أن يكون جاهزاً للنشر.
develop
فرع التطوير، يجمع كل الميزات الجديدة قبل دمجها مع main.
feature/*
فروع الميزات الجديدة، تنشأ من develop وتُدمج معه.
hotfix/*
فروع الإصلاحات العاجلة، تنشأ من main وتُدمج مع main وdevelop.
release/*
فروع التحضير للإصدار، لإجراء التعديلات الأخيرة قبل النشر.
9.2 قواعد ذهبية للعمل مع Git
- commit صغير ومتكرر: commits صغيرة أسهل في المراجعة والتراجع عنها.
- رسائل commits واضحة: اشرح لماذا التغيير، ليس ماذا.
- فرع لكل مهمة: لا تعمل مباشرة على main أو develop.
- حدّث فرعك بانتظام: اعمل rebase أو merge من develop يومياً.
- راجع كودك قبل push: استخدم
git diffوgit status. - لا تشارك commits مكسورة: تأكد أن الكود يعمل قبل الرفع.
- استخدم .gitignore: لا ترفع ملفات مؤقتة أو حساسة.
- احذف الفروع المدمجة: حافظ على نظافة المستودع.
- استخدم tags للإصدارات: سهل تتبع الإصدارات.
- تعلم حل التعارضات: لا تخف منها، هي جزء طبيعي من العمل.
9.3 أخطاء شائعة وكيفية تجنبها
commit إلى main مباشرة
الحل: أنشئ فرعاً جديداً للميزة واعمل عليه.
رسائل commits غامضة
الحل: استخدم Conventional Commits وكن وصفيًا.
دفع كود غير مختبر
الحل: شغّل الاختبارات محلياً قبل الرفع.
فروع قديمة غير محذوفة
الحل: احذف الفروع بعد الدمج.
تجاهل .gitignore
الحل: أضف .gitignore في البداية.
رفع مفاتيح سرية
الحل: استخدم .env واستخدم git-secrets.
أفضل الممارسات في Git - العمل الاحترافي والمنظم
💡 الخلاصة الهندسية الشاملة:
- ✅ Git أداة قوية لكن فهم الأساسيات يفتح لك أبواب الاحتراف.
- ✅ الفروع هي أقوى ميزة في Git - استخدمها بحكمة.
- ✅ commits الصغيرة والواضحة تسهل العمل الجماعي.
- ✅ التراجع ممكن دائماً - لا تخف من التجربة.
- ✅ أفضل الممارسات توفر الوقت وتمنع الكوارث.
- ✅ الممارسة المستمرة هي مفتاح الإتقان.
Git ليس مجرد أداة، بل مهارة أساسية لكل مطور محترف! 🚀✨