البدء باستخدام Git: أنشئ أول مستودع لك

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

يحوّل هذا الدليل الفكرة السابقة إلى تمرين عملي متكامل. ستنشئ مشروعًا صغيرًا، وتبدأ مستودع Git، وتفحص حالات الملفات، وتجهز التغييرات، وتنشئ الالتزامات، وتتجاهل الملفات الناتجة تلقائيًا، وتقارن الإصدارات، ثم تتأكد من أن المستودع في حالة نظيفة.

الهدف ليس حفظ الأوامر، بل فهم ما الذي يتغير داخل Git بعد كل أمر تنفذه.

ما الذي سنبنيه؟

سننشئ مشروعًا صغيرًا يعمل من سطر الأوامر باسم Task Notes. سيبدأ المشروع بملف README وقائمة مهام نصية بسيطة.

سيكون الشكل النهائي للمشروع كما يلي:

task-notes/
├── .gitignore
├── README.md
├── notes/
│   └── tasks.txt
└── src/
    └── app.txt

خلال هذا التطبيق ستتعلم كيفية:

  • إنشاء مجلد جديد للمشروع.

  • بدء مستودع Git.

  • فحص مجلد .git المخفي.

  • قراءة مخرجات git status.

  • فهم حالات الملفات: غير المتتبعة، والمتتبعة، والمعدلة، والمجهزة، والمسجلة في التزام.

  • تجهيز ملفات منفردة أو مجموعات من الملفات.

  • إنشاء التزامات واضحة ومحددة الهدف.

  • استخدام git diff قبل إنشاء الالتزام.

  • تجاهل الملفات المؤقتة والحساسة.

  • إيقاف تتبع ملف في Git دون حذف نسخته المحلية.

  • عرض سجل مختصر لتاريخ المشروع.

  • التأكد من أن شجرة العمل نظيفة.

المتطلبات المسبقة

قبل المتابعة، تأكد من أن Git مثبت وأن هويتك مضبوطة:

git --version
git config --get user.name
git config --get user.email

يجب أن يعرض أمرا الاسم والبريد الإلكتروني الهوية التي تريد تسجيلها داخل الالتزامات الجديدة.

إذا كانت إحدى القيمتين مفقودة، فاضبطها:

git config --global user.name "Jane Developer"
git config --global user.email "jane@example.com"

تحقق أيضًا من اسم الفرع الأولي الافتراضي:

git config --get init.defaultBranch

إذا لم تظهر أي قيمة، يمكنك بدء المشروع صراحة باستخدام git init -b main، أو ضبط القيمة الافتراضية العامة:

git config --global init.defaultBranch main

طريقتان للحصول على مستودع Git

توجد طريقتان أساسيتان لبدء العمل على مستودع Git:

  1. بدء Git داخل مشروع محلي جديد أو موجود.

  2. استنساخ مستودع موجود من مكان آخر.

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

سنتناول الاستنساخ لاحقًا عند شرح المستودعات البعيدة والعمل التعاوني.

الخطوة 1: إنشاء مجلد المشروع

على macOS أو Linux أو Git Bash

mkdir task-notes
cd task-notes

على PowerShell

New-Item -ItemType Directory task-notes
Set-Location task-notes

في هذه اللحظة، لا يزال task-notes مجلدًا عاديًا فقط، ولا يقوم Git بتتبعه.

تحقق من المسار الحالي:

pwd

في PowerShell، يعرض الأمر Get-Location المعلومة نفسها:

Get-Location

تأكد من أنك داخل مجلد المشروع المقصود قبل بدء Git. قد يؤدي تشغيل git init داخل مجلد خاطئ إلى جعل Git يراقب ملفات لم تكن تنوي إضافتها.

الخطوة 2: بدء المستودع

نفّذ:

git init -b main

ستشير النتيجة الناجحة إلى إنشاء مستودع Git فارغ.

إذا كان إصدار Git لديك أو بيئة العمل لا تدعم الخيار -b، فنفّذ:

git init

ثم تحقق من اسم الفرع الأولي:

git branch --show-current

قبل إنشاء أول التزام، قد تصف بعض الأوامر الفرع بأنه غير مولود unborn، لأن اسم الفرع موجود من الناحية المنطقية لكنه لا يشير بعد إلى أي التزام.

ماذا يفعل git init فعليًا؟

ينشئ git init مجلدًا مخفيًا باسم .git داخل المشروع. يحتوي هذا المجلد على البيانات الداخلية التي يحتاج إليها Git لإدارة المستودع.

ويتضمن بنى خاصة بـ:

  • الكائنات التي تمثل محتوى المشروع والالتزامات.

  • مراجع الفروع والعلامات.

  • إعدادات خاصة بالمستودع.

  • منطقة التجهيز، التي تُسمّى أيضًا الفهرس index.

  • السجلات والبيانات الوصفية المستخدمة في عمليات Git.

