TuBrief
Subscribed Channels
Videos
Community

دليل تطبيق ممارسات PRs المتراكمة (Stacked PRs) لحل مشكلة تأخر المراجعات بسبب طلبات الدمج العملاقة

TuBrief Editorial
August 7, 2026
0
Computing/Software

Written with AI assistance from the source video. The video is the authority.

العربية한국어EnglishEspañol中文हिन्दीDeutschFrançaisPortuguêsРусскийBahasa Indonesia日本語

Related Video

أكبر إطلاق لـ غيت هاب (GitHub) منذ سنوات. طلبات السحب المتراكمة (Stacked PRs).5:17

أكبر إطلاق لـ غيت هاب (GitHub) منذ سنوات. طلبات السحب المتراكمة (Stacked PRs).

Better Stack

More from the community

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

September 13, 2026

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

September 13, 2026

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

September 13, 2026

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

September 13, 2026

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

September 12, 2026

Apple Won the AI Race

September 12, 2026

Comments (0)

Log in to leave a comment

No posts yet

© 2026 . All rights reserved.

TuBrief
Subscribed Channels
Videos
Community
Log in

دليل تطبيق ممارسات PRs المتراكمة (Stacked PRs) لحل مشكلة تأخر المراجعات بسبب طلبات الدمج العملاقة

مع إدخال أدوات الذكاء الاصطناعي، أصبحت سرعة توليد الكود سريعة بشكل مذهل. ومع ذلك، لا تستطيع سرعة المراجعة مواكبة ذلك. وفقاً لتقرير DORA (أبحاث وتقييم DevOps) لعام 2024، زاد متوسط حجم طلبات الدمج (PRs) بنسبة 154% في الفرق ذات معدل تبني الذكاء الاصطناعي العالي، وزاد وقت المراجعة بنسبة 91%. ونتيجة لذلك، أصبحت دورة النشر أبطأ في الواقع. عندما يُطلب من أي شخص مراجعة كود يتجاوز 1,000 سطر دفعة واحدة، فإن عينيه ستتعبان بالتأكيد. لإنهاء هذه الفوضى، يجب الانتقال إلى هيكل سلسلة PRs المتراكمة (Stacked PRs) حيث يتم تكديس الكود طبقة فوق طبقة.

تقسيم كتلة من 1,000 سطر إلى 3 فروع

إذا قمت بقطع الكود بشكل عشوائي، فسف يفشل الترجمة أو تنكسر التبعيات. أنت بحاجة إلى معيار واضح. اترك طلب الدمج الفردي يقتصر على 200 سطر أو أقل من كود التغيير وأقل من 10 ملفات معدلة، بحيث يمكن للمراجع إنهاء عمله في غضون 15 دقائق. يتم تقسيم الميزة الضخمة الواحدة إلى حد أقصى من 3 سلاسل فروع فرعية.

  • Layer 1: مخطط قاعدة البيانات، كيان (Entity)، DTO
  • Layer 2: منطق المجال (Domain logic)، كائنات الخدمة (Service implementations)
  • Layer 3: وحدة التحكم (Controller)، نقاط نهاية API

اتبع هذا الترتيب بصرامة. قم بتثبيت أسماء الفروع على شكل feature/<اسم-الميزة>/stack-<المرحلة>-<الوصف>. عملية تفكيك فرع legacy-giant-branch المكون من 1,000 سطر والذي أصبح متشابكًا بالفعل هي عملية بسيطة.

أولاً، قم تحديث فرع main ونسخ النسخة الأصلية احتياطيًا.

`bash
git checkout main
git pull origin main
git checkout legacy-giant-branch
git branch backup/legacy-giant-branch

`

بعد ذلك، قم بإنشاء فرع Layer 1 من main واجلب التغييرات (Cherry-pick) الخاصة بالمخطط فقط.

`bash
git checkout -b feature/order-refactor/stack-1-schema main
git cherry-pick
git push origin feature/order-refactor/stack-1-schema

`

الآن، باستخدام Layer 1 كأب، يمكنك توسيع Layer 2 و Layer 3 بشكل تسلسلي.

