We are still cooking the magic in the way!
Git و GitHub
تتبع التغييرات
تتبع التغييرات
الآن بعد أن تعرف سير عمل Git الأساسي، لنغوص بشكل أعمق في تتبع التغييرات. في هذا الدرس، ستتعلم كيفية استخدام git status بفعالية، وفهم الطرق المختلفة لتدريج الملفات، ونقل وإزالة الملفات، والتحكم في الملفات التي تتجاهلها Git.
فهم إخراج git status
أمر git status هو أفضل صديق لك في Git. يظهر لك بالضبط ما يحدث في مستودعك:
# التحقق من حالة المستودع
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: index.html
modified: style.css
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: script.js
Untracked files:
(use "git add <file>..." to include in what will be committed)
config.json
تحليل الإخراج
1. معلومات الفرع:
"On branch main" - أنت حالياً على فرع main
"Your branch is up to date" - فرعك المحلي يطابق البعيد
2. التغييرات المراد الالتزام بها (مدرجة):
الملفات المدرجة والجاهزة للالتزام
• new file: ملف جديد تماماً مضاف إلى Git
• modified: ملف موجود تم تغييره وتدريجه
3. التغييرات غير المدرجة للالتزام (معدلة):
الملفات التي تتتبعها Git لكن لديها تغييرات غير مدرجة
لقد عدلتها لكن لم تشغل git add بعد
4. الملفات غير المتتبعة:
الملفات التي تراها Git لكن لا تتتبعها
ملفات جديدة لم تضف أبداً
إخراج الحالة المضغوط
# تنسيق الحالة القصير
git status -s
git status --short
الإخراج:
M style.css # تعديل مدرج
M script.js # تعديل غير مدرج
A index.html # ملف جديد مدرج
?? config.json # ملف غير متتبع
MM README.md # معدل، مدرج، ثم معدل مرة أخرى
رموز الحالة:
?? = غير متتبع
A = مضاف (ملف جديد مدرج)
M = معدل
D = محذوف
R = أعيدت تسميته
C = منسوخ
MM = معدل في التدريج ومجلد العمل
نصيحة احترافية: استخدم git status -s للحصول على نظرة عامة سريعة، و git status للحصول على معلومات تفصيلية مع تلميحات مفيدة.
طرق مختلفة لتدريج الملفات
1. تدريج ملفات محددة
# تدريج ملف واحد
git add filename.txt
# تدريج عدة ملفات محددة
git add file1.txt file2.css file3.js
# تدريج الملفات بنمط
git add *.html # جميع ملفات HTML في المجلد الحالي
git add src/*.js # جميع ملفات JS في مجلد src
git add **/*.css # جميع ملفات CSS بشكل متكرر
2. تدريج جميع التغييرات
# تدريج جميع التغييرات في المجلد الحالي والمجلدات الفرعية
git add .
# تدريج جميع التغييرات في المستودع بالكامل (موصى به)
git add -A
git add --all
# تدريج الملفات المعدلة والمحذوفة فقط (وليس الملفات الجديدة)
git add -u
git add --update
الفرق بين git add . و git add -A:
git add .
• يدرج كل شيء في المجلد الحالي والمجلدات الفرعية
• نسبي لموقعك الحالي
git add -A
• يدرج كل شيء في المستودع بالكامل
• يعمل من أي مجلد
• أكثر قابلية للتنبؤ وأكثر أماناً
التوصية: استخدم git add -A للاتساق
3. التدريج التفاعلي (git add -p)
درج أجزاء من الملفات بدلاً من الملفات بأكملها:
# وضع الرقعة التفاعلي
git add -p filename.txt
git add --patch
ما يحدث:
Git تظهر كل تغيير (جزء) وتسأل ماذا تفعل:
Stage this hunk [y,n,q,a,d,s,e,?]?
y - نعم، درج هذا الجزء
n - لا، لا تدرج هذا الجزء
q - أنهِ، لا تدرج هذا أو الأجزاء المتبقية
a - درج هذا وجميع الأجزاء المتبقية
d - لا تدرج هذا أو الأجزاء المتبقية
s - قسم هذا الجزء إلى أجزاء أصغر
e - حرر هذا الجزء يدوياً
? - أظهر المساعدة
سيناريو مثال:
لديك ملف واحد بإصلاحين منفصلين لخطأين:
1. إصلاح للتحقق من تسجيل الدخول
2. إصلاح لإعادة تعيين كلمة المرور
باستخدام git add -p:
• درج الإصلاح #1: y
• لا تدرج الإصلاح #2: n
النتيجة: يمكنك الالتزام بالإصلاح #1 بشكل منفصل!
هذا يحافظ على التزاماتك ذرية ومنطقية.
حالة الاستخدام: التدريج التفاعلي مثالي عندما تكون قد أجريت تغييرات متعددة غير مرتبطة على نفس الملف وتريد الالتزام بها بشكل منفصل.
4. الوضع التفاعلي (git add -i)
# الوضع التفاعلي الكامل
git add -i
git add --interactive
يوفر قائمة:
*** Commands ***
1: status 2: update 3: revert 4: add untracked
5: patch 6: diff 7: quit 8: help
يسمح لك بـ:
• رؤية الحالة
• تدريج الملفات بشكل تفاعلي
• إلغاء تدريج الملفات
• إضافة ملفات غير متتبعة
• عرض الاختلافات
نقل وإعادة تسمية الملفات
# إعادة تسمية ملف
git mv old-name.txt new-name.txt
# نقل ملف إلى مجلد مختلف
git mv file.txt src/file.txt
# إعادة التسمية والنقل في أمر واحد
git mv old-name.txt src/new-name.txt
ما يفعله git mv:
1. يعيد تسمية/ينقل الملف في مجلد العمل
2. يدرج حذف الملف القديم
3. يدرج إضافة الملف الجديد
4. Git تتعرف عليه كإعادة تسمية (وليس حذف + إضافة)
لماذا تستخدم git mv بدلاً من mv العادي؟
الطريقة العادية (يدوية):
mv old.txt new.txt
git rm old.txt
git add new.txt
طريقة Git (تلقائية):
git mv old.txt new.txt
الفوائد:
✓ أمر واحد بدلاً من ثلاثة
✓ Git تحافظ على تاريخ الملف
✓ تاريخ التزام أنظف
إزالة الملفات
# إزالة الملف من Git ومجلد العمل
git rm filename.txt
# إزالة الملف من Git لكن احتفظ به في مجلد العمل
git rm --cached filename.txt
# إزالة ملفات متعددة
git rm *.log
# إزالة مجلد
git rm -r directory-name/
# إزالة قسرية (إذا كان الملف لديه تغييرات)
git rm -f filename.txt
متى تستخدم git rm مقابل rm:
rm العادي:
rm file.txt # يزيل فقط من القرص
git add file.txt # يجب تدريج الحذف يدوياً
Git rm:
git rm file.txt # يزيل ويدرج في خطوة واحدة
حالات الاستخدام الشائعة:
# التزمت عن طريق الخطأ بملف حساس
git rm --cached .env # أزل من Git، احتفظ به محلياً
# إزالة جميع ملفات السجل
git rm *.log # إزالة كاملة
# إزالة الملف لكن احتفظ بنسخة محلية
git rm --cached temp.txt # احتفظ به للتطوير المحلي
مهم: git rm --cached يزيل الملف من Git لكن يحتفظ به في مجلد عملك. هذا مفيد للملفات التي تريد الاحتفاظ بها محلياً لكن لا تتتبعها في Git (مثل ملفات التكوين).
تجاهل الملفات باستخدام .gitignore
ليست كل الملفات يجب أن تتتبعها Git. ملف .gitignore يخبر Git بالملفات التي يجب تجاهلها:
إنشاء .gitignore
# إنشاء ملف .gitignore
touch .gitignore
# التحرير بمحررك المفضل
nano .gitignore
# الإضافة إلى Git
git add .gitignore
git commit -m "Add .gitignore"
أنماط .gitignore الشائعة
# مثال على ملف .gitignore
# التبعيات
node_modules/
vendor/
# ملفات البيئة
.env
.env.local
.env.*.local
# السجلات
*.log
logs/
npm-debug.log*
# ملفات نظام التشغيل
.DS_Store # macOS
Thumbs.db # Windows
*.swp # Vim
# ملفات IDE
.vscode/
.idea/
*.sublime-project
# مخرجات البناء
dist/
build/
*.min.js
*.min.css
# الملفات المؤقتة
*.tmp
*.temp
tmp/
# ملفات قاعدة البيانات
*.sqlite
*.db
# الملفات المترجمة
*.class # Java
*.pyc # Python
*.o # C/C++
# ملف محدد
config/secret.json
# جميع الملفات في المجلد
cache/*
# جميع ملفات .txt في الجذر فقط
/*.txt
# استثناء: لا تتجاهل هذا الملف
!important.txt
قواعد نمط .gitignore
مطابقة النمط:
*.log # تجاهل جميع ملفات .log
build/ # تجاهل مجلد build بالكامل
temp # تجاهل ملف أو مجلد temp
/TODO.txt # تجاهل فقط في مجلد الجذر
doc/**/*.pdf # تجاهل ملفات PDF في أي مكان تحت doc/
النفي (الاستثناءات):
*.log # تجاهل جميع ملفات السجل
!important.log # لكن تتبع important.log
التعليقات:
# هذا تعليق
# استخدم # في بداية السطر
الأسطر الفارغة:
يتم تجاهل الأسطر الفارغة (استخدم للتنظيم)
أفضل ممارسة: أنشئ .gitignore في بداية مشروعك. إنه أسهل بكثير من إزالة الملفات لاحقاً التي تم تتبعها عن طريق الخطأ.
ما الذي يجب عليك تجاهله؟
تجاهل دائماً:
✓ التبعيات (node_modules/, vendor/)
✓ مخرجات البناء (dist/, build/)
✓ متغيرات البيئة (.env)
✓ مفاتيح API والأسرار
✓ كلمات المرور وبيانات الاعتماد
✓ ملفات نظام التشغيل (.DS_Store)
✓ تكوين IDE (.vscode/, .idea/)
✓ ملفات السجل (*.log)
✓ الملفات المؤقتة (*.tmp)
✓ ملفات قاعدة البيانات (*.sqlite)
لا تتجاهل أبداً:
✗ الكود المصدري
✗ الوثائق
✗ قوالب التكوين (.env.example)
✗ الاختبارات
✗ ملفات README
.gitignore العالمي
# إعداد .gitignore عالمي لجميع المستودعات
git config --global core.excludesfile ~/.gitignore_global
# إنشاء الملف
touch ~/.gitignore_global
# إضافة أنماط شائعة
echo ".DS_Store" >> ~/.gitignore_global
echo "*.swp" >> ~/.gitignore_global
echo ".vscode/" >> ~/.gitignore_global
حالة الاستخدام:
ضع التفضيلات الشخصية هنا (IDE، ملفات نظام التشغيل)
احتفظ بالتجاهلات الخاصة بالمشروع في .gitignore للمشروع
التحقق من الملفات المتجاهلة
# انظر إلى الملفات المتجاهلة
git status --ignored
# تحقق إذا كان ملف محدد متجاهل
git check-ignore -v filename.txt
الإخراج يظهر:
.gitignore:3:*.txt filename.txt
(الملف، رقم السطر، النمط، اسم الملف)
# قائمة جميع الملفات المتجاهلة
git ls-files --others --ignored --exclude-standard
إلغاء تتبع الملفات المتتبعة بالفعل
المشكلة:
أضفت ملفاً إلى .gitignore، لكن Git لا تزال تتتبعه
(لأنه التزمت به قبل إنشاء .gitignore)
الحل:
# إزالة من Git لكن احتفظ به محلياً
git rm --cached filename.txt
# إزالة مجلد من Git لكن احتفظ به محلياً
git rm -r --cached directory/
# إزالة كل شيء وإعادة الإضافة (خيار نووي)
git rm -r --cached .
git add .
# الالتزام بالتغييرات
git commit -m "Remove ignored files from tracking"
النتيجة:
الملف لم يعد متتبعاً لكن يبقى على قرصك
مهم: إذا التزمت بملف ودفعته سابقاً، فهو في تاريخ Git. حتى بعد إزالته، لا يزال الآخرون يمكنهم رؤيته في الالتزامات القديمة. استخدم أدوات مثل git-filter-repo لإزالة البيانات الحساسة تماماً من التاريخ.
ملفات .gitignore القالب
GitHub توفر قوالب لمختلف اللغات/الأطر:
زيارة: https://github.com/github/gitignore
القوالب المتاحة:
• Node.js
• Python
• Java
• Ruby
• PHP
• Laravel
• React
• وأكثر من 100+
استخدام قالب:
1. زيارة المستودع
2. ابحث عن لغتك/إطار العمل
3. انسخ محتوى .gitignore
4. الصق في ملف .gitignore الخاص بك
أو استخدم GitHub عند إنشاء المستودع:
• اختر قائمة "Add .gitignore" المنسدلة
• اختر لغتك
مثال عملي: سير عمل كامل
# ابدأ مشروعاً جديداً
mkdir my-app && cd my-app
git init
# أنشئ .gitignore أولاً
cat > .gitignore << EOF
node_modules/
.env
*.log
dist/
EOF
# أنشئ ملفات المشروع
echo "console.log('Hello');" > app.js
echo "API_KEY=secret123" > .env
mkdir dist
# تحقق من الحالة
git status
الإخراج:
Untracked files:
.gitignore
app.js
(لاحظ .env غير معروض - إنه متجاهل!)
# درج والتزم
git add .
git commit -m "Initial commit with source code"
# أنشئ ملف سجل (سيتم تجاهله)
echo "Error log" > error.log
# تحقق من الحالة
git status
الإخراج:
nothing to commit, working tree clean
(error.log متجاهل)
# تحقق من الملفات المتجاهلة
git status --ignored
الإخراج يظهر error.log متجاهل
تمرين عملي:
تدرب على تتبع وتجاهل الملفات:
- أنشئ مستودع Git جديد
- أنشئ .gitignore يتجاهل *.log و temp/
- أنشئ: index.html، style.css، debug.log، temp/cache.txt
- شغل git status وتحقق من أن .log و temp/ متجاهلين
- درج فقط index.html
- تحقق من الحالة باستخدام git status -s
- درج الملفات المتتبعة المتبقية
- التزم بجميع التغييرات
الأوامر:
mkdir test-repo && cd test-repo git init echo -e "*.log\ntemp/" > .gitignore touch index.html style.css debug.log mkdir temp && touch temp/cache.txt git status git add index.html git status -s git add . git commit -m "Add website files"
الملخص
في هذا الدرس، تعلمت:
- كيفية قراءة وتفسير إخراج git status بالتفصيل
- طرق مختلفة لتدريج الملفات: محدد، الكل، الأنماط، التفاعلي
- كيفية استخدام git add -p لتدريج أجزاء من الملفات
- نقل وإعادة تسمية الملفات باستخدام git mv
- إزالة الملفات باستخدام git rm و git rm --cached
- إنشاء واستخدام ملفات .gitignore
- أنماط .gitignore الشائعة وأفضل الممارسات
- كيفية التحقق من الملفات المتجاهلة
- إلغاء تتبع الملفات المتتبعة سابقاً
- استخدام قوالب .gitignore لمشاريع مختلفة
التالي: في الدرس التالي، سنتعلم عن إجراء الالتزامات، وكتابة رسائل التزام محترفة، وتعديل الالتزامات عندما ترتكب أخطاء!