تبقى ملفات المشروع الظاهرة داخل مجلد العمل، بينما يخزن Git بيانات المستودع الوصفية بصورة منفصلة داخل .git.

فحص المجلد المخفي

على macOS أو Linux أو Git Bash:

ls -la

على PowerShell:

Get-ChildItem -Force

يُفترض أن ترى المجلد .git.

لا تعدّل الملفات الموجودة داخل .git يدويًا ولا تحذفها إلا إذا كنت تفهم بنية Git الداخلية ولديك خطة استعادة. يؤدي حذف هذا المجلد إلى إزالة تاريخ المستودع وإعداداته من مجلد العمل.

هل يمكن تشغيل git init مرة أخرى؟

عادةً ما يعيد تشغيل git init داخل مستودع موجود تهيئة المستودع دون حذف تاريخ الالتزامات. لكن لا حاجة إلى تشغيله بصورة متكررة، ولن ينشئ مستودعًا متداخلًا جديدًا إلا إذا شغلته داخل مجلد فرعي منفصل.

الخطوة 3: فحص الحالة الأولية للمستودع

نفّذ:

git status

يُفترض أن توضح النتيجة أنك على الفرع الأولي، وأنه لا توجد التزامات بعد، ولا يوجد حاليًا شيء يحتاج إلى الالتزام.

يُعد git status من أهم الأوامر اليومية في Git. فهو يجيب عن أسئلة مثل:

  • على أي فرع أعمل؟

  • ما الملفات غير المتتبعة؟

  • ما الملفات المتتبعة التي تم تعديلها؟

  • ما التغييرات المجهزة للالتزام التالي؟

  • هل شجرة العمل نظيفة؟

شغّل هذا الأمر باستمرار. فهو أمر آمن للفحص فقط ولا يغيّر الملفات أو تاريخ المستودع.

مخرجات الحالة المختصرة

يوفر Git أيضًا صيغة مختصرة:

git status --short

في هذه المرحلة، يجب ألا يعرض الأمر أي نتيجة لأن المجلد لا يحتوي على ملفات مشروع.

الخطوة 4: إنشاء أول ملف في المشروع

على macOS أو Linux أو Git Bash

cat > README.md <<'EOF'
# Task Notes

مشروع صغير للتدرب على مسار العمل الأساسي في Git.

## الميزات

- حفظ ملاحظات المهام
- تنظيم ملفات المشروع
- التدرب على إنشاء التزامات Git مفهومة
EOF

على PowerShell

@"
# Task Notes

مشروع صغير للتدرب على مسار العمل الأساسي في Git.

## الميزات

- حفظ ملاحظات المهام
- تنظيم ملفات المشروع
- التدرب على إنشاء التزامات Git مفهومة
"@ | Set-Content README.md

الآن نفّذ:

git status

يُفترض أن يضع Git الملف README.md تحت قسم Untracked files.

ما الملف غير المتتبع؟

الملف غير المتتبع هو ملف موجود داخل مجلد العمل، لكنه لم يصبح بعد جزءًا من التاريخ الذي يتتبعه Git.

يعرف Git أن الملف موجود، لكنه لن يضيفه تلقائيًا إلى أي التزام.

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

تظهر الملفات غير المتتبعة في مخرجات الحالة المختصرة باستخدام علامتي استفهام:

git status --short

النتيجة المتوقعة:

?? README.md

الخطوة 5: تجهيز ملف README

نفّذ:

git add README.md

ثم افحص الحالة مرة أخرى:

git status

يُفترض أن يظهر الملف الآن تحت قسم Changes to be committed.

في الصيغة المختصرة:

A  README.md

يعني الحرف A أن الملف أُضيف إلى منطقة التجهيز.

ما معنى git add؟

يؤدي git add وظيفتين مترابطتين:

  • بدء تتبع ملف جديد.

  • تحديث النسخة المجهزة من ملف متتبع.

لا ينشئ هذا الأمر التزامًا، بل يجهز المحتوى الدقيق الذي سيسجله الالتزام التالي.

يمكنك تصور المسار بهذه الصورة:

مجلد العمل
       |
       | git add README.md
       v
   منطقة التجهيز
       |
       | git commit
       v
تاريخ المستودع

منطقة التجهيز لقطة محتوى وليست قائمة ملفات

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

هذا الفرق مهم؛ فقد تجهز ملفًا ثم تعدله مرة أخرى. سيحتفظ Git بالنسخة التي جُهزت للالتزام، بينما تبقى التعديلات الأحدث داخل مجلد العمل كتغييرات غير مجهزة.

سترى هذا السلوك عمليًا لاحقًا في التمرين.

الخطوة 6: مراجعة التغيير المجهز

نفّذ:

git diff --staged

قد ترى أيضًا الصيغة المكافئة:

git diff --cached

تعرض النتيجة ما الذي سيحتويه الالتزام التالي مقارنة بالالتزام الحالي. ولأن المستودع لا يحتوي على التزام سابق، يعرض Git الملف الجديد كاملًا على أنه محتوى مضاف.

