Git و GitHub

أوامر Git المتقدمة

13 دقيقة الدرس 30 من 35

أوامر Git المتقدمة

بعيداً عن أوامر Git الأساسية، هناك أدوات متقدمة قوية يمكن أن تنقذك في المواقف الحرجة وتعزز إنتاجيتك. في هذا الدرس، سنستكشف cherry-pick و reflog و bisect و blame وأوامر Git المتقدمة الأخرى التي يجب على كل مطور محترف معرفتها.

Git Cherry-Pick: تطبيق التزامات محددة

يسمح لك Cherry-pick بتطبيق التزام محدد من فرع إلى آخر دون دمج الفرع بأكمله.

Cherry-Pick الأساسي: # أنت على فرع main git checkout main # تطبيق الالتزام من فرع الميزة git cherry-pick abc123 # الالتزام abc123 الآن على main (مع تجزئة جديدة) حالات الاستخدام: ✓ تطبيق الإصلاح العاجل على فروع متعددة ✓ اختيار ميزات محددة من فرع تجريبي ✓ نقل الإصلاحات إلى فروع الإصدار الأقدم ✓ نقل الالتزامات إلى الفرع الصحيح بعد الخطأ
مهم: ينشئ Cherry-pick التزاماً جديداً بنفس التغييرات ولكن تجزئة مختلفة. لا ينقل الالتزام الأصلي.

أمثلة Cherry-Pick

Cherry-Pick لالتزامات متعددة: # اختر نطاقاً من الالتزامات git cherry-pick abc123..def456 # اختر التزامات محددة git cherry-pick abc123 def456 ghi789 Cherry-Pick بدون التزام تلقائي: # ترحيل التغييرات بدون الالتزام git cherry-pick -n abc123 # أو git cherry-pick --no-commit abc123 # راجع التغييرات، ثم التزم يدوياً git commit -m "Cherry-picked feature from abc123" حل تعارضات Cherry-Pick: # إذا حدث تعارض git cherry-pick abc123 # CONFLICT (content): Merge conflict in file.php # أصلح التعارضات يدوياً # ثم: git add file.php git cherry-pick --continue # أو ألغِ: git cherry-pick --abort
نصيحة احترافية: استخدم cherry-pick بحذر. إذا وجدت نفسك تختار العديد من الالتزامات انتقائياً، ففكر في الدمج أو إعادة الأساس بدلاً من ذلك.

Git Reflog: شبكة الأمان

يسجل Reflog (سجل المرجع) كل تغيير على HEAD. إنها شبكة الأمان الخاصة بك لاستعادة الالتزامات "المفقودة".

عرض Reflog: $ git reflog abc123 HEAD@{0}: commit: Add user authentication def456 HEAD@{1}: checkout: moving from feature to main ghi789 HEAD@{2}: commit: Fix payment bug jkl012 HEAD@{3}: reset: moving to HEAD~1 mno345 HEAD@{4}: commit: Add payment feature (LOST!) شرح Reflog: - HEAD@{0} = موضع HEAD الحالي - HEAD@{1} = موضع HEAD السابق - HEAD@{2} = حركتان للوراء - إلخ.

استعادة الالتزامات المفقودة باستخدام Reflog

السيناريو: إعادة تعيين صعبة بطريق الخطأ # فعلت عن طريق الخطأ: git reset --hard HEAD~3 # يا للهول! 3 التزامات ذهبت! # الحل: استخدم reflog git reflog # اعثر على تجزئة الالتزام قبل إعادة التعيين abc123 HEAD@{4}: commit: Add payment feature # استعد إلى ذلك الالتزام git reset --hard abc123 # التزاماتك عادت! 🎉 السيناريو: استعادة الفرع المحذوف # حذفت فرعاً بطريق الخطأ git branch -D feature/important-work # اعثر على آخر التزام على ذلك الفرع git reflog | grep "feature/important-work" # أعد إنشاء الفرع git branch feature/important-work abc123 git checkout feature/important-work
ملاحظة: تنتهي إدخالات Reflog بعد 90 يوماً افتراضياً. لا تنتظر طويلاً لاستعادة العمل المفقود!