`bash
git checkout -b feature/order-refactor/stack-2-service feature/order-refactor/stack-1-schema
git cherry-pick
git push origin feature/order-refactor/stack-2-service

git checkout -b feature/order-refactor/stack-3-controller feature/order-refactor/stack-2-service
git cherry-pick
git push origin feature/order-refactor/stack-3-controller

`

اختيار الأداة هو أيضًا عنصر مقلق. أداة Pure Git CLI لا تكلف مالاً ولكنها تتطلب الكثير من العمل اليدوي، بينما الأدوات المخصصة مثل Graphite مريحة ولكنها تخلق تبعيات تكلفة وبنية تحتية.

عنصر التقييم Pure Git CLI GitHub CLI (gh stack) Graphite / External Tools
تتبع التبعيات تعيين فرع الأساس يدويًا .git المحلي وبيانات GitHub التعريفية محرك عن بعد منفصل وقاعدة بيانات محلية
إعادة الأساس التلقائية عمل يدوي لكل فرع على حدة تشغيل أمر gh stack rebase المعالجة التلقائية للسلسلة التحتية عند تغيير الالتزام
منحنى التعلم مرتفع (يتطلب فهم مبادئ Git) منخفض (تثبيت امتداد CLI) متوسط (يتطلب التكيف مع واجهة مخصصة منفصلة)
استقرار التشغيل متوافق بنسبة 100% مع Git القياسي في حالة معاينة عامة مرتفع للغاية

منع تعارضات إعادة الأساس عند تعديل طلب الدمج الأب

عند استخدام PRs المتراكمة، فإن اللحظة الأكثر إيلامًا هي عندما يأتي طلب لتعديل طلب الدمج الأب. يتسبب ذلك في تغير الالتزام (Commit Hash) وكسر جميع الفروع الابتدائية التحتية المعلقة. إذا قمت بتشغيل git rebase فقط، فسيتم إدخال الالتزامات مرتين. يجب عليك تحديد النطاق المراد قطعه باستخدام صيغة git rebase --onto.

إذا تم تعديل Layer 1، فانتقل إلى Layer 2 وأعد وضع ما بين نقطة التزام Layer 1 قبل التعديل وحتى HEAD الحالي فوق نقطة النهاية للطبقة Layer 1 الجديدة.

`bash
git checkout feature/order-refactor/stack-2-service
git rebase --onto feature/order-refactor/stack-1-schema feature/order-refactor/stack-2-service
git push --force-with-lease

`

انقل Layer 3 أيضًا بنفس الطريقة فوق Layer 2 الجديد.

`bash
git checkout feature/order-refactor/stack-3-controller
git rebase --onto feature/order-refactor/stack-2-service feature/order-refactor/stack-3-controller
git push --force-with-lease

`

إذا قمت بهذه العملية يدويًا في كل مرة، فسوف يخطئ البشر بالتأكيد. أنشئ برنامجلصياغة الأوامر (Shell script) لأتمتة إعادة الأساس التسلسلي.

`bash
#!/usr/bin/env bash
set -e

STACK_BRANCHES=(
"feature/order-refactor/stack-1-schema"
"feature/order-refactor/stack-2-service"
"feature/order-refactor/stack-3-controller"
)
TARGET_BASE="main"

git fetch origin
CURRENT_PARENT="$TARGET_BASE"

for BRANCH in "STACKBRANCHES[@]";dogitcheckout"{STACK_BRANCHES[@]}"; do git checkout "STACKB​RANCHES[@]";dogitcheckout"BRANCH"
OLD_BASE=(gitmerge−base"(git merge-base "(gitmerge−base"CURRENT_PARENT" "BRANCH"2>/dev/null∣∣echo"")if[−n"BRANCH" 2>/dev/null || echo "") if [ -n "BRANCH"2>/dev/null∣∣echo"")if[−n"OLD_BASE" ]; then
git rebase --onto "CURRENTPARENT""CURRENT_PARENT" "CURRENTP​ARENT""OLD_BASE" "BRANCH"∣∣exit1figitpush−−force−with−leaseorigin"BRANCH" || exit 1 fi git push --force-with-lease origin "BRANCH"∣∣exit1figitpush−−force−with−leaseorigin"BRANCH"
CURRENT_PARENT="$BRANCH"
done

`

