ناس كتير بتفتكر إن Git بيحفظ الفرق بين كل نسخة والتانية. الحقيقة أبسط من كده:
كل commit صورة كاملة للمشروع في لحظة معينة، ومعاها ورقة فيها مين عمله، وإمتى، وليه، وإيه الـ commit اللي قبله.
Git ذكي في التخزين، فالملف اللي متغيرش مش بيتخزن مرتين. بس في دماغك، فكّر فيه كصورة كاملة.
الـ commit جواه إيه؟
- snapshot للملفات كلها.
- الكاتب والتاريخ.
- الرسالة اللي إنت كتبتها.
- الـ parent: الـ commit اللي قبله. ده اللي بيربط الـ commits في سلسلة.
ومن كل ده، Git بيطلّع hash، رقم طويل زي a3f9c21.... ده اسم الـ commit. لو أي حاجة جواه اتغيرت، حتى حرف في الرسالة، الـ hash بيتغير. وده هيفرق جدًا لما نتكلم عن الـ rebase.
git log --oneline# a3f9c21 Add cart page# 7b2e014 Add product page# 1c0d9aa Init project
التلات أماكن
الملف بيعدّي على تلات أماكن قبل ما يبقى في commit:
Working treeالملفات اللي بتعدّلها
Staging areaاللي هيدخل الـ commit الجاي
Repositoryالـ commits المتسجلة
git status # إيه اللي اتغير، وإيه اللي في الـ staginggit add cart.tsx # حط الملف ده في الـ staginggit commit -m "Add cart page" # صوّر اللي في الـ staging
ليه الـ staging مهم؟
عشان تعمل commits صغيرة ومفهومة. لو عدّلت في الـ cart وصلّحت typo في الـ footer، متحطهمش في commit واحد:
git add src/cart/git commit -m "Add quantity limit to cart"git add src/footer.tsxgit commit -m "Fix footer typo"
وتقدر تحط جزء من ملف بس بـ git add -p، بيسألك على كل حتة اتغيرت: تحطها ولا لأ.
خلّصت الفصل لما
🧠 اختبر نفسك
١) إيه اللي بيربط الـ commits ببعض في سلسلة؟
الـ parent. كل commit فيه hash الـ commit اللي قبله.
٢) غيّرت رسالة commit قديم. الـ hash بتاعه هيفضل زي ما هو؟
لا. أي تغيير في الـ commit بيطلّع hash جديد، يعني commit جديد.
٣) ليه الـ staging area موجودة أصلًا؟
عشان تختار إيه بالظبط يدخل الـ commit، فتعمل commits صغيرة كل واحد فيه فكرة واحدة.