Git Bisect: العثور على الأخطاء بالبحث الثنائي

يستخدم Bisect البحث الثنائي للعثور على الالتزام الذي قدم خطأ.

سير عمل Bisect الأساسي: # ابدأ bisect git bisect start # ضع علامة على الالتزام الحالي كسيئ (الخطأ موجود) git bisect bad # ضع علامة على التزام جيد معروف (الخطأ لم يكن موجوداً) git bisect good v1.2.0 # يفحص Git الالتزام الأوسط # اختبر ما إذا كان الخطأ موجوداً # إذا كان الخطأ موجوداً: git bisect bad # إذا لم يكن الخطأ موجوداً: git bisect good # كرر حتى يعثر Git على الالتزام الإشكالي # عند الانتهاء: git bisect reset

Bisect التلقائي مع الاختبارات

تشغيل Bisect تلقائياً: # ابدأ bisect git bisect start HEAD v1.2.0 # شغّل bisect مع أمر الاختبار git bisect run php artisan test --filter=PaymentTest # سيختبر Git تلقائياً كل التزام # ضع علامة جيد/سيئ بناءً على رمز خروج الاختبار # رمز الخروج 0 = جيد، غير صفري = سيئ # سيجد Bisect الالتزام المحدد الذي كسر الاختبارات مثال على المخرجات: abc123 is the first bad commit commit abc123 Author: John Doe <john@example.com> Date: Mon Jan 15 10:30:00 2024 +0000 Refactor payment calculation This commit introduced the bug!
حركة قوية: يمكن لـ Bisect التحقق من مئات الالتزامات في دقائق باستخدام البحث الثنائي. الاختبار اليدوي سيستغرق ساعات!

Git Blame: تتبع التغييرات حسب المؤلف

يعرض Blame من عدّل آخر مرة كل سطر من ملف ومتى.