لا تنس تشغيل ميزة تسجيل تاريخ حل التعارضات في إعدادات Git. سيقوم بتجاوز التعارضات المتكررة تلقائيًا.

`bash
git config --global rerere.enabled true
git config --global rerere.autoupdate true
git config --global rebase.autoStash true
git config --global rebase.updateRefs true

`

منع إهدار تكلفة تشغيل CI وتشابك ترتيب الدمج

إذا قمت بتقسيم PR إلى 3 أجزاء، تنشأ مشكلة تشغيل مشغلات CI أيضًا 3 مرات. ليس من الضروري تشغيل اختبارات E2E الثقيلة في كل طلب دمج. قم بتكوين بيئة GitHub Actions بحيث يتم تشغيل اختبارات الوحدة الصلبة فقط في الطبقات السفلى، ويتم إجراء التحقق المتكامل الشامل في طلب الدمج العلوي فقط.

أضف شرط التحقق من مكان التراكم إلى ملف .github/workflows/ci.yml.

`yaml
name: Stack-Aware CI Pipeline

on:
pull_request:
branches: [ main ]

jobs:
fast-lint-and-unit-test:
name: Fast Validation (All Layers)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Linter & Unit Tests
run: |
npm ci
npm run test:unit

heavy-integration-test:
name: Full E2E Test (Top Layer Only)
runs-on: ubuntu-latest
if: |
github.event.pull_request.stack == null ||
github.event.pull_request.stack.position == github.event.pull_request.stack.size
steps:
- uses: actions/checkout@v4
- name: Run Heavy Integration & E2E Tests
run: |
npm ci
npm run test:e2e

`

كما أن إعداد قواعد حماية الفروع على مستوى المؤسسة أمر ضروري أيضًا.

  1. قم بتشغيل ميزة GitHub Merge Queue لفرض دمج طلبات التراكم المعتمدة بالترتيب.
  2. قم بتشغيل خيار 'Require Linear History' في Repository Rulesets لمنع التزام الدمج المتبقي (Merge Commit).
  3. استخدم خيار 'Require Status Checks to Pass Before Merging' لمنع وقوع حادث يختلط فيه طلب الدمج العلوي بـ main أولاً بينما لم يتم دمج طلب الدمج السفلي بعد.

التعامل مع ثقافة مراجعة الفريق وانكسار واجهة المستخدم بعد الدمج من نوع Squash

لكي تعمل طلبات الدمج المتراكمة بشكل صحيح، يجب أن يتمكن المراجع من رؤية الصورة بأكملها. حدد خريطة التراكم في ملف .github/PULL_REQUEST_TEMPLATE.md.

`markdown
Stack Overview
هذا الـ PR هو جزء من سلسلة Order Refactoring Stack.

  1. #101 - feature/order-refactor/stack-1-schema (DB Migration)
  2. [Current PR] #102 - feature/order-refactor/stack-2-service (Business Logic)
  3. #103 - feature/order-refactor/stack-3-controller (API Controller)

Current Layer Scope

  • تطبيق منطق تغيير حالة الدفع داخل OrderService
  • معالجة إصدار حدث المجال وإضافة اختبار ربط المستودع

Dependency Status

  • Base PR: #101 (Must be merged first)

`

بعد أن يتم دمج طلب الدمج السفلي #101 في main عبر Squash Merge، ينفجر Diff واجهة مستخدم GitHub للفرع الفرعي #102 فجأة. إنها ظاهرة يتم فيها التقاط حتى كود #101 الذي تم دمج مسبقًا كتغييرات لطلب الدمج الفرعي. يحدث هذا لأن SHA لالتزام Squash وSHA للالتزام الأب قد اختلفا على رسم بياني التزام Git. لا تقلق، فقط قم برفع التزامات الفرع الفرعي وحدها فوق main بالترتيب التالي.

`bash
git log --graph --oneline
git checkout feature/order-refactor/stack-2-service
git fetch origin
git rebase --onto origin/main feature/order-refactor/stack-2-service
git push --force-with-lease origin feature/order-refactor/stack-2-service

`

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