استخدم هذا الأمر قبل الالتزامات المهمة، فهو يساعدك على اكتشاف:

  • شيفرة تصحيح أخطاء أُضيفت بالخطأ.

  • تغييرات لا علاقة لها بالمهمة.

  • بيانات اعتماد أو معلومات خاصة.

  • فروقات تنسيق غير ضرورية.

  • ملفات جُهزت بالخطأ.

يخبرك git status بالمسارات التي جرى تجهيزها، بينما يعرض git diff --staged المحتوى الفعلي سطرًا بسطر.

الخطوة 7: إنشاء أول التزام

نفّذ:

git commit -m "إنشاء ملف README للمشروع"

يتيح الخيار -m كتابة رسالة الالتزام مباشرة داخل سطر الأوامر.

ينشئ الالتزام الناجح أول لقطة مسجلة داخل المستودع.

تحقق من الحالة:

git status

النتيجة المتوقعة:

On branch main
nothing to commit, working tree clean

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

ما الذي يحتويه أول التزام؟

يخزن الالتزام:

  • النسخة المجهزة من README.md.

  • هوية المؤلف ومنشئ الالتزام.

  • التاريخ والوقت.

  • الرسالة إنشاء ملف README للمشروع.

  • معرّفًا فريدًا للالتزام.

  • مرجعًا إلى لقطة المشروع.

لا يملك الالتزام الأول التزامًا أبًا، لأنه يبدأ تاريخ المشروع.

الخطوة 8: عرض تاريخ الالتزامات

نفّذ:

git log

تعرض النتيجة معرّف الالتزام والمؤلف والتاريخ والرسالة.

لعرض تاريخ مختصر:

git log --oneline

مثال:

7a93c2e إنشاء ملف README للمشروع

سيختلف المعرّف لديك.

لفحص أحدث التزام والتغييرات التي يحتويها:

git show --stat
git show --oneline

يثبت نجاح أول التزام أن Git مثبت ومضبوط وقادر على تسجيل التاريخ بصورة صحيحة.

الخطوة 9: إضافة مجلدات وملفات المشروع

على macOS أو Linux أو Git Bash

mkdir -p notes src

cat > notes/tasks.txt <<'EOF'
[ ] تعلم git status
[ ] تعلم git add
[ ] تعلم git commit
EOF

cat > src/app.txt <<'EOF'
تطبيق Task Notes
الإصدار: 0.1.0
EOF

على PowerShell

New-Item -ItemType Directory notes, src

@"
[ ] تعلم git status
[ ] تعلم git add
[ ] تعلم git commit
"@ | Set-Content notes/tasks.txt

@"
تطبيق Task Notes
الإصدار: 0.1.0
"@ | Set-Content src/app.txt

نفّذ:

git status --short

بحسب الطريقة التي يلخص بها Git المجلدات غير المتتبعة، قد ترى:

?? notes/
?? src/

يتتبع Git الملفات، وليس المجلدات الفارغة. ولا يظهر المجلد في تاريخ المستودع إلا من خلال ملف متتبع بداخله.

تجهيز ملف واحد أو مجلد أو الشجرة الحالية

يمكنك تجهيز ملف محدد:

git add notes/tasks.txt

ويمكنك تجهيز جميع التغييرات المناسبة داخل مجلد:

git add src/

ويمكنك تجهيز التغييرات الموجودة تحت المجلد الحالي:

git add .

كما يمكنك تجهيز تحديثات المستودع كاملة باستخدام:

git add -A

المهم للمبتدئ ليس حفظ كل صيغة، بل تجنب التجهيز العشوائي دون مراجعة.

بعد أمر واسع مثل git add .، راجع دائمًا:

git status
git diff --staged

يوفر التجهيز الواسع الوقت، لكنه قد يضيف ملفات لم تكن تقصد تضمينها في الالتزام.

الخطوة 10: إنشاء التزام ثانٍ محدد الهدف

جهّز قائمة المهام فقط:

git add notes/tasks.txt

تحقق من الحالة:

git status --short

يُفترض أن ترى ملف المهام مجهزًا، بينما يبقى مجلد المصدر غير متتبع.

راجع المحتوى المجهز:

git diff --staged

أنشئ الالتزام:

git commit -m "إضافة مهام التعلم الأولية"

الآن جهّز وصف التطبيق وسجله في التزام مستقل:

git add src/app.txt
git commit -m "إضافة معلومات إصدار التطبيق"

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

اعرض التاريخ:

git log --oneline

مثال:

ca52d10 إضافة معلومات إصدار التطبيق
34e8c91 إضافة مهام التعلم الأولية
7a93c2e إنشاء ملف README للمشروع

لماذا تهم الالتزامات المركزة؟

يجب أن يمثل الالتزام وحدة عمل واحدة يسهل فهمها.

