পুল রিকোয়েস্ট ও কোড রিভিউ ওয়ার্কফ্লো
এই পাঠে যা শিখবেন
- Pull Request আসলে কী, এবং কেন এটি raw git কমান্ড নয় বরং একটি প্ল্যাটফর্ম ফিচার
- স্ট্যান্ডার্ড PR ওয়ার্কফ্লোর পাঁচটি ধাপ, M7-M9 এর এখন-পর্যন্ত শেখা সবকিছুকে একসাথে যুক্ত করে
- PR কেন কোড রিভিউ ও CI-এর জন্য একটি গুরুত্বপূর্ণ চেকপয়েন্ট তৈরি করে
- Python দিয়ে একটি বাস্তবসম্মত approval-gate (
can_merge()) লজিক লেখা ও ধাপে ধাপে যাচাই করা
১ · Pull Request কী
Pull Request (PR)Pull Requestএকটি ব্রাঞ্চের পরিবর্তন আরেকটিতে merge করার জন্য একটি হোস্টিং প্ল্যাটফর্মে খোলা রিকোয়েস্ট — কিছু প্ল্যাটফর্মে "Merge Request" নামেও পরিচিত। হলো একটি ব্রাঞ্চ (প্রায়ই একটি feature ব্রাঞ্চ, M8-এর ব্রাঞ্চিং উপাদানের সরাসরি প্রয়োগ) আরেকটিতে (প্রায়ই main/শেয়ার্ড ব্রাঞ্চ) merge করার একটি রিকোয়েস্ট, যা GitHub/GitLab-এর মতো একটি হোস্টিং প্ল্যাটফর্মে খোলা হয়। একটি গুরুত্বপূর্ণ বিষয় স্পষ্ট করা দরকার: PR নিজে একটি raw git কমান্ড নয় — এটি git-এর প্রকৃত ব্রাঞ্চ/মার্জ মেকানিক্সের ওপর প্ল্যাটফর্মের তৈরি করা একটি ফিচার।
২ · স্ট্যান্ডার্ড PR ওয়ার্কফ্লো
M7-M9-এ এখন পর্যন্ত শেখা প্রায় সবকিছুকে এখানে একসাথে যুক্ত করা যাক:
৩ · কেন PR গুরুত্বপূর্ণ
PR একটি প্রাকৃতিক চেকপয়েন্ট তৈরি করে কোড রিভিউর জন্য (M11/L52-এ বিস্তারিত দেখব) এবং
স্বয়ংক্রিয় CI চেক (M12/L53-এ দেখব) চালানোর জন্য — শেয়ার্ড ব্রাঞ্চে পৌঁছানোর আগেই। এটি
একটি গুরুত্বপূর্ণ কোয়ালিটি-গেট যা সরাসরি main-এ git push করাতে থাকে না।
নিচের কোড সেলে একটি বাস্তবসম্মত PullRequest ক্লাস লেখা হয়েছে, যার
can_merge() মেথড দুটো শর্ত একসাথে যাচাই করে — অন্তত একটি approval, এবং কোনো outstanding
changes-requested রিভিউ নেই। লক্ষ্য করুন প্রতিটি রিভিউয়ারের সর্বশেষ সিদ্ধান্তই টিকে
থাকে — কেউ প্রথমে changes requested দিয়ে পরে approve করলে তার আগের সিদ্ধান্ত আর গণনায় আসে না।
# PullRequest ও approval-gate লজিক -- এটি সাধারণ, real Python OOP (git-এর সিমুলেশন নয়,
# কারণ PR নিজেই কোনো git অভ্যন্তরীণ অবজেক্ট নয়, বরং একটি প্ল্যাটফর্ম-লেভেল ধারণা)।
class PullRequest:
def __init__(self, source_branch, target_branch):
self.source_branch = source_branch
self.target_branch = target_branch
self.status = "open"
self.reviews = [] # [{"reviewer":..., "decision":..., "comment":...}]
def add_review(self, reviewer, decision, comment):
self.reviews.append({"reviewer": reviewer, "decision": decision, "comment": comment})
def can_merge(self):
latest_by_reviewer = {}
for r in self.reviews:
latest_by_reviewer[r["reviewer"]] = r["decision"] # শেষেরটাই টিকে থাকে
has_approval = "approved" in latest_by_reviewer.values()
has_outstanding_changes_requested = "changes_requested" in latest_by_reviewer.values()
return has_approval and not has_outstanding_changes_requested
def merge(self):
if not self.can_merge():
raise ValueError("can_merge() False -- merge করা যাবে না")
self.status = "merged"
pr = PullRequest("feature/login-page", "main")
pr.add_review("অনিতা", "changes_requested", "পাসওয়ার্ড ভ্যালিডেশন মিসিং")
print("অনিতা 'changes_requested' দেওয়ার পর can_merge():", pr.can_merge())
pr.add_review("রাহুল", "approved", "বাকি সব ঠিক আছে")
print("রাহুল 'approved' দেওয়ার পরও can_merge():", pr.can_merge(),
"(অনিতার changes_requested এখনো outstanding)")
pr.add_review("অনিতা", "approved", "ভ্যালিডেশন যোগ হয়েছে, এখন ঠিক আছে")
print("অনিতা নিজের রিভিউ বদলে 'approved' দেওয়ার পর can_merge():", pr.can_merge())
pr.merge()
print("\nPR status:", pr.status)
print("\nমোট রিভিউ এন্ট্রি:", len(pr.reviews))
latest = {}
for r in pr.reviews:
latest[r["reviewer"]] = r["decision"]
print("প্রতিটি রিভিউয়ারের সর্বশেষ সিদ্ধান্ত:", latest)
can_merge() False। ধাপ ২: রাহুল approve করলেন, এখন একটি approval আছে — কিন্তু অনিতার
changes-requested এখনো outstanding, তাই এখনো can_merge() False (দুটো শর্তই একসাথে লাগে)।
ধাপ ৩: অনিতা নিজের রিভিউ বদলে approve করলেন — এখন কোনো outstanding changes-requested নেই এবং অন্তত
একটি approval আছে, তাই can_merge() True হয়ে merge সম্ভব হয়।
PR হলো git-এর ব্রাঞ্চ/মার্জ মেকানিক্সের ওপর তৈরি একটি প্ল্যাটফর্ম ফিচার, যা কোড main-এ পৌঁছানোর আগে রিভিউ ও যাচাইয়ের একটি প্রাকৃতিক চেকপয়েন্ট তৈরি করে। একটি ভালো approval-gate শুধু "কেউ approve করেছে কিনা" দেখে না — এটি নিশ্চিত করে কোনো outstanding আপত্তিও নেই, এবং প্রতিটি রিভিউয়ারের সর্বশেষ সিদ্ধান্তকেই গুরুত্ব দেয়। পরের পাঠে (L41) আমরা দেখব কীভাবে Git Flow-এর মতো একটি সংগঠিত ব্রাঞ্চিং স্ট্র্যাটেজি PR-ভিত্তিক ইন্টিগ্রেশনের সাথে মিলিয়ে পুরো একটি রিলিজ-প্রক্রিয়া গঠন করে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ PR কি git-এর নিজস্ব কমান্ড, নাকি অন্য কিছু? এটি স্পষ্ট করে ব্যাখ্যা করুন।
PR git-এর নিজস্ব কমান্ড নয় — এটি একটি প্ল্যাটফর্ম (GitHub, GitLab, ইত্যাদি) ফিচার, যা git-এর
প্রকৃত ব্রাঞ্চ ও মার্জ মেকানিক্সের ওপর তৈরি। যখন একটি PR merge করা হয়, প্ল্যাটফর্ম তার নিজের
"merge" বাটনের মাধ্যমে ভেতরে ভেতরে একটি প্রকৃত git merge (অথবা squash-merge) চালায় —
কিন্তু PR-এর রিভিউ/স্ট্যাটাস ট্র্যাকিং সিস্টেমটি নিজে raw git-এর অংশ নয়।
প্র ০২
উপরের কোড সেলে রাহুলের approval থাকা সত্ত্বেও দ্বিতীয় ধাপে can_merge() False কেন হলো?
কারণ can_merge()-এর নিয়ম হলো "AND" লজিক — অন্তত একটি approval এবং
কোনো outstanding changes-requested নেই। রাহুলের approval প্রথম শর্তটি পূরণ করলেও, অনিতার
changes-requested রিভিউ তখনও তার সর্বশেষ (এবং একমাত্র) সিদ্ধান্ত ছিল — অর্থাৎ দ্বিতীয় শর্তটি ব্যর্থ
হয়। শুধু কোনো একজন approve করলেই যথেষ্ট নয়, যদি অন্য কারো আপত্তি এখনো সমাধান না হয়ে থাকে।
প্র ০৩
সরাসরি git push দিয়ে main-এ কোড পাঠানো আর PR-এর মাধ্যমে merge করার মধ্যে গুণগত পার্থক্য কী?
সরাসরি push-এ কোনো বাধ্যতামূলক চেকপয়েন্ট নেই — কোড সাথে সাথে শেয়ার্ড ব্রাঞ্চে চলে যায়। PR
workflow-এ কোড প্রথমে একটি "প্রস্তাব" অবস্থায় থাকে — অন্য টিম সদস্যরা রিভিউ করতে পারে, স্বয়ংক্রিয়
CI চেক চলতে পারে, এবং merge শুধুমাত্র can_merge()-এর মতো একটি স্পষ্ট নিয়ম পূরণ হলেই
ঘটে। এটি ভুল/নিম্নমানের কোড শেয়ার্ড ব্রাঞ্চে পৌঁছানোর সম্ভাবনা উল্লেখযোগ্যভাবে কমায়।
অনুশীলন
-
চিন্তা করুন: যদি একটি PR-এ তিনজন রিভিউয়ার থাকে, এবং দুজন approve করেন কিন্তু তৃতীয়জন কখনো কোনো রিভিউ-ই না দেন (নীরব থাকেন), তাহলে
can_merge()কী ফেরত দেবে? এটি কি ন্যায্য আচরণ বলে মনে হয়?can_merge()True ফেরত দেবে, কারণ নীরব থাকা কোনো"changes_requested"এন্ট্রি তৈরি করে না — শুধু outstanding আপত্তি থাকলেই merge আটকায়, কারো রিভিউ না-দেওয়া নয়। এটি একটি বাস্তবসম্মত ডিজাইন সিদ্ধান্ত: টিমকে একজন অনুপস্থিত/ধীরগতির রিভিউয়ারের জন্য অসীম সময় অপেক্ষা করতে বাধ্য করা হয় না, যদিও বাস্তব প্ল্যাটফর্মগুলোতে প্রায়ই "প্রয়োজনীয় রিভিউয়ার" নির্দিষ্ট করার আলাদা সেটিং থাকে। -
পরীক্ষা করুন: একটি নতুন
PullRequest("feature/x", "main")তৈরি করুন এবং শুরুতেইpr.merge()কল করে দেখুন কী হয় — তারপর ব্যাখ্যা করুন কেন।এটি একটি
ValueErrorরেইজ করবে ("can_merge() False -- merge করা যাবে না"), কারণ কোনো রিভিউ এখনো যোগ করা হয়নি —latest_by_reviewerখালি, তাইhas_approvalFalse, এবংcan_merge()False। এটি নিশ্চিত করে একটি PR কখনোই কোনো রিভিউ ছাড়া merge হতে পারবে না।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৮টি পাঠ পরবর্তী পাঠ — Git Flow ব্রাঞ্চিং স্ট্র্যাটেজি, যেখানে feature ব্রাঞ্চ PR-এর মাধ্যমে develop-এ ইন্টিগ্রেট হয়।
- কোড রিভিউ বেস্ট প্র্যাক্টিস L52 এই পাঠে যে "রিভিউ" ধাপটি সংক্ষেপে দেখানো হলো, সেটি কীভাবে ভালোভাবে করা যায় — বিস্তারিত সেই পাঠে।