Stacked PRs को वास्तविक कार्यप्रवाह में लागू करने का तरीका, जब विशाल PR के कारण कोड रिव्यू एक सप्ताह तक पिछड़ जाते हैं
AI टूल अपनाने के बाद कोड जनरेशन की गति बहुत तेज हो गई है। हालाँकि, रिव्यू की गति उस रफ़्तार से मेल नहीं खा पा रही है। 2024 की DORA (DevOps Research and Assessment) रिपोर्ट के अनुसार, उच्च AI अपनाने वाली टीमों में PR का आकार औसतन 154% बढ़ गया है और रिव्यू का समय 91% बढ़ गया है। परिणामस्वरूप, डिप्लॉयमेंट साइकिल वास्तव में धीमी हो गई है। जब कोई एक ही बार में 1,000 से अधिक लाइनों के कोड को रिव्यू करने के लिए दे देता है, तो किसी की भी आँखें थक जाती हैं। इस अव्यवस्था को समाप्त करने के लिए, हमें स्टैक्ड PRs (Stacked PRs) चेन संरचना पर स्विच करने की आवश्यकता है, जहाँ कोड को परतों में स्टैक किया जाता है।
1,000-लाइन के चंक को 3 शाखाओं (Branches) में विभाजित करना
यदि आप बिना सोचे-समझे कोड को काटते हैं, तो कंपाइल विफल हो जाएगा या डिपेंडेंसी टूट जाएगी। आपको एक स्पष्ट मानक की आवश्यकता है। एक ही PR को 200 से कम परिवर्तित लाइनों और 10 से कम संशोधित फ़ाइलों तक सीमित रखें ताकि रिव्यूअर्स इसे 15 मिनट में पूरा कर सकें। एक बड़े फ़ंक्शन को अधिकतम 3 चाइल्ड ब्रांच चेन में विभाजित किया गया है।
- Layer 1: DB स्कीमा, एंटिटी (Entity), DTO
- Layer 2: डोमेन लॉजिक, सर्विस इम्प्लीमेंटेशन
- Layer 3: कंट्रोलर, API एंडपॉइंट
इस क्रम का कड़ाई से पालन करें। शाखा का नाम भी feature/<फ़ंक्शन का नाम>/stack-<चरण>-<विवरण> प्रारूप में तय किया जाना चाहिए। पहले से उलझे हुए 1,000-लाइन के ब्रांच (legacy-giant-branch) को चेन में विघटित करने की प्रक्रिया सरल है।
सबसे पहले, main ब्रांच को अपडेट करें और मूल का बैकअप लें।
`bash
git checkout main
git pull origin main
git checkout legacy-giant-branch
git branch backup/legacy-giant-branch
`
अगला, main से Layer 1 ब्रांच को बाहर निकालें और केवल स्कीमा से संबंधित कमिट को चेरी-पिक करें।
`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
`
टूल का चयन भी एक विचारणीय बिंदु है। शुद्ध Git CLI में कोई लागत नहीं आती है लेकिन इसमें बहुत अधिक मैनुअल काम की आवश्यकता होती है, जबकि Graphite जैसे समर्पित टूल सुविधाजनक हैं लेकिन लागत और बुनियादी ढांचा निर्भरता पैदा करते हैं।
| मूल्यांकन आइटम |
Pure Git CLI |
GitHub CLI (gh stack) |
Graphite / External Tools |
| डिपेंडेंसी ट्रैकिंग |
मैनुअल ब्रांच बेस सेटिंग |
लोकल .git और GitHub metadata |
अलग रिमोट इंजन और Local DB |
| रीबेस ऑटोमेशन |
व्यक्तिगत शाखा का मैनुअल काम |
gh stack rebase कमांड निष्पादित करें |
कमिट बदलने पर लोअर चेन का स्वचालित प्रसंस्करण |
| लर्निंग कर्व |
उच्च (Git सिद्धांतों को समझने की आवश्यकता है) |
कम (CLI एक्सटेंशन स्थापित करें) |
मध्यम (अलग समर्पित UI के अनुकूल होना आवश्यक है) |
| परिचालन स्थिरता |
100% मानक Git संगत |
सार्वजनिक पूर्वावलोकन स्थिति |
बहुत उच्च |
जब पैरेंट PR संशोधित किया जाता है तो रीबेस संघर्षों को रोकना
जब आप स्टैक्ड PR का उपयोग करते हैं, तो वह पल सबसे दर्दनाक होता है जब पैरेंट PR संशोधन का अनुरोध किया जाता है। ऐसा इसलिए है क्योंकि कमिट हैश बदल जाता है और नीचे की सभी चाइल्ड ब्रांच टूट जाती हैं। यदि आप केवल 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
`
यदि आप हर बार इस कार्य को मैन्युअल रूप से करते हैं, तो मनुष्य निश्चित रूप से गलती करेगा। क्रमिक रीबेस को स्वचालित करने के लिए एक शेल स्क्रिप्ट बनाएं।
`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"BRANCH"
OLD_BASE=(gitmerge−base"CURRENT_PARENT" "BRANCH"2>/dev/null∣∣echo"")if[−n"OLD_BASE" ]; then
git rebase --onto "CURRENTPARENT""OLD_BASE" "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 गुना चलता है। सभी PRs पर भारी E2E परीक्षण चलाने की कोई आवश्यकता नहीं है। निचली परत पर केवल ठोस यूनिट परीक्षण चलाएं, और GitHub Actions वातावरण को इस तरह से कॉन्फ़िगर करें कि संपूर्ण एकीकृत सत्यापन केवल सबसे ऊपरी PR पर किया जाए।
.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
`
संगठन स्तर पर शाखा सुरक्षा नियम सेटिंग्स को कॉन्फ़िगर करना भी अनिवार्य है।
- स्वीकृत स्टैक PRs को क्रमिक रूप से मर्ज करने के लिए मजबूर करने के लिए GitHub Merge Queue फ़ंक्शन को चालू करें।
- कचरा मर्ज कमिट को रोकने के लिए Repository Rulesets में 'Require Linear History' चालू करें।
- निचली PR के मर्ज न होने की स्थिति में ऊपरी PR के मुख्य (main) में पहले मिलने वाली दुर्घटना को रोकने के लिए 'Require Status Checks to Pass Before Merging' का उपयोग करें।
टीम रिव्यू संस्कृति और Squash Merge के बाद UI टूटने से निपटना
स्टैक किए गए PRs को ठीक से चलाने के लिए, रिव्यूअर्स को पूरी तस्वीर देखने में सक्षम होना चाहिए। .github/PULL_REQUEST_TEMPLATE.md में स्टैक मैप निर्दिष्ट करें।
`markdown
Stack Overview
यह PR Order Refactoring Stack चेन का हिस्सा है।
- #101 - feature/order-refactor/stack-1-schema (DB Migration)
- [Current PR] #102 - feature/order-refactor/stack-2-service (Business Logic)
- #103 - feature/order-refactor/stack-3-controller (API Controller)
Current Layer Scope
- OrderService के भीतर भुगतान स्थिति परिवर्तन तर्क का कार्यान्वयन
- डोमेन इवेंट जारी करने की प्रक्रिया और रिपॉजिटरी एकीकरण परीक्षण जोड़ा गया
Dependency Status
- Base PR: #101 (Must be merged first)
`
निचली PR #101 के Squash Merge के माध्यम से main में प्रवेश करने के बाद, चाइल्ड PR #102 का GitHub UI Diff अचानक फट जाता है। यह एक ऐसी घटना है जहाँ पहले से मर्ज किए गए #101 का कोड भी चाइल्ड PR परिवर्तनों के रूप में पकड़ा जाता है। यह इसलिए होता है क्योंकि Git Commit Graph पर Squash कमिट का SHA और पैरेंट कमिट का SHA बदल गया है। घबराएं नहीं और केवल चाइल्ड ब्रांच कमिट को नीचे दिए गए क्रम में 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
`
विशाल 1,000-लाइन PR को विभाजित करने का कार्य केवल Git तकनीक से निपटने की समस्या नहीं है। यह एक इंजीनियरिंग कार्य के करीब है जो टीम की कोड समीक्षा पद्धति और पूरे डिप्लॉयमेंट चेन को बड़े पैमाने पर व्यवस्थित करता है। यदि आप किसी गंदे लीगेसी ब्रांच का सामना करते हैं, तो पहले एक बैकअप बनाएं और इसे 3-चरणीय परत में काट लें। न केवल रिव्यूअर की थकान कम होगी, बल्कि आप स्वयं भी कोड को अधिक स्पष्ट रूप से नियंत्रित करने में सक्षम होंगे।