Blame الأساسي: $ git blame app/Http/Controllers/PaymentController.php abc123 (John Doe 2024-01-15 10:30:00 +0000 1) <?php abc123 (John Doe 2024-01-15 10:30:00 +0000 2) def456 (Jane Smith 2024-02-01 14:20:00 +0000 3) public function process($order) { def456 (Jane Smith 2024-02-01 14:20:00 +0000 4) $tax = $order->total * 0.08; ghi789 (Bob Johnson 2024-03-10 09:15:00 +0000 5) // TODO: Fix tax calculation def456 (Jane Smith 2024-02-01 14:20:00 +0000 6) return $order->total + $tax; abc123 (John Doe 2024-01-15 10:30:00 +0000 7) } خيارات Blame المفيدة: # إظهار أرقام الأسطر ومعلومات الالتزام git blame -L 10,20 file.php # إظهار نطاق سطر محدد فقط git blame -L 10,+5 file.php # إظهار البريد الإلكتروني بدلاً من الأسماء git blame -e file.php # تجاهل تغييرات المسافات البيضاء git blame -w file.php
نصيحة احترافية: استخدم blame للعثور على من كتب الكود، وليس لإلقاء اللوم عليهم! إنها لفهم السياق وطرح الأسئلة.

Git Grep: البحث في محتوى المستودع

يبحث Grep في محتويات الملفات عبر مستودع Git الخاص بك بالكامل.

Grep الأساسي: # ابحث عن نص في جميع الملفات المتتبعة git grep "calculateTax" # ابحث مع أرقام الأسطر git grep -n "calculateTax" # بحث غير حساس لحالة الأحرف git grep -i "calculatetax" # إظهار عدد التطابقات لكل ملف git grep -c "calculateTax" # ابحث في فرع محدد git grep "calculateTax" main # ابحث في التزام محدد git grep "calculateTax" abc123 Grep المتقدم: # ابحث بـ regex git grep "function.*calculate" # ابحث عن كلمات كاملة فقط git grep -w "tax" # إظهار السياق (3 أسطر قبل/بعد) git grep -C 3 "calculateTax" # ابحث فقط في ملفات PHP git grep "calculateTax" -- "*.php" # ابحث عن أنماط متعددة (AND) git grep -e "tax" --and -e "calculate"

Git Submodules: إدارة التبعيات

تسمح لك الوحدات الفرعية بتضمين مستودع Git آخر داخل مستودعك.

إضافة وحدة فرعية: # إضافة وحدة فرعية git submodule add https://github.com/vendor/library.git lib/library # ينشئ هذا ملف .gitmodules استنساخ مستودع مع وحدات فرعية: # استنسخ وهيّئ الوحدات الفرعية git clone --recurse-submodules https://github.com/user/repo.git # أو إذا تم الاستنساخ بالفعل: git submodule init git submodule update تحديث الوحدات الفرعية: # تحديث جميع الوحدات الفرعية إلى الأحدث git submodule update --remote # تحديث وحدة فرعية محددة git submodule update --remote lib/library إزالة وحدة فرعية: # إزالة وحدة فرعية git submodule deinit lib/library git rm lib/library rm -rf .git/modules/lib/library
ملاحظة: الوحدات الفرعية معقدة ولها مشاكل. فكر في استخدام Composer (PHP) أو npm (JavaScript) لإدارة التبعية بدلاً من ذلك.

Git Worktree: أدلة عمل متعددة

يسمح لك Worktree بفحص فروع متعددة في وقت واحد في أدلة مختلفة.

حالة الاستخدام: أنت تعمل على ميزة ولكن تحتاج إلى إصلاح خطأ إنتاج بسرعة دون فقدان عملك الحالي. إنشاء Worktree: # أنشئ worktree للإصلاح العاجل git worktree add ../hotfix-dir hotfix/urgent-bug # الآن لديك: # - /project (دليل العمل الرئيسي) # - /hotfix-dir (دليل منفصل مع فرع hotfix) # اعمل في دليل hotfix cd ../hotfix-dir # أجرِ تغييرات، التزم، ادفع git add . git commit -m "Fix urgent bug" git push # ارجع إلى العمل الرئيسي cd /project # عمل ميزتك لم يمس! إدارة Worktrees: # اسرد جميع worktrees git worktree list # أزل worktree git worktree remove ../hotfix-dir # تقليم worktrees المحذوفة git worktree prune
الفائدة: تلغي Worktrees الحاجة إلى التخزين المؤقت، الالتزام بـ WIP، أو استنساخ المستودع مرة أخرى. اعمل على فروع متعددة في وقت واحد!

Git Show: فحص الالتزامات والكائنات

إظهار تفاصيل الالتزام: # إظهار آخر التزام git show # إظهار التزام محدد git show abc123 # إظهار ملف محدد من الالتزام git show abc123:app/Models/User.php # إظهار ملف من فرع مختلف git show main:README.md إظهار العلامة: # إظهار تفاصيل العلامة المشروحة git show v1.2.0 إظهار التخزين المؤقت: # إظهار آخر تخزين مؤقت git show stash@{0} # إظهار تخزين مؤقت محدد git show stash@{2}

Git Archive: إنشاء أرشيفات الإصدار

إنشاء أرشيف: # إنشاء أرشيف zip لفرع main git archive --format=zip --output=release-v1.2.0.zip main # إنشاء أرشيف tar.gz git archive --format=tar.gz --output=release.tar.gz main # أرشيف علامة محددة git archive --format=zip --output=v1.2.0.zip v1.2.0 # أرشيف مع دليل بادئة git archive --prefix=myapp/ --format=zip --output=myapp.zip main أرشيف ملفات محددة: # أرشيف دليل app/ فقط git archive --format=zip --output=app-only.zip main app/ # أرشيف باستثناء vendor/ git archive --format=zip --output=no-vendor.zip main \ $(git ls-files | grep -v "^vendor/")

Git Clean: إزالة الملفات غير المتتبعة

تنظيف الملفات غير المتتبعة: # تشغيل جاف (إظهار ما سيتم حذفه) git clean -n # إزالة الملفات غير المتتبعة git clean -f # إزالة الملفات والأدلة غير المتتبعة git clean -fd # إزالة الملفات المتجاهلة أيضاً git clean -fdx # تنظيف تفاعلي git clean -i حالة استخدام شائعة: # بعد تبديل الفروع، أزل مصنوعات البناء git clean -fdx # نظّف لكن احتفظ بملف .env git clean -fdx -e .env
خطر: git clean -fdx يحذف الملفات نهائياً! شغّل دائماً git clean -n أولاً للمعاينة.

Git Shortlog: تلخيص المساهمين

عرض ملخص المساهمين: # إظهار عدد الالتزامات حسب المؤلف git shortlog -sn # المخرجات: 150 John Doe 87 Jane Smith 45 Bob Johnson # إظهار مع عناوين البريد الإلكتروني git shortlog -sne # إظهار لفرع محدد git shortlog -sn main # إظهار لنطاق تاريخ git shortlog -sn --since="2024-01-01" --until="2024-12-31" # إظهار رسائل الالتزام التفصيلية git shortlog

استعلامات Git Log المتقدمة

استعلامات السجل القوية: # التزامات بواسطة مؤلف محدد git log --author="John Doe" # التزامات في نطاق تاريخ git log --since="2024-01-01" --until="2024-12-31" # التزامات تؤثر على ملف محدد git log -- app/Models/User.php # ابحث في رسائل الالتزام git log --grep="fix bug" # ابحث في محتوى الالتزام (تغييرات الكود) git log -S "calculateTax" # التزامات أضافت أو أزالت نصاً محدداً git log -G "function.*calculate" # إظهار الملفات المتغيرة في كل التزام git log --name-only # إظهار الإحصائيات (الإدراجات/الحذفات) git log --stat # تنسيق مخصص git log --pretty=format:"%h - %an, %ar : %s" # التزامات على الفرع ولكن ليس على main git log main..feature/new-feature # التزامات الدمج فقط git log --merges # التزامات غير الدمج فقط git log --no-merges

تمرين عملي:

السيناريو: تطبيق الإنتاج الخاص بك به خطأ. الخطأ لم يكن موجوداً في v1.0.0 (صدر قبل 3 أشهر)، ولكنه موجود الآن. تحتاج إلى العثور على الالتزام الذي قدمه.

المهام:

  1. استخدم git bisect للعثور على الالتزام الإشكالي
  2. استخدم git blame لرؤية من كتب السطر الخاطئ
  3. استخدم git show لفحص تفاصيل الالتزام
  4. استخدم git log لفهم السياق

الحل:

# 1. ابدأ bisect git bisect start git bisect bad # الإصدار الحالي به خطأ git bisect good v1.0.0 # v1.0.0 كان يعمل # يفحص Git الالتزام الأوسط # اختبر التطبيق... # الخطأ موجود: git bisect bad # استمر حتى يعثر Git على الالتزام: # abc123 is the first bad commit # 2. استخدم blame للعثور على من كتب الكود الخاطئ git blame app/Services/PaymentService.php # المخرجات تظهر أن السطر 45 تم تعديله في الالتزام abc123 # 3. إظهار تفاصيل الالتزام git show abc123 # اطلع على الفرق الكامل ورسالة الالتزام # 4. احصل على السياق مع السجل git log abc123~5..abc123 # اطلع على الالتزامات حول الإشكالية # 5. اختر الإصلاح انتقائياً لفرع hotfix git checkout -b hotfix/payment-bug git cherry-pick def456 # الالتزام الذي يصلحه # 6. انتهيت! git bisect reset

الملخص

في هذا الدرس، تعلمت:

  • git cherry-pick: تطبيق التزامات محددة على فرع آخر
  • git reflog: استعادة الالتزامات والفروع "المفقودة"
  • git bisect: العثور على الالتزامات التي تقدم أخطاء بالبحث الثنائي
  • git blame: تتبع من عدّل كل سطر من الكود
  • git grep: البحث في محتوى المستودع بكفاءة
  • git worktree: العمل على فروع متعددة في وقت واحد
  • git clean: إزالة الملفات غير المتتبعة بأمان
  • git log المتقدم: استعلامات سجل الالتزامات القوية
تهانينا! لقد أكملت دروس Git و GitHub. لديك الآن المهارات لاستخدام Git بثقة للتحكم في الإصدارات، والتعاون مع الفرق على GitHub، والتعامل مع السيناريوهات المتقدمة. استمر في الممارسة، وستتقن Git في وقت قصير!