تسهّل الالتزامات المركزة:

  • المراجعة.

  • الشرح.

  • الاختبار.

  • البحث داخل التاريخ.

  • التراجع عند ظهور مشكلة.

  • نقل التغييرات بين الفروع لاحقًا.

لا يقدم التزام واحد باسم تحديث المشروع يغيّر التوثيق ومنطق التطبيق والتنسيق والإعدادات تاريخًا مفيدًا.

أما التاريخ الجيد فيوضح كيف تطور المشروع من خلال خطوات مقصودة.

الخطوة 11: تعديل ملف متتبع موجود

أضف قسمًا جديدًا إلى README.md.

على macOS أو Linux أو Git Bash

cat >> README.md <<'EOF'

## الاستخدام

افتح `notes/tasks.txt` وحدّث حالة المهام.
EOF

على PowerShell

@"

## الاستخدام

افتح `notes/tasks.txt` وحدّث حالة المهام.
"@ | Add-Content README.md

نفّذ:

git status --short

النتيجة المتوقعة:

 M README.md

موضع الحرف مهم في مخرجات الحالة المختصرة. هنا يوجد التغيير داخل مجلد العمل لكنه لم يُجهز بعد.

الخطوة 12: فحص التغييرات غير المجهزة

نفّذ:

git diff

من دون خيارات إضافية، يعرض git diff التغييرات الموجودة داخل مجلد العمل والتي لم تُجهز بعد.

أي أنه يقارن بين:

مجلد العمل ومنطقة التجهيز

أما:

git diff --staged

فيقارن بين:

منطقة التجهيز وأحدث التزام

فهم هذا الفرق أساسي.

الأمرما الذي يعرضه؟
git statusملخص حالات الملفات
git diffالتغييرات غير المجهزة سطرًا بسطر
git diff --stagedالتغييرات المجهزة للالتزام التالي سطرًا بسطر
git log --onelineتاريخ مختصر للالتزامات
git showتفاصيل التزام أو كائن Git آخر

الخطوة 13: رؤية نسخة مجهزة وأخرى غير مجهزة من الملف نفسه

جهّز النسخة الحالية من README:

git add README.md

الآن أضف سطرًا جديدًا دون تجهيزه.

على macOS أو Linux أو Git Bash

echo "" >> README.md
echo "يُستخدم هذا المشروع للتدرب على Git." >> README.md

على PowerShell

"" | Add-Content README.md
"يُستخدم هذا المشروع للتدرب على Git." | Add-Content README.md

نفّذ:

git status --short

يُفترض أن ترى:

MM README.md

يعني الحرف M الأول أن نسخة معدلة جرى تجهيزها. ويعني الحرف M الثاني أن مجلد العمل يحتوي على تعديل إضافي غير مجهز.

افحص كل طبقة:

# يعرض السطر الإضافي غير المجهز
git diff

# يعرض تغيير README الذي جرى تجهيزه سابقًا
git diff --staged

يوضح هذا المثال لماذا تُعد منطقة التجهيز لقطة مستقلة. عند تشغيل git add README.md التقط Git الملف كما كان في تلك اللحظة، ولم تحدث التعديلات اللاحقة النسخة المجهزة تلقائيًا.

لتضمين أحدث نسخة من مجلد العمل في الالتزام، جهّز الملف مرة أخرى:

git add README.md

الآن يجب ألا يعرض:

git diff

أي فرق غير مجهز، بينما يعرض:

git diff --staged

تحديث README كاملًا.

أنشئ الالتزام:

git commit -m "توثيق الاستخدام الأساسي للمشروع"

الخطوة 14: إنشاء ملف .gitignore

تُنتج المشاريع عادة ملفات لا ينبغي إدخالها إلى إدارة الإصدارات، مثل السجلات، والمخرجات المؤقتة، وملفات البيئة المحلية، ومجلدات الاعتماديات، وملفات التخزين المؤقت الخاصة بالمحرر.

أنشئ بعض الملفات التي يجب أن تبقى محلية.

على macOS أو Linux أو Git Bash

mkdir logs
echo "مخرجات مؤقتة للتطبيق" > logs/app.log
echo "APP_SECRET=لا-تسجل-هذا" > .env
echo "ملاحظات مؤقتة" > scratch.tmp

على PowerShell

New-Item -ItemType Directory logs
"مخرجات مؤقتة للتطبيق" | Set-Content logs/app.log
"APP_SECRET=لا-تسجل-هذا" | Set-Content .env
"ملاحظات مؤقتة" | Set-Content scratch.tmp

تحقق من الحالة:

git status --short

يُفترض أن يعرض Git المسارات الجديدة غير المتتبعة.

أنشئ ملف .gitignore.

على macOS أو Linux أو Git Bash

cat > .gitignore <<'EOF'
# أسرار البيئة المحلية
.env
.env.*

# سجلات التطبيق
logs/
*.log

# الملفات المؤقتة
*.tmp

# ملفات شائعة خاصة بأنظمة التشغيل
.DS_Store
Thumbs.db
EOF

