الفصل 02Chapter 02

سجل التطوير (Git History) Development History

تتبع رحلة بناء MRE CashBook من البداية، وكيف تطورت الشيفرة البرمجية عبر الزمن. Tracking the journey of building MRE CashBook from the start, and how the code evolved over time.

⚙️ تجهيز بيئة الـ Git Git Environment Setup

قبل أي كود، كان لازم نبدأ بـ Version Control عشان نحفظ كل خطوة. بنستخدم Git كأداة أساسية.

Before any code, we had to start with Version Control to save every step. We use Git as our primary tool.

🖥️ Terminal Command
git init
git init
🔍 بيعمل إيه؟🔍 What does it do?

بيحول الفولدر الحالي لمستودع (Repository) محلي، وبيعمل فولدر مخفي اسمه `.git` فيه كل التاريخ.

Converts the current folder into a local repository, creating a hidden `.git` folder containing all history.

🖥️ Terminal Command
git config --global user.name "Your Name"
git config --global user.name "Your Name"
🔍 بيعمل إيه؟🔍 What does it do?

بيعرف Git مين اللي عمل الـ commit ده. ده مهم جداً في المشاريع الجماعية.

Tells Git who made this commit. This is crucial for collaborative projects.

الجدول الزمني للتطوير Development Timeline

المشروع مر بمراحل كتير، كل مرحلة كانت بتمثل تحدي تقني مختلف.

The project went through many phases, each representing a different technical challenge.

1
التأسيس وتجهيز الـ Clean Architecture Foundations & Clean Architecture Setup

في أول commits، ركزنا على بناء هيكل يقدر يستوعب ميزات كتير من غير ما الكود يبوظ.

In the first commits, we focused on building a structure that can handle many features without code rot.

📁 Root Directory (Commit: Initial)
lib/
├── core/         # Shared utilities, themes, and config
├── features/     # Business modules (Data, Domain, Presentation)
└── init_di.dart  # Dependency Injection setup

فلسفة البداية: "ابني صح من الأول عشان ترتاح في الآخر". استخدام Clean Architecture في البداية وفر علينا ساعات من الـ refactoring لاحقاً.

Founder's Philosophy: "Build it right first to rest later." Using Clean Architecture from the start saved us hours of refactoring later.

2
دعم الشاشات الكبيرة (Micro-Responsiveness) Micro-Responsiveness & Tablet Support

في الـ commit رقم 896e52fe، تم إضافة نظام الـ Responses المتقدم اللي بيتعامل مع الـ Tablets والـ iPads.

In commit 896e52fe, we added the advanced Responsive system for Tablets and iPads.

🖥️ Terminal Command
git show 896e52fe
git show 896e52fe
🔍 بيعمل إيه؟🔍 What does it do?

بيعرض التغييرات اللي حصلت في commit معين بالتفصيل (Diff).

Shows changes made in a specific commit in detail (Diff).

FeatureReasoning
Adaptive LayoutsSwitching between BottomNav and NavigationRail.
Micro-SpacingAdjusting padding based on screen width using AppSizes.
Constraint BoxesPreventing forms from taking too much width on Desktops.
3
تطوير نظام الـ PDF والتقارير PDF & Reporting System Evolution

أحد أصعب التحديات كان طباعة اللغة العربية بوضوح في الـ PDF. جربنا حلول كتير لحد ما وصلنا لاستخدام خطوط مخصصة (Custom Fonts) مدمجة.

One of the hardest challenges was printing Arabic clearly in PDFs. we tried many solutions until we settled on embedded custom fonts.

التحدي: مكتبة PDF العادية مش بتدعم الـ RTL (Right-to-Left) بشكل طبيعي، فكان لازم نستخدم مكاتب مساعدة وشغل يدوي لإعادة ترتيب الحروف.

Challenge: Standard PDF libraries don't support RTL naturally, so we used helper libs and manual work to reorder characters.

4
إدارة الـ Assets والـ Screenshots Asset & Screenshot Management

في الـ commit ccc49420، أضفنا device_preview_screenshot عشان نقدر نولد صور دعائية للتطبيق بسهولة من جوه التطبيق نفسه.

In commit ccc49420, we added device_preview_screenshot to generate promotional images easily from within the app.

🏷️ رحلة الـ Rebranding (Ledger ➜ MRE) The Rebranding Saga

كان قرار جريء جداً تغيير اسم المشروع في نص الطريق. ده استلزم تعديلات في أكتر من 50 ملف!

It was a bold decision to change the project name mid-way. It required modifications in over 50 files!

1
تغيير هوية التطبيق في الـ Pubspec
# Original
name: ledger
description: A new Flutter project.

# New
name: mre_cashbook
description: The ultimate financial manager.
2
تغيير اسم الملفات والـ Imports

كل الـ imports في المشروع كان لازم تتغير من package:ledger/... إلى package:mre_cashbook/.... دي عملية مرهقة لو اتعملت مانيوال.

All imports had to change from package:ledger/... to package:mre_cashbook/.... This is exhausting if done manually.

🖥️ Terminal Command (Global Replace)
grep -rl "package:ledger" . | xargs sed -i '' 's/package:ledger/package:mre_cashbook/g'
grep -rl "package:ledger" .
🔍 بتعمل إيه؟🔍 What does it do?

بتبحث داخل كل الملفات (Recursive) عن جملة "package:ledger" وبتطلع لستة بأسماء الملفات اللي فيها الجملة دي.

Searches within all files (Recursive) for the string "package:ledger" and outputs a list of filenames containing it.

| xargs sed -i '' 's/.../.../g'
🔍 بتعمل إيه؟🔍 What does it do?

بتاخد لستة الملفات وتنفذ عليهم أمر sed اللي بيعمل استبدال (Replace) للنص القديم بالنص الجديد جوه الفايلات فوراً.

Takes the file list and executes sed, which replaces the old text with the new text inside the files immediately.

3
تغيير المعرف الفريد (Bundle ID)

تغيير الـ PRODUCT_BUNDLE_IDENTIFIER في iOS والـ applicationId في Android.

Changing PRODUCT_BUNDLE_IDENTIFIER in iOS and applicationId in Android.

تحذير: الخطوة دي بتمسح بيانات الـ Firebase وبتخليك تضطر تعمل App جديد على Firebase Console ببيانات الـ ID الجديد عشان الـ Notifications والـ Analytics يشتغلوا.

Warning: This step disconnects Firebase and forces you to create a new App on Firebase Console with the new ID for Notifications and Analytics to work.

🌱 البداية الحقيقية (The Genesis) The First Commit Analysis

في أول commit للمشروع، تم إنشاء 123 ملفاً دفعة واحدة! دي كانت "البيج بانج" اللي حطت أساسات كل حاجة بنشوفها النهاردة.

In the project's first commit, 123 files were created at once! This was the "Big Bang" that laid the foundations of everything we see today.

📁 First Commit Stats
123 files changed, 4915 insertions(+)
create mode 100644 lib/main.dart
create mode 100644 pubspec.yaml
create mode 100644 .gitignore
create mode 100644 android/app/src/main/AndroidManifest.xml
create mode 100644 ios/Runner/Info.plist
... and 118 more files
1
تحليل الملفات الأساسية في البداية
FilePurpose at GenesisDetails
lib/main.dart Entry Point البداية كانت بسيطة جداً مع Counter app، وبعدها اتحولت لمنصة إدارة مالية.
pubspec.yaml Registry مكان تعريف المكاتب. أول مجموعة مكاتب كانت للـ UI والـ Fonts بس.
.gitignore Safety منع رفع ملفات الـ build والـ secrets لـ GitHub.
android/ folders Native Config تحميل الـ SDKs المطلوبة وتجهيز الـ permissions المبدئية.
🌿 استراتيجية الفروع (Branching Strategy) Branching Strategy

عشان نحافظ على استقرار التطبيق، بنستخدم استراتيجية تشبه الـ GitFlow ولكن بشكل مبسط.

To maintain app stability, we use a simplified GitFlow-like strategy.

  • Main Branch: الفرع المقدس، دايماً عليه النسخة المستقرة والقابلة للنشر.
  • Dev Branch: فرع التطوير، بنجمع فيه كل الميزات قبل ما نرفعها للـ Main.
  • Feature Branches: أي ميزة جديدة بتتعمل في فرع لوحدها (مثل feat/charts).
  • Hotfix Branches: لتصليح أي Bug طارئ في النسخة المنشورة.
🖥️ Terminal Command: Create Feature
git checkout -b feat/advanced-filters
git checkout -b feat/advanced-filters
🔍 بتعمل إيه؟🔍 What does it do?

بتعمل نسخة جديدة من الكود في "غرفة جانبية" عشان تجرب فيها الفلاتر الجديدة من غير ما تأثر على الكود اللي شغال.

Creates a new code version in a "side room" to experiment with new filters without affecting the working code.

🧪 مختبر Git التفاعلي (Interactive Lab) Interactive Git Lab

هنا هنمشي خطوة بخطوة مع أهم الأوامر اللي استخدمناها في دورة حياة التطبيق.

Here we'll go step-by-step with the most important commands used in the app's lifecycle.

🖥️ Terminal Command: History Check
git log --oneline --graph --all
git log --oneline --graph --all
🔍 بيعمل إيه؟🔍 What does it do?

بيعرض تاريخ المشروع بشكل "شجري" (Tree) ملون، وكل commit في سطر واحد بس.

Displays project history in a colorful "tree" format, with each commit on a single line.

🖥️ Terminal Command: Who wrote this?
git blame lib/main.dart
git blame lib/main.dart
🔍 بيعمل إيه؟🔍 What does it do?

بيعرض كل سطر في الفايل ومين المبرمج اللي كتبه وأمتى. مفيد جداً لمعرفة "ليه السطر ده اتكتب كده".

Shows every line in the file, who wrote it, and when. Very useful to know "why this line was written this way".

🖥️ Terminal Command: Temporary Save
git stash
git stash
🔍 بيعمل إيه؟🔍 What does it do?

بيخبي التعديلات الحالية "على جنب" عشان تقدر تغير الـ branch من غير ما تعمل commit.

Temporarily slides your current changes aside so you can switch branches without committing.

🖥️ Terminal Command: Restore from Stash
git stash pop
git stash pop
🔍 بيعمل إيه؟🔍 What does it do?

بيرجع التعديلات اللي كنت مخبيها بالـ stash وبيطبقها على الكود الحالي.

Restores the changes you stashed and applies them to the current code.

🖥️ Terminal Command: Undo Last Commit (Soft)
git reset --soft HEAD~1
git reset --soft HEAD~1
🔍 بتعمل إيه؟🔍 What does it do?

بترجع في كلامك عن آخر commit عملته بس بتحافظ على كل مجهودك وتعديلاتك في الـ staging area.

Undoes your last commit but keeps all your work and modifications in the staging area.

📚 قاموس Git التقني الشامل Comprehensive Git Glossary

عشان تفهم الـ logic بتاع Git صح، لازم تعرف المصطلحات دي كويس:

To understand Git logic, you must know these terms well:

