Git & GitHub
الدمج في Git — دليل شامل Merge 2026
📅 2026-11-25⏱ 8 دقائق قراءة
في المقال السابق، تعلمت الفروع. الآن سنتعلم **الدمج (Merge)** — كيف نُدمج الفروع ببعضها بأمان واحترافية.
في هذا الدليل العملي، سنأخذك خطوة بخطوة لفهم الدمج، مع تمارين وحلول.
## ما هو الدمج (Merge)؟
**الدمج** هو **ضم فرع** إلى فرع آخر.
**مثال:**
- أنت على `main`.
- أنشأت `feature/login` وأضفت فيها صفحة تسجيل دخول.
- بعد الانتهاء، **تدمج** `feature/login` في `main`.
## أنواع الدمج
<table>
<thead>
<tr>
<th>النوع</th>
<th>الوصف</th>
<th>متى يحدث</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Fast-forward</strong></td>
<td>تقديم مباشر</td>
<td>عندما لا يوجد تغييرات في main</td>
</tr>
<tr>
<td><strong>Three-way Merge</strong></td>
<td>دمج 3 نقاط</td>
<td>عندما تغيّر main أيضاً</td>
</tr>
<tr>
<td><strong>Squash Merge</strong></td>
<td>دمج كـ commit واحد</td>
<td>لتبسيط السجل</td>
</tr>
<tr>
<td><strong>Rebase</strong></td>
<td>إعادة ترتيب</td>
<td>لتاريخ نظيف</td>
</tr>
</tbody>
</table>
## Fast-forward Merge
**يحدث عندما:**
- `main` **لم يتغير** منذ إنشاء الفرع.
- الفرع **أمام** `main` بعدة commits.
**مثال:**
```bash
# 1. من main، أنشئ فرعاً
git checkout -b feature/login
# 2. أضف commits
echo "login" > login.html
git add .
git commit -m "feat: login"
echo "styles" > login.css
git add .
git commit -m "style: login styles"
# 3. ارجع لـ main
git checkout main
# 4. ادمج
git merge feature/login
```
**النتيجة:**
```
Updating abc1234..def5678
Fast-forward
login.html | 1 +
login.css | 1 +
2 files changed, 2 insertions(+)
```
**الفائدة:** سجل **خطي نظيف**.
## Three-way Merge
**يحدث عندما:**
- `main` **تغيّر** منذ إنشاء الفرع.
- لا يمكن "التقديم" مباشرة.
**مثال:**
```bash
# 1. من main، أنشئ فرعاً
git checkout -b feature/login
# 2. أضف commit
echo "login" > login.html
git add .
git commit -m "feat: login"
# 3. ارجع لـ main، وعدّل
git checkout main
echo "homepage" > index.html
git add .
git commit -m "feat: homepage"
# 4. ادمج
git merge feature/login
```
**النتيجة:**
```
Merge made by the 'ort' strategy.
login.html | 1 +
1 file changed, 1 insertion(+)
create mode 100644 login.html
```
**Git يُنشئ commit جديد** يجمع التغييرات.
## Squash Merge
**يدمج كل commits الفرع في commit واحد.**
```bash
git checkout main
git merge --squash feature/login
git commit -m "feat: إضافة تسجيل الدخول"
```
**الفائدة:** سجل **نظيف** بدون تفاصيل صغيرة.
**العيب:** تفقد تاريخ الفرع.
## Rebase
**بديل للـ Merge**، يُعيد ترتيب commits.
```bash
git checkout feature/login
git rebase main
# أو
git rebase main feature/login
```
**النتيجة:** commits الفرع **تظهر بعد** main.
**الميزة:** سجل **خطي تماماً**.
**⚠️ تحذير:** لا تستخدم `rebase` على commits **مرفوعة**.
## Merge vs Rebase
<table>
<thead>
<tr>
<th>المعيار</th>
<th>Merge</th>
<th>Rebase</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>السجل</strong></td>
<td>متشعب</td>
<td>خطي</td>
</tr>
<tr>
<td><strong>Commit إضافي</strong></td>
<td>✅ نعم</td>
<td>❌ لا</td>
</tr>
<tr>
<td><strong>الأمان</strong></td>
<td>✅ آمن دائماً</td>
<td>⚠️ خطر على commits مرفوعة</td>
</tr>
<tr>
<td><strong>الاستخدام</strong></td>
<td>في main</td>
<td>في الفروع المحلية</td>
</tr>
</tbody>
</table>
**القاعدة الذهبية:**
- **`merge`** على `main`.
- **`rebase`** على الفروع المحلية قبل الدمج.
## مثال عملي كامل
### السيناريو: إضافة ميزة جديدة
**الخطوة 1: تحديث main**
```bash
git checkout main
git pull
```
**الخطوة 2: إنشاء فرع**
```bash
git checkout -b feature/search
```
**الخطوة 3: العمل على الميزة**
```bash
echo "<input type='search'>" > search.html
git add .
git commit -m "feat: إضافة شريط البحث"
echo "input { padding: 10px; }" > search.css
git add .
git commit -m "style: تنسيق شريط البحث"
```
**الخطوة 4: رفع الفرع**
```bash
git push -u origin feature/search
```
**الخطوة 5: Pull Request على GitHub**
- اذهب إلى GitHub.
- اضغط **Compare & pull request**.
- املأ الوصف.
- اضغط **Create pull request**.
**الخطوة 6: بعد المراجعة، الدمج**
```bash
git checkout main
git pull
git merge feature/search
git push
```
**الخطوة 7: حذف الفرع**
```bash
git branch -d feature/search
git push origin --delete feature/search
```
## فحص ما قبل الدمج
```bash
# ما سيُدمج؟
git log main..feature/login --oneline
# الفرق بين الفرعين
git diff main feature/login
# هل سيكون fast-forward؟
git merge --no-commit --no-ff feature/login
git merge --abort
```
## إلغاء الدمج
**قبل الـ Commit:**
```bash
git merge --abort
```
**بعد الـ Commit:**
```bash
git reset --hard HEAD~1
```
## الدمج مع استراتيجيات
### 1. `--no-ff` — دائماً إنشاء commit
```bash
git merge --no-ff feature/login
```
**الفائدة:** حتى لو fast-forward، يُنشئ commit يوضح الدمج.
### 2. `--ff-only` — Fast-forward فقط
```bash
git merge --ff-only feature/login
```
**يفشل** إذا كان three-way مطلوباً.
### 3. `--squash` — دمج كـ commit واحد
```bash
git merge --squash feature/login
git commit -m "feat: login"
```
## حل التعارضات (Conflict)
**التعارض يحدث** عندما:
- نفس السطر تم تعديله في **فرعين**.
- Git لا يعرف أي نسخة يفوز.
**مثال:**
```bash
git checkout main
git merge feature/login
```
**النتيجة:**
```
Auto-merging login.html
CONFLICT (content): Merge conflict in login.html
Automatic merge failed; fix conflicts and then commit the result.
```
**حل التعارض:**
### 1. افتح الملف المتعارض
```html
<<<<<<< HEAD
<h1>الرئيسية</h1>
=======
<h1>تسجيل الدخول</h1>
>>>>>>> feature/login
```
**التفسير:**
- `<<<<<<< HEAD` → نسخة `main`.
- `=======` → فاصل.
- `>>>>>>> feature/login` → نسخة الفرع.
### 2. احل التعارض يدوياً
```html
<h1>الرئيسية</h1>
<h1>تسجيل الدخول</h1>
```
### 3. أضف الملف
```bash
git add login.html
```
### 4. أنشئ commit
```bash
git commit -m "merge: حل تعارض في login.html"
```
### 5. أدوات مساعدة
**VS Code:** يعرض التعارضات بشكل مرئي.
**`git mergetool`:**
```bash
git mergetool
```
## أفضل الممارسات
### 1. حدّث main قبل الإنشاء
```bash
git checkout main
git pull
git checkout -b feature/new
```
### 2. حدّث main قبل الدمج
```bash
git checkout main
git pull
git merge feature/new
```
### 3. استخدم Pull Requests
**لا تدمج مباشرة — افتح PR.**
### 4. اختبر قبل الدمج
```bash
npm test
npm run build
```
### 5. فرع = ميزة = PR
**لا تجمع ميزات متعددة في فرع واحد.**
### 6. احذف الفروع المدمجة
```bash
git branch -d feature/done
```
## تمارين عملية
### تمرين 1: Fast-forward Merge
أنشئ فرعاً وادمجه (fast-forward).
**الحل:**
```bash
git checkout -b feature/a
echo "a" > a.txt
git add . && git commit -m "feat: a"
git checkout main
git merge feature/a
```
### تمرين 2: Three-way Merge
أنشئ تعارضاً بسيطاً وحله.
**الحل:**
```bash
# على main
echo "main" > file.txt && git add . && git commit -m "main"
# على فرع
git checkout -b feature/b
echo "feature" > file.txt && git add . && git commit -m "feature"
# ارجع لـ main وعدّل
git checkout main
echo "main2" > file.txt && git add . && git commit -m "main2"
# ادمج
git merge feature/b
# حل التعارض يدوياً
```
### تمرين 3: Squash Merge
ادمج فرعاً بـ `--squash`.
**الحل:**
```bash
git checkout main
git merge --squash feature/b
git commit -m "feat: b"
```
### تمرين 4: Rebase
أعد ترتيب فرع فوق main.
**الحل:**
```bash
git checkout feature/b
git rebase main
```
### تمرين 5: إلغاء الدمج
ادمج ثم ألغِ.
**الحل:**
```bash
git merge feature/b
git reset --hard HEAD~1
```
### تمرين 6: --no-ff
ادمج مع `--no-ff`.
**الحل:**
```bash
git merge --no-ff feature/b
```
### تمرين 7: عرض الفرق
اعرض الفرق قبل الدمج.
**الحل:**
```bash
git diff main feature/b
```
### تمرين 8: مشروع كامل
أنشئ 3 فروع، ادمجها معاً.
**الحل:**
```bash
# فرع 1
git checkout -b feature/a
git commit -m "feat: a"
git checkout main
git merge feature/a
# فرع 2
git checkout -b feature/b
git commit -m "feat: b"
git checkout main
git merge feature/b
# فرع 3
git checkout -b feature/c
git commit -m "feat: c"
git checkout main
git merge feature/c
```
## حل المشاكل الشائعة
### 🔴 المشكلة 1: `CONFLICT`
**الحل:** افتح الملف، حل التعارض، `git add`، `git commit`.
### 🔴 المشكلة 2: `Merge aborted`
**الحل:**
```bash
git merge --abort
```
### 🔴 المشكلة 3: دمج خاطئ
**الحل:**
```bash
git reset --hard HEAD~1
```
### 🔴 المشكلة 4: `rebase` فشل
**الحل:**
```bash
git rebase --abort
```
### 🔴 المشكلة 5: نسيت حل التعارض
**الحل:**
```bash
git status # يعرض الملفات المتعارضة
```
## جدول أوامر الدمج
<table>
<thead>
<tr>
<th>الأمر</th>
<th>الوظيفة</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>git merge feature</code></td>
<td>دمج</td>
</tr>
<tr>
<td><code>git merge --no-ff feature</code></td>
<td>دائماً commit</td>
</tr>
<tr>
<td><code>git merge --squash feature</code></td>
<td>دمج كـ commit واحد</td>
</tr>
<tr>
<td><code>git merge --abort</code></td>
<td>إلغاء</td>
</tr>
<tr>
<td><code>git rebase main</code></td>
<td>إعادة ترتيب</td>
</tr>
<tr>
<td><code>git rebase --abort</code></td>
<td>إلغاء rebase</td>
</tr>
<tr>
<td><code>git diff main feature</code></td>
<td>الفرق</td>
</tr>
<tr>
<td><code>git log main..feature</code></td>
<td>commits الفرع</td>
</tr>
</tbody>
</table>
## قائمة تحقق نهائية
<table>
<thead>
<tr>
<th>المهمة</th>
<th>الحالة</th>
</tr>
</thead>
<tbody>
<tr>
<td>Fast-forward Merge</td>
<td>⬜</td>
</tr>
<tr>
<td>Three-way Merge</td>
<td>⬜</td>
</tr>
<tr>
<td>Squash Merge</td>
<td>⬜</td>
</tr>
<tr>
<td>Rebase</td>
<td>⬜</td>
</tr>
<tr>
<td>حل التعارضات</td>
<td>⬜</td>
</tr>
<tr>
<td>إلغاء الدمج</td>
<td>⬜</td>
</tr>
<tr>
<td>حل التمارين الثمانية</td>
<td>⬜</td>
</tr>
</tbody>
</table>
## ماذا بعد هذا المقال؟
الآن بعد أن أتقنت الدمج، أنت جاهز للمقال التالي:
1. **GitHub** — مقدمة في المنصة.
2. **Pull Requests** — العمل الجماعي.
3. **حل التعارضات المتقدم**.
## الخلاصة
في هذا المقال، تعلمت:
- ✅ ما هو الدمج.
- ✅ أنواع الدمج (Fast-forward، Three-way).
- ✅ Squash و Rebase.
- ✅ حل التعارضات.
- ✅ أفضل الممارسات.
- ✅ حل 8 تمارين عملية.
**تذكر:** الدمج هو **قلب العمل الجماعي** في Git. أتقنه جيداً.