على PowerShell

@"
# أسرار البيئة المحلية
.env
.env.*

# سجلات التطبيق
logs/
*.log

# الملفات المؤقتة
*.tmp

# ملفات شائعة خاصة بأنظمة التشغيل
.DS_Store
Thumbs.db
"@ | Set-Content .gitignore

نفّذ:

git status --short

يُفترض أن تختفي الملفات المتجاهلة من مخرجات الحالة العادية. ويبقى ملف .gitignore نفسه ظاهرًا لأنه يجب تسجيله كجزء من سياسة المشروع.

جهّزه وسجله:

git add .gitignore
git commit -m "تجاهل الأسرار المحلية والسجلات والملفات المؤقتة"

كيف تعمل أنماط .gitignore؟

تشمل الأنماط الشائعة:

# تجاهل ملف محدد
.env

# تجاهل جميع ملفات .log
*.log

# تجاهل مجلد ومحتوياته
logs/

# تجاهل الملفات المؤقتة في أي مكان
*.tmp

# تجاهل ملف موجود فقط في جذر المستودع
/config.local.php

# تجاهل كل شيء داخل build مع إبقاء ملف مطلوب
build/*
!build/.gitkeep

يُتجاهل السطر الفارغ، وتُعد الأسطر التي تبدأ بـ # تعليقات ما لم يُستخدم رمز الهروب.

يجب أن يصف ملف .gitignore على مستوى المستودع قواعد المشروع المشتركة. ويمكن حفظ أنماط المحرر ونظام التشغيل الشخصية داخل ملف تجاهل عام يخص مطورًا واحدًا.

.gitignore لا يؤثر في الملفات المتتبعة

هذه من أكثر النقاط التي تفاجئ المبتدئين.

إذا كان الملف متتبعًا بالفعل، فإن إضافة اسمه إلى .gitignore لن تزيله من تاريخ Git ولن تمنع Git من ملاحظة تعديلاته المستقبلية.

تنطبق قواعد التجاهل على الملفات المقصود إبقاؤها غير متتبعة.

لإيقاف تتبع ملف مع إبقائه داخل مجلد العمل:

git rm --cached path/to/file

ثم سجّل عملية إزالته من فهرس المستودع.

ولمجلد كامل:

git rm -r --cached path/to/directory

استخدم هذه الأوامر بحذر وراجع النتيجة المجهزة قبل الالتزام.

تشخيص قاعدة تجاهل

إذا لم تفهم لماذا يتجاهل Git ملفًا معينًا، فاستخدم:

git check-ignore -v logs/app.log

تعرض النتيجة ملف التجاهل والنمط المسؤول عن التطابق.

لعرض الملفات المتجاهلة داخل مخرجات الحالة:

git status --ignored --short

يفيد هذا الأمر عندما يبدو أن ملفًا مطلوبًا مفقود من المستودع.

الخطوة 15: إضافة مهمة أخرى وتسجيلها

حدّث notes/tasks.txt.

على macOS أو Linux أو Git Bash

cat > notes/tasks.txt <<'EOF'
[x] تعلم git status
[x] تعلم git add
[x] تعلم git commit
[ ] تعلم فروع Git
EOF

على PowerShell

@"
[x] تعلم git status
[x] تعلم git add
[x] تعلم git commit
[ ] تعلم فروع Git
"@ | Set-Content notes/tasks.txt

راجع التغيير:

git status
git diff

جهّزه:

git add notes/tasks.txt

راجع بدقة ما جرى تجهيزه:

git diff --staged

أنشئ الالتزام:

git commit -m "تحديث مهام تعلم Git المكتملة"

الخطوة 16: إعادة تسمية ملف متتبع

أعد تسمية src/app.txt إلى src/version.txt.

استخدم أمر النقل في Git:

git mv src/app.txt src/version.txt

تحقق من الحالة:

git status --short

يُفترض أن يعرض Git إعادة تسمية مجهزة، ويُعبَّر عنها غالبًا بالحرف R.

أنشئ الالتزام:

git commit -m "إعادة تسمية ملف معلومات التطبيق"

هل يخزن Git عمليات إعادة التسمية مباشرة؟

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

يمكنك أيضًا إعادة تسمية الملف بأمر من نظام التشغيل ثم تجهيز التغييرات. وقد يتعرف Git على النتيجة باعتبارها إعادة تسمية.

الخطوة 17: حذف ملف متتبع

لأغراض الشرح، أنشئ ملفًا قديمًا وسجله أولًا.

على macOS أو Linux أو Git Bash

echo "مسودة قديمة" > old-notes.txt
git add old-notes.txt
git commit -m "إضافة مسودة مؤقتة للمشروع"

على PowerShell

"مسودة قديمة" | Set-Content old-notes.txt
git add old-notes.txt
git commit -m "إضافة مسودة مؤقتة للمشروع"

الآن احذفه من خلال Git:

git rm old-notes.txt

يحذف هذا الأمر الملف من مجلد العمل ويجهز عملية الحذف.

راجع:

git status
git diff --staged

أنشئ الالتزام:

git commit -m "إزالة مسودة المشروع القديمة"

يمكن أيضًا حذف ملف متتبع باستخدام أمر من نظام التشغيل، لكن يجب تجهيز الحذف بعد ذلك.

فهم دورة حياة الملف

يمكن أن ينتقل الملف بين عدة حالات:

ملف جديد
   |
   v
غير متتبع
   |
   | git add
   v
مجهز
   |
   | git commit
   v
متتبع ومسجل
   |
   | تعديل الملف
   v
متتبع ومعدل
   |
   | git add
   v
مجهز من جديد
   |
   | git commit
   v
نسخة جديدة مسجلة

يمكن أيضًا حذف الملف المتتبع أو إعادة تسميته أو إزالته عمدًا من الفهرس.

الحالةالمعنىالإجراء التالي المعتاد
Untrackedالملف موجود لكن Git لا يتتبعهاستخدام git add أو إضافة قاعدة تجاهل
Modifiedملف متتبع يختلف عن نسخته المجهزةمراجعته باستخدام git diff
Stagedالنسخة المحددة جاهزة للالتزام التاليالمراجعة ثم الالتزام
Committedالنسخة مسجلة داخل تاريخ المستودعمتابعة التطوير
Ignoredمسار غير متتبع يطابق قاعدة تجاهلتركه محليًا عادة

قراءة git status --short

تستخدم الصيغة المختصرة عمودين للحالة:

XY PATH
  • X: الفرق بين أحدث التزام ومنطقة التجهيز.

  • Y: الفرق بين منطقة التجهيز ومجلد العمل.

أمثلة شائعة:

?? file.txt       ملف غير متتبع
A  file.txt       ملف جديد مجهز
 M file.txt       ملف متتبع معدل لكنه غير مجهز
M  file.txt       نسخة معدلة مجهزة
MM file.txt       تغيير مجهز مع تغيير إضافي غير مجهز
D  file.txt       حذف مجهز
R  old -> new     إعادة تسمية مجهزة

تُعد مخرجات الحالة الطويلة أسهل للمبتدئين، بينما تصبح الصيغة المختصرة مفيدة للفحص اليومي السريع والسكربتات.

أوامر مفيدة لمسارات محددة

لفحص ملف واحد فقط:

git status --short README.md

لعرض التغييرات غير المجهزة في ملف واحد:

git diff -- README.md

لعرض التغييرات المجهزة في ملف واحد:

git diff --staged -- README.md

لتجهيز مجلد واحد:

git add notes/

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

ما الذي قد يضيفه git add . بالخطأ؟

الأمر:

git add .

مريح، لكنه قد يجهز:

  • مخرجات تصحيح الأخطاء.

  • ملفات مؤقتة.

  • مخرجات بناء مولدة.

  • ملفات كبيرة.

  • إعدادات محلية.

  • بيانات اعتماد لم تُضف إلى التجاهل.

  • تعديلات لا علاقة لها بالمهمة الحالية.

استخدم التسلسل الآمن التالي:

git status
git add .
git status
git diff --staged
git commit -m "صِف التغيير المنطقي"

لا تفترض أبدًا أن أمر تجهيز واسع اختار الملفات التي تقصدها فقط.

لا تسجل الأسرار داخل Git

قبل أول التزام، وقبل إضافة ملفات إعداد جديدة، تحقق من عدم وجود:

  • كلمات مرور.

  • مفاتيح API.

  • سلاسل اتصال بقواعد البيانات.

  • بيانات اعتماد الخدمات السحابية.

  • مفاتيح SSH خاصة.

  • رموز وصول.

  • ملفات بيئة إنتاج حقيقية.

تساعد إضافة .env إلى .gitignore على منع تتبعه بالخطأ، لكن قواعد التجاهل ليست نظام حماية. راجع المحتوى المجهز قبل الالتزام.

إذا سُجل سر حقيقي داخل التزام، فإن حذفه في التزام لاحق لا يجعل القيمة القديمة آمنة. قم بتدوير السر أو إلغائه فورًا، ثم نظّف التاريخ باستخدام إجراء مناسب.

فحص المستودع النهائي

نفّذ:

git status
git log --oneline --decorate

يُفترض أن تعرض الحالة شجرة عمل نظيفة.

افحص الملفات المتتبعة:

git ls-files

المحتوى المتتبع المتوقع:

.gitignore
README.md
notes/tasks.txt
src/version.txt

يجب ألا تظهر الملفات المتجاهلة .env وlogs/app.log وscratch.tmp.

افحص الملفات المتجاهلة بصورة منفصلة:

git status --ignored --short

اعرض التاريخ على شكل رسم:

git log --oneline --graph --decorate --all

لأنه لا توجد فروع متباعدة حتى الآن، سيظهر الرسم كسلسلة مستقيمة من الالتزامات.

تتبع يدوي: ما الذي تغيّر بعد كل أمر؟

يلخص التتبع التالي الحالة الداخلية خلال التمرين.

1. قبل git init

مجلد العمل: موجود
مجلد .git: غير موجود
تاريخ المستودع: غير موجود
منطقة التجهيز: غير موجودة

2. بعد git init -b main

مجلد العمل: موجود
مجلد .git: أُنشئ
الفرع الحالي: main
الالتزامات: لا توجد
منطقة التجهيز: فارغة

3. بعد إنشاء README.md

README.md: غير متتبع
منطقة التجهيز: فارغة
الالتزامات: لا توجد

4. بعد git add README.md

README.md: متتبع ومجهز
منطقة التجهيز: تحتوي على لقطة README.md
الالتزامات: لا توجد

5. بعد أول git commit

README.md: متتبع ومسجل
أحدث التزام: إنشاء ملف README للمشروع
منطقة التجهيز: مطابقة لأحدث التزام
شجرة العمل: نظيفة

6. بعد تعديل README.md

النسخة المسجلة: محفوظة كما هي
النسخة المجهزة: ما زالت مطابقة للنسخة المسجلة
نسخة العمل: معدلة
git diff: يعرض التعديل الجديد

7. بعد التجهيز ثم التعديل مرة أخرى

النسخة المسجلة: المحتوى الأصلي المسجل
النسخة المجهزة: التعديل الجديد الأول
نسخة العمل: التعديل الأول مع التعديل الثاني
git diff --staged: يعرض التعديل الأول
git diff: يعرض التعديل الثاني

8. بعد التجهيز مرة أخرى ثم الالتزام

النسخة المسجلة: تحتوي على التعديلين
منطقة التجهيز: مطابقة لأحدث التزام
مجلد العمل: مطابق لمنطقة التجهيز
شجرة العمل: نظيفة

هذا هو نموذج Git الأساسي أثناء العمل.

أخطاء شائعة لدى المبتدئين

تشغيل git init داخل المجلد الخطأ

تحقق دائمًا من المسار الحالي قبل التهيئة. قد يبدأ مستودع أُنشئ في مستوى مرتفع من نظام الملفات بمراقبة ملفات لا علاقة لها بالمشروع.

افتراض أن git add ينشئ التزامًا

يجهز git add المحتوى، بينما يسجله git commit في التاريخ.

افتراض أن git commit يشمل كل الملفات المعدلة

يسجل الالتزام العادي المحتوى المجهز فقط. وتبقى التغييرات غير المجهزة والملفات غير المتتبعة خارج الالتزام.

استخدام git add . دون مراجعة

قد يضيف التجهيز الواسع ملفات غير مرتبطة أو حساسة. افحص الحالة والفرق المجهز معًا.

إنشاء “التزام أولي” ضخم دون فحص

حتى الالتزام الأول يجب أن يستبعد الملفات المولدة والاعتماديات والسجلات والأسرار والإعدادات المحلية.

إضافة ملف سري متتبع إلى .gitignore

لا توقف قواعد التجاهل Git عن تتبع ملف موجود بالفعل في التاريخ.

تعديل الملفات داخل .git

يمثل مجلد .git البنية الداخلية للمستودع. تعامل معه على أنه جزء داخلي ما لم تكن تدرس بنية Git عن قصد.

كتابة رسائل التزام بلا معنى

لا توضح رسائل مثل تغييرات أو تحديث أو إصلاح الغرض من اللقطة.

خلط عدة مهام داخل التزام واحد

يُفضّل فصل التوثيق وإعادة الهيكلة وإصلاح الأخطاء والميزات الجديدة عندما تمثل تغييرات منطقية مختلفة.

أفضل الممارسات لأول مستودعاتك

  • ابدأ Git في جذر المشروع.

  • أنشئ .gitignore قبل تجهيز مشروع كبير.

  • شغّل git status بصورة متكررة.

  • راجع العمل غير المجهز باستخدام git diff.

  • راجع الالتزام التالي باستخدام git diff --staged.

  • جهّز الملفات بوعي.

  • اجعل الالتزامات محددة الهدف.

  • اكتب رسائل التزام واضحة وموجهة إلى الفعل.

  • لا تسجل الأسرار أبدًا.

  • حاول إنهاء كل مهمة مكتملة بشجرة عمل نظيفة عندما يكون ذلك عمليًا.

مرجع الأوامر المستخدمة في هذا الدليل

الأمرالغرض
git init -b mainبدء مستودع بفرع أولي اسمه main
git statusعرض معلومات تفصيلية عن شجرة العمل ومنطقة التجهيز
git status --shortعرض رموز الحالة المختصرة
git add fileتجهيز النسخة الحالية من ملف واحد
git add .تجهيز التغييرات المناسبة تحت المجلد الحالي
git diffعرض التغييرات غير المجهزة
git diff --stagedعرض التغييرات المجهزة للالتزام التالي
git commit -m "message"إنشاء التزام من المحتوى المجهز
git log --onelineعرض تاريخ الالتزامات بصورة مختصرة
git showفحص أحدث التزام بصورة افتراضية
git check-ignore -v pathتوضيح قاعدة التجاهل التي تطابق المسار
git mv old newنقل ملف أو إعادة تسميته وتجهيز النتيجة
git rm fileإزالة ملف متتبع وتجهيز الحذف
git ls-filesعرض الملفات التي يتتبعها الفهرس حاليًا

قائمة التحقق للبدء

قبل الانتقال إلى المقالة الأكثر تعمقًا حول التجهيز والالتزامات، تأكد من أنك تستطيع:

  • إنشاء مجلد مشروع.

  • بدء مستودع باستخدام git init.

  • شرح وظيفة مجلد .git.

  • تمييز ملف غير متتبع.

  • تجهيز ملف محدد.

  • إنشاء التزام برسالة واضحة.

  • تمييز الفرق بين git diff وgit diff --staged.

  • شرح كيف يمكن لملف مجهز أن يحتوي أيضًا على تغييرات غير مجهزة.

  • إنشاء ملف .gitignore واختباره.

  • إدراك أن الملفات المتتبعة لا تتأثر بقواعد التجاهل الجديدة.

  • قراءة رموز الحالة المختصرة الشائعة.

  • التحقق من أن المستودع يملك شجرة عمل نظيفة.

الأسئلة الشائعة

هل يمكن تشغيل git init داخل مشروع موجود؟

نعم. يمكن بدء Git داخل مجلد مشروع موجود. أنشئ ملف .gitignore مناسبًا وافحص جميع الملفات غير المتتبعة قبل تجهيز أول التزام.

هل يرفع git init المشروع إلى الإنترنت؟

لا. ينشئ مستودعًا محليًا فقط. يتطلب رفع الالتزامات أو مشاركتها مستودعًا بعيدًا وعملية push لاحقة.

هل يتتبع Git المجلدات الفارغة؟

لا. يتتبع Git محتوى الملفات. تضع المشاريع أحيانًا ملفًا مثل .gitkeep داخل مجلد فارغ، لكن هذا الاسم لا يملك معنى خاصًا مدمجًا في Git.

ما الفرق بين git add وgit commit؟

يجهز git add نُسخ الملفات المحددة داخل منطقة التجهيز، بينما يسجل git commit اللقطة المجهزة داخل تاريخ المستودع.

لماذا لا يعرض git diff شيئًا بعد git add؟

يعرض git diff العادي التغييرات غير المجهزة فقط. بعد التجهيز، استخدم git diff --staged لفحص المحتوى المعد للالتزام التالي.

هل يمكن تسجيل ملف واحد فقط؟

نعم. جهّز ذلك الملف وحده، وراجع الفرق المجهز، ثم أنشئ الالتزام.

هل يجب استخدام git add . دائمًا؟

لا. هو مريح عندما تنتمي جميع التغييرات الحالية إلى المهمة نفسها، لكن تجهيز مسارات محددة أو استخدام التجهيز التفاعلي يمنحك تحكمًا أفضل عندما تختلط عدة مهام.

لماذا لا يزال الملف المتجاهل متتبعًا؟

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

ما معنى “Working Tree Clean”؟

يعني أن Git لا يرى تعديلات متتبعة أو فروقات مجهزة أو ملفات غير متتبعة قابلة للإبلاغ مقارنة بالالتزام الحالي وقواعد التجاهل.

هل يمكن حذف مجلد .git؟

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

الخلاصة

يعرض أول مستودع Git لك مسار العمل الأساسي كاملًا: بدء المشروع، وإنشاء الملفات، وفحص حالاتها، وتجهيز النسخ المحددة، ومراجعة المحتوى المجهز، وتسجيل التزامات واضحة.

أهم درس هو أن Git يدير عدة حالات في الوقت نفسه. يحتوي مجلد العمل على التعديلات الحالية، وتحتوي منطقة التجهيز على اللقطة المقترحة للالتزام التالي، بينما يخزن المستودع التاريخ المسجل. وتكشف أوامر مثل git status وgit diff وgit diff --staged الفروق بين هذه الحالات.

مسار العمل المنظم بسيط: افحص الحالة، وعدّل، وافحص مجددًا، وجهّز بوعي، وراجع الفرق المجهز، وأنشئ التزامًا برسالة مفهومة، ثم تحقق من الحالة النهائية.

ستتناول المقالة التالية التجهيز والالتزامات بمزيد من التفصيل، بما يشمل التجهيز الجزئي، وإخراج التغييرات من منطقة التجهيز، وتعديل الالتزامات، وبنية رسائل الالتزام، واستراتيجيات إنشاء تاريخ نظيف ومفيد.

المراجع الرسمية ومواد إضافية للقراءة