TermMeaning (English)المعنى (عربي)
Repository (Repo)Storage space for project history.المستودع أو "المخزن" اللي فيه تاريخ الكود.
CommitA snapshot of changes at a point in time."لقطة" أو سيف للكود في لحظة معينة.
Stage (Index)Preparation area before committing.منطقة "التحضير" قبل ما تعمل السيف النهائي.
BranchA parallel version of the codebase.فرع أو نسخة موازية من الكود للتجربة.
MergeCombining changes from different branches.دمج التعديلات من فرع للتاني.
ConflictWhen two changes overlap at same line.تضارب (لما مبرمجين يغيروا نفس السطر).
RemoteCopy of project hosted on servers (GitHub).النسخة المرفوعة أونلاين (زي GitHub).
FetchDownload updates without merging.تحميل التحديثات من غير ما تدمجها في كودك.
PullFetch + Merge in one command.تحميل التحديثات ودمجها فوراً.
PushUpload your local commits to Remote.رفع تعديلاتك من جهازك للسيرفر.
Cherry-pickApplying a specific commit from one branch to another.اختيار commit معين بس ونقله لفرع تاني.
RebaseMoving or combining a sequence of commits to a new base commit.إعادة ترتيب الـ commits عشان يبانوا كأنهم اتعملوا ورا بعض.
أفضل ممارسات الـ Git في المشروع Git Best Practices in MRE

عشان نحافظ على سجل نضيف، بنتبع القواعد دي:

To maintain a clean history, we follow these rules:

1
Semantic Commit Messages

بنبدأ كل رسالة بنوع التعديل:

  • feat: لإضافة ميزة جديدة.
  • fix: لتصليح bug.
  • refactor: لتحسين الكود من غير تغيير وظيفته.
  • chore: لتعديلات بسيطة (زي تحديث مكتبة).
2
Atomic Commits

كل commit لازم يعمل "حاجة واحدة بس". مبيكونش فيه تصليح bug مع ميزة جديدة في نفس الوقت.

Every commit must do "exactly one thing". No mixing bug fixes with new features.

⚔️ إدارة تضارب الكود (Merge Conflicts) Handling Merge Conflicts

التضارب بيحصل لما مبرمجين يغيروا نفس السطر في نفس الملف ويرفعوا كودهم في نفس الوقت. Git بيفقد القدرة على الدمج التلقائي وبيطلب تدخل بشري.

Conflicts happen when two devs change the same line in the same file and push at the same time. Git loses auto-merge ability and asks for human intervention.

📁 Conflict Markers Example
<<<<<<< HEAD
static const String appName = 'MRE CashBook';
=======
static const String appName = 'CashBook Pro';
>>>>>>> feature/branding-update
1
تحليل الرموز
  • <<<<<<< HEAD: الكود اللي عندك حالياً.
  • =======: الخط الفاصل.
  • >>>>>>> feature-branch: الكود اللي جاي من الفرع التاني.
2
خطوات الحل

لازم تختار كود واحد، أو تدمجهم مع بعض، وتمسح الرموز دي (Markers) وبعدين تعمل git add.

You must pick one version, or merge them, delete the markers, then run git add.

🖥️ Terminal Command: Abort Merge
git merge --abort
git merge --abort
🔍 بتعمل إيه؟🔍 What does it do?

بترجع الكود لحالته قبل ما تبدأ عملية الدمج الفاشلة. مفيدة لو الدنيا باظت منك وعاوز ترجع لنقطة الصفر.

Reverts everything back to the state before the failed merge. Useful if things got messy and you want to start over.

🪝 الـ Git Hooks والأتمتة Git Hooks & Automation

في MRE CashBook، بنستخدم الـ Hooks عشان نمنع رفع كود فيه أخطاء (Linting errors).

In MRE CashBook, we use Hooks to prevent pushing code with Linting errors.

!
Pre-commit Hook

ده سكريبت بيتفذ أوتوماتيك أول ما تدوس git commit. لو الـ Analyze بتاع Flutter لقى غلطة، الـ commit بيفشل.

A script that auto-runs when you hit git commit. If Flutter Analyze finds an error, the commit fails.

🖥️ Terminal Command: Manual Check
flutter analyze && flutter test
flutter analyze && flutter test
🔍 بتعمل إيه؟🔍 What does it do?

أول جزء بيفحص جودة الكود (Static Analysis)، وتاني جزء (بعد &&) بيشغل الاختبارات. الـ && معناها "لو الأول نجح، شغل التاني".

First part checks code quality, second part (after &&) runs tests. && means "if first succeeds, run second".

💡 نصائح احترافية لـ Git مع Flutter Flutter Git Pro Tips
1
إهمال ملفات الـ Generated

دايماً حط ملفات .g.dart و .freezed.dart في الـ .gitignore لو كنت بتستخدم Code Generation، عشان متملقاش الـ commits بتغييرات أوتوماتيكية.

Always ignore .g.dart and .freezed.dart in .gitignore if using Code Gen, to avoid cluttering commits.

2
استخدام Git Aliases

وفر وقتك واعمل اختصارات للأوامر الطويلة.

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
3
الـ Commit الصغير أحسن

لو عملت commit كل ما تخلص ويدجت واحدة، هتقدر ترجع في كلامك بسهولة لو حاجة باظت، بدل ما تضطر تمسح شغل يوم كامل.

Committing after finishing one widget lets you revert easily if something breaks, instead of losing a whole day's work.

خلاصة الخبرة: الكود هو السكن، والـ Git هو التأمين. لا تبخل على تأمين مستقبلك التقني.

Expert's Take: Code is the house, Git is the insurance. Don't skimp on securing your technical future.

أسئلة شائعة حول الـ Git في المشروع Git Historical FAQ
Q
ليه الـ Rebranding أخد وقت طويل؟ Why did Rebranding take so long?

لأننا مغيرناش بس الاسم اللي بيظهر لليوزر، إحنا غيرنا الـ Package Name والـ Folder Structure والـ Configuration بتاع Firebase. كل ده كان لازم يتم بدقة عشان التطبيق ميفقدش القدرة على الاتصال بالسيرفر.

Because we didn't just change the display name; we changed the Package Name, Folder Structure, and Firebase config. Everything had to be done precisely so the app wouldn't lose server connectivity.

Q
إيه هو الـ Commit اللي ندمنا عليه؟ Which commit did we regret?

كان فيه commit بدري جداً حاولنا فيه نستخدم قاعدة بيانات NoSQL، بس اكتشفنا إن الـ Data Relations في MRE معقدة جداً ومحتاجة SQL وقوة Drift. عملنا git revert ورجعنا للـ Drift.

There was a very early commit where we tried using NoSQL, but we discovered that MRE data relations are complex and needed SQL and Drift's power. We performed a git revert and went back to Drift.

Q
إزاي Git بيساعد في الـ PDF؟ How does Git help with PDF?

بفضل الـ History، قدرنا نقارن بين أكتر من 5 نسخ لمكتبات PDF مختلفة ونشوف مين اللي كان بيسبب تهنيج في الجهاز (Memory Leak) ومين اللي كان بيدعم العربي صح.

Thanks to History, we could compare over 5 versions of different PDF libraries to see which one caused memory leaks and which one supported Arabic correctly.

Q
هل بنستخدم Shorebird للـ Updates؟ Do we use Shorebird for updates?

نعم، واستخدام Git Branches مهم جداً هنا عشان نرفع الـ Pathches لـ Shorebird من غير ما نغير نسخة الـ Store الأساسية.

Yes, and using Git branches is crucial here to push patches to Shorebird without changing the main store version.

📝 ملخص الفصل Chapter Summary

اتعلمنا في الفصل ده إن الكود مش بس ملفات، ده تاريخ من القرارات. فهمنا إزاي Git بيحمينا وإزاي نتتبع التغييرات الكبيرة زي الـ Rebranding والـ Adaptive UI.

In this chapter, we learned that code isn't just files—it's a history of decisions. We understood how Git protects us and how to track major changes like Rebranding and Adaptive UI.

تذكر: الـ Git History هو "ذاكرة" المشروع. المبرمج الشاطر هو اللي بيسيب رسائل واضحة وتاريخ نضيف للي هيجي بعده.

Remember: Git History is the "memory" of the project. A good dev leaves clear messages and clean history for those who follow.

  • المحطة الجاية: هندخل جوه الفولدرات ونشوف توزيعة الملفات في الفصل الثالث: هيكل المشروع.

Next Stop: We'll go inside the folders and see the file distribution in Chapter 03: Project Structure.