অধ্যায় 2 · Git ও GitHub
পুল রিকোয়েস্ট, README ও আপনার প্রথম প্রকাশিত প্রজেক্ট
- পৃষ্ঠা 10 / 22
- 18 মিনিট পড়া
আসল দলে কেউ সরাসরি main-এ পুশ করে না। আপনি একটা ব্রাঞ্চে কাজ করেন, সেটা পুশ করেন, আর একটা পুল রিকোয়েস্ট (pull request, PR) খোলেন: GitHub-এর একটা পাতা, যা বলে "দয়া করে এই ব্রাঞ্চ main-এ মার্জ করুন", ঠিক কী বদলাচ্ছে দেখায়, আর সহকর্মীদের মন্তব্য করতে, পরিবর্তন চাইতে ও অনুমোদন দিতে দেয়। এতে স্বয়ংক্রিয় চেকও (টেস্ট, লিন্টার) চলে। তারপরই কেবল মার্জ হয়।
প্রতিটা বড় AI লাইব্রেরিসহ প্রায় সব সফটওয়্যার এভাবেই বানানো হয়। ওপেন সোর্সে অবদান রাখার উপায়ও এটা, আর রিভিউয়ার এভাবেই আপনার কাজ যাচাই করেন। এই পাতায় একটা ছোট সংশোধনকে শুরু থেকে শেষ পর্যন্ত নিয়ে যাবেন: ইস্যু, ব্রাঞ্চ, ভালো বিবরণসহ পুল রিকোয়েস্ট, রিভিউ, মার্জ আর গোছানো। পথে এমন একটা README লিখবেন যা মানুষ সত্যিই কাজে লাগাতে পারে, এবং প্রজেক্টটা ঠিকভাবে প্রকাশ করবেন।
যা শিখবেন
- কোন বিষয়গুলো একটা README-কে কাজের করে, আর AI প্রজেক্টের জন্য একটা টেমপ্লেট।
- পুল রিকোয়েস্টের ওয়ার্কফ্লো: ইস্যু → ব্রাঞ্চ → পুশ → PR → রিভিউ → মার্জ → গোছানো।
- রিভিউয়ার যে PR বিবরণের ওপর কাজ করতে পারেন সেটা লেখা, আর
Closes #1দিয়ে ইস্যু জুড়ে দেওয়া। - GitHub-এ মার্জ কমিট বনাম স্কোয়াশ বনাম রিবেস মার্জ, এবং প্রতিটা হিস্ট্রির ওপর কী প্রভাব ফেলে।
- প্রথম প্রজেক্ট প্রকাশের চেকলিস্ট, আর
ghকমান্ড-লাইন টুলের প্রথম পরিচয়।
উদাহরণ প্রজেক্ট সাজানো
আবার সেই রিভিউ অ্যানালাইজার, যা আগে থেকেই একটা রিমোটে পুশ করা। আগের পাতার মতো ~/remotes-এর একটা বেয়ার রিপোজিটরি GitHub-এর কাজ করে, আর রাফির ক্লোন সহকর্মীর ভূমিকা নেয়। স্যাম্পল ডেটায় একটা রিভিউ আছে, যেটা অ্যানালাইজার ভুল বোঝে:
mkdir -p ~/projects/review-analyser
cd ~/projects/review-analyser
git init -q
cat > words.py <<'EOF'
POSITIVE = {"good", "great", "fast", "love"}
NEGATIVE = {"bad", "slow", "broken", "late"}
EOF
cat > analyse.py <<'EOF'
"""Label product reviews as positive, negative or neutral."""
import csv
from words import NEGATIVE, POSITIVE
def label(text):
words = text.lower().split()
score = sum(w in POSITIVE for w in words) - sum(w in NEGATIVE for w in words)
return "positive" if score > 0 else "negative" if score < 0 else "neutral"
if __name__ == "__main__":
with open("reviews.csv", newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
print(label(row["text"]), "|", row["text"])
EOF
cat > reviews.csv <<'EOF'
id,text
1,great phone and fast delivery
2,battery is bad and the box was broken
3,not good at all
EOF
printf '.env\n.venv/\n__pycache__/\n' > .gitignore
git add .
git commit -q -m "Add keyword review analyser"
git init -q --bare ~/remotes/review-analyser.git
git remote add origin ~/remotes/review-analyser.git
git push -q -u origin main
git clone -q ~/remotes/review-analyser.git ~/rafi/review-analyser
git -C ~/rafi/review-analyser config user.name "Rafi Ahmed"
git -C ~/rafi/review-analyser config user.email "rafi@example.com"
python analyse.pypositive | great phone and fast delivery
negative | battery is bad and the box was broken
positive | not good at allকাজের README
README আপনার রিপোজিটরির সামনের পাতা: GitHub ফাইলের তালিকার নিচে এটা দেখায়। একজন দর্শক প্রায় তিরিশ সেকেন্ডেই ঠিক করে ফেলেন প্রজেক্টটা কাজের কি না, আর একজন সহকর্মীর (বা ছয় মাস পরের আপনার) কোড চালাতে এটা লাগে। একটা ভালো README এই ক্রমে উত্তর দেয়:
| অংশ | কী উত্তর দেয় | AI প্রজেক্টের বিশেষ বিষয় |
|---|---|---|
| শিরোনাম + এক-দুই বাক্য | এটা কী, আর কেন আমি পরোয়া করব? | টাস্ক, ইনপুট ও আউটপুট ("labels reviews as positive/negative/neutral") |
| Quick start | কপি করা যায় এমন কমান্ডে এটা কীভাবে চালাব? | Python সংস্করণ, ইনস্টল কমান্ড, কি লাগলে cp .env.example .env |
| উদাহরণ | এটা আসলে কী করে? | একটা আসল ইনপুট ও আসল আউটপুট |
| How it works | কোডের কোথায় তাকাব? | মডেল বা পদ্ধতি, ডেটা ও মডেল ফাইল কোথা থেকে আসে |
| Limitations | কখন এটা বিশ্বাস করব না? | ভাষা, যে ডেটায় পরীক্ষা হয়নি, জানা ব্যর্থতার ঘটনা, ইভ্যালুয়েশনের ফলাফল |
| Licence | আমি কি এটা ব্যবহার করতে পারি? | কোডের লাইসেন্স, আর ডেটা বা মডেল ওয়েটের লাইসেন্স আলাদা হলে সেটাও |
README লেখা হয় Markdown-এ: শিরোনামের জন্য #, **bold**, তালিকার জন্য -, code-এর জন্য ব্যাকটিক, আর কমান্ডের জন্য তিন ব্যাকটিকের মাঝে ফেন্সড ব্লক। অ্যানালাইজারের জন্য একটা বানান:
cat > README.md <<'EOF'
# Review analyser
Labels product reviews as **positive**, **negative** or **neutral** using two
small keyword lists: a simple baseline to compare ML models and LLMs against.
## Quick start
```bash
git clone https://github.com/nadia-rahman/review-analyser.git
cd review-analyser
python analyse.py
```
Needs Python 3.12 or newer; no extra packages.
## Example
`reviews.csv` contains `1,great phone and fast delivery`, and the output is:
```text
positive | great phone and fast delivery
```
## How it works
`words.py` holds the keyword lists. `analyse.py` counts positive words minus
negative words in each review and turns the score into a label.
## Limitations
- English only; no sarcasm, emoji or context.
- The word lists are small and hand-made.
## Licence
MIT
EOF
git add README.md
git commit -q -m "Write a README with quick start, example and limitations"
git push -qছোট, সৎ আর চালানোর মতো। "Limitations" অংশটা খেয়াল করুন: যে প্রজেক্টে মডেল আছে, সেখানে কোথায় সেটা ব্যর্থ হয় তা বলা কাজটা ভালোভাবে করারই অংশ, দুর্বলতার স্বীকারোক্তি নয়।
ইস্যু দিয়ে শুরু
ওপরের ৩ নম্বর রিভিউ, "not good at all", পজিটিভ লেবেল পাচ্ছে। GitHub-এ সমস্যা ও ধারণা ট্র্যাক করা হয় ইস্যু (issue) দিয়ে: রিপোজিটরির Issues ট্যাব → New issue খুলুন, একটা পরিষ্কার শিরোনাম দিন, সমস্যাটা পুনরায় ঘটাতে যথেষ্ট বিবরণ লিখুন, আর চাইলে bug-এর মতো একটা লেবেল দিন। নাদিয়া এটা ফাইল করে:
Title: "not good" is labelled positive
Steps: python analyse.py with review 3, "not good at all".
Expected: negative
Actual: positive
The analyser ignores "not" before a keyword.GitHub এটাকে নম্বর দেয় #1। একটা রিপোজিটরিতে ইস্যু ও পুল রিকোয়েস্ট একই নম্বর-ক্রম ভাগ করে, তাই এরপর যে পুল রিকোয়েস্ট খুলব সেটা হবে #2। ইস্যুতে ফিচার রিকোয়েস্ট, প্রশ্ন আর করণীয় তালিকাও থাকে; লেবেল, অ্যাসাইনি ও মাইলস্টোন সেগুলোকে সাজায়।
পুল রিকোয়েস্টের ওয়ার্কফ্লো
issue #1 --> branch fix/1-negation --> commits --> git push -u --> open PR #2
|
main <-- merge <-- approve <-- review comments <-- push more commits১. হালনাগাদ main থেকে ব্রাঞ্চ করুন
সবসময় সর্বশেষ main থেকে শুরু করুন, যাতে আপনার ব্রাঞ্চ পুরোনো অবস্থা থেকে শুরু না হয়। ব্রাঞ্চের নাম ইস্যুর নামে রাখলে সংযোগটা স্পষ্ট থাকে:
git switch main
git pull
git switch -c fix/1-negationAlready on 'main'
Your branch is up to date with 'origin/main'.
Already up to date.
Switched to a new branch 'fix/1-negation'২. পরিবর্তন কমিট করুন
cat > analyse.py <<'EOF'
"""Label product reviews as positive, negative or neutral."""
import csv
from words import NEGATIVE, POSITIVE
def label(text):
words = text.lower().split()
score = 0
for i, w in enumerate(words):
sign = -1 if i > 0 and words[i - 1] == "not" else 1
score += sign * ((w in POSITIVE) - (w in NEGATIVE))
return "positive" if score > 0 else "negative" if score < 0 else "neutral"
if __name__ == "__main__":
with open("reviews.csv", newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
print(label(row["text"]), "|", row["text"])
EOF
python analyse.py
git commit -q -am "Flip the score of a keyword that follows not"positive | great phone and fast delivery
negative | battery is bad and the box was broken
negative | not good at all৩. ব্রাঞ্চ পুশ করুন
git push -u origin fix/1-negationTo /home/nadia/remotes/review-analyser.git
* [new branch] fix/1-negation -> fix/1-negation
branch 'fix/1-negation' set up to track 'origin/fix/1-negation'.GitHub-এ পুশের আউটপুটে remote: Create a pull request for 'fix/1-negation' on GitHub by visiting: এবং তার নিচে একটা লিংকও থাকে, আর রিপোজিটরির পাতায় একটা হলুদ ব্যানারে Compare & pull request বোতাম আসে।
৪. পুল রিকোয়েস্ট খুলুন
বোতামটা চাপুন (বা Pull requests → New pull request), তারপর:
- ব্রাঞ্চ দেখে নিন: base:
main← compare:fix/1-negation। base হলো যেখানে পরিবর্তনগুলো যাবে। - PR কী করে সেটা বলে এমন শিরোনাম লিখুন: Handle negation: "not good" is negative।
- বিবরণ লিখুন (নিচে)।
- ডানদিকে: একজন রিভিউয়ার (রাফি) চান, একটা লেবেল দিন, নিজেকে অ্যাসাইন করুন।
- Create pull request চাপুন; রিভিউয়ের জন্য এখনো তৈরি না হলে বোতামের মেনু থেকে Create draft pull request বেছে নিন।
রিভিউয়ার যার ওপর কাজ করতে পারেন এমন বিবরণ
আপনি যখন কাজ করছিলেন, রিভিউয়ার তখন আপনার মাথার ভেতরে ছিলেন না। তাকে বলুন কী বদলেছে, কেন, কীভাবে যাচাই করেছেন, আর কোন জায়গাগুলো তাঁর বিশেষভাবে দেখা দরকার:
## What
A keyword right after "not" now counts the opposite way, so
"not good" scores -1 instead of +1.
## Why
Reviews like "not good at all" were labelled positive.
Closes #1
## How I tested it
python analyse.py on reviews.csv: review 3 is now negative,
reviews 1 and 2 are unchanged.
## Notes for the reviewer
Only "not" is handled. "never", "no" and "isn't" are left for a
follow-up; is that OK?Closes #1 (বা Fixes, Resolves) ইস্যুটা জুড়ে দেয়: PR ডিফল্ট ব্রাঞ্চে মার্জ হলে GitHub নিজে থেকে #1 ইস্যু বন্ধ করে দেয়। PR ছোট এবং একটা বিষয়ে রাখুন; ৫০ লাইনের PR মন দিয়ে রিভিউ হয়, ২,০০০ লাইনেরটায় বলা হয় "looks good to me"। UI-র পরিবর্তনে স্ক্রিনশট দিন; মডেলের পরিবর্তনে আগে ও পরের ইভ্যালুয়েশনের সংখ্যা দিন।
৫. রিভিউ
রিভিউয়ার Files changed ট্যাব পড়েন, যেকোনো লাইনে ক্লিক করে মন্তব্য (বা এক ক্লিকে প্রয়োগ করা যায় এমন suggestion) রাখতে পারেন, এবং শেষ করেন Comment, Approve বা Request changes দিয়ে। ভালো রিভিউয়ার কোডটা চালিয়েও দেখেন। রাফি নিজের ক্লোন থেকে সেটাই করে: ফেচ করে, PR ব্রাঞ্চে সুইচ করে, আর PR ঠিক কী বদলাচ্ছে দেখে:
cd ~/rafi/review-analyser
git fetch -q
git switch fix/1-negation
git log --oneline origin/main..origin/fix/1-negation
git diff --stat origin/main...origin/fix/1-negation
python analyse.pySwitched to a new branch 'fix/1-negation'
branch 'fix/1-negation' set up to track 'origin/fix/1-negation'.
7a86d1d Flip the score of a keyword that follows not
analyse.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
positive | great phone and fast delivery
negative | battery is bad and the box was broken
negative | not good at allorigin/main..BRANCH সেই কমিটগুলো দেখায় যা ব্রাঞ্চে আছে কিন্তু রিমোটের main-এ নেই (PR-এর Commits ট্যাব), আর তিন ডটের git diff origin/main...BRANCH ব্রাঞ্চ শুরুর পর থেকে হওয়া পরিবর্তন দেখায় (Files changed ট্যাব)। রাফি নাদিয়া-কে বলে: "Please handle never too, it is common in reviews." সে Request changes চাপে।
৬. পুল রিকোয়েস্ট হালনাগাদ করুন
মতামতের জন্য নতুন PR খুলবেন না। একই ব্রাঞ্চে কমিট করে পুশ করুন: PR নিজে থেকে হালনাগাদ হয়ে যায় এবং রিভিউয়ার নতুন কমিট দেখেন।
cd ~/projects/review-analyser
cat > analyse.py <<'EOF'
"""Label product reviews as positive, negative or neutral."""
import csv
from words import NEGATIVE, POSITIVE
NEGATORS = {"not", "never"}
def label(text):
words = text.lower().split()
score = 0
for i, w in enumerate(words):
sign = -1 if i > 0 and words[i - 1] in NEGATORS else 1
score += sign * ((w in POSITIVE) - (w in NEGATIVE))
return "positive" if score > 0 else "negative" if score < 0 else "neutral"
if __name__ == "__main__":
with open("reviews.csv", newline="", encoding="utf-8") as f:
for row in csv.DictReader(f):
print(label(row["text"]), "|", row["text"])
EOF
echo "4,never fast enough" >> reviews.csv
python analyse.py
git commit -q -am "Treat never like not, as asked in review"
git push -qpositive | great phone and fast delivery
negative | battery is bad and the box was broken
negative | not good at all
negative | never fast enoughরাফি আবার রিভিউ করে Approve চাপে। সুরক্ষিত main-এ (রুলসেট, অ্যাডভান্সড টিউটোরিয়ালে) GitHub মার্জের আগে অনুমোদন ও পাস করা চেক বাধ্যতামূলক করতে পারে; তখনই মার্জ বোতাম সবুজ হয়।
৭. মার্জ
Merge pull request বোতামের তিনটা মোড আছে। কোনগুলো অনুমোদিত তা রিপোজিটরির মালিক Settings → General → Pull Requests-এ ঠিক করেন।
| বোতাম | main-এ যা এসে বসে | কখন ভালো |
|---|---|---|
| Create a merge commit (ডিফল্ট) | ব্রাঞ্চের সব কমিট এবং একটা মার্জ কমিট "Merge pull request #2 from …" (git merge --no-ff-এর মতো) | প্রতিটা PR-এর পুরো গল্প রাখতে |
| Squash and merge | PR-এর সব পরিবর্তন নিয়ে একটাই নতুন কমিট | "fix typo" ধরনের এলোমেলো কমিটওয়ালা PR; প্রতি PR-এ এক কমিটের পরিপাটি হিস্ট্রি |
| Rebase and merge | ব্রাঞ্চের কমিটগুলো এক এক করে main-এর ওপর বসানো, কোনো মার্জ কমিট নেই | প্রতিটা কমিট রেখে সরল রেখার হিস্ট্রি |
নাদিয়ার PR ডিফল্ট ব্যবহার করে। বোতামটা Git-এর ভাষায় কী করে দেখতে এখানে রাফি নিজের ক্লোনে ঠিক একই মার্জ করে পুশ করে। GitHub-এ আপনি শুধু Merge pull request → Confirm merge চাপবেন, তারপর Delete branch:
cd ~/rafi/review-analyser
git switch -q main
git pull -q
git merge --no-ff -m "Merge pull request #2 from nadia-rahman/fix/1-negation" origin/fix/1-negation
git push -q
git push origin --delete fix/1-negationMerge made by the 'ort' strategy.
analyse.py | 7 ++++++-
reviews.csv | 1 +
2 files changed, 7 insertions(+), 1 deletion(-)
To /home/nadia/remotes/review-analyser.git
- [deleted] fix/1-negation৮. লোকালি গুছিয়ে নিন
নিজের মেশিনে ফিরে নাদিয়া main হালনাগাদ করে, শেষ হয়ে যাওয়া ব্রাঞ্চ মুছে ফেলে, আর রিমোটে আর নেই এমন রিমোট-ট্র্যাকিং ব্রাঞ্চ ছেঁটে ফেলে (prune):
cd ~/projects/review-analyser
git switch main
git pull -q
git branch -d fix/1-negation
git fetch --prune
git log --oneline --graph --decorateSwitched to branch 'main'
Your branch is up to date with 'origin/main'.
Deleted branch fix/1-negation (was 6c272cb).
From /home/nadia/remotes/review-analyser
- [deleted] (none) -> origin/fix/1-negation
* 153381b (HEAD -> main, origin/main) Merge pull request #2 from nadia-rahman/fix/1-negation
|\
| * 6c272cb Treat never like not, as asked in review
| * 7a86d1d Flip the score of a keyword that follows not
|/
* cd2ea36 Write a README with quick start, example and limitations
* 4217c26 Add keyword review analyserগ্রাফটা পুরো PR দেখায়: ব্রাঞ্চের দুটো কমিট, আর সেগুলোকে main-এ এনে দেওয়া মার্জ কমিট। একবার git config --global fetch.prune true চালালে প্রতিটা ফেচ ও পুল মুছে ফেলা ব্রাঞ্চ নিজে থেকেই ছেঁটে দেয়। তারপর চক্র আবার শুরু: নতুন ইস্যু, হালনাগাদ main থেকে নতুন ব্রাঞ্চ।
আপনার প্রথম প্রজেক্ট প্রকাশ
CV, কোর্স সাবমিশন বা LinkedIn-এ রিপোজিটরির লিংক দেওয়ার আগে এই তালিকাটা দেখে নিন:
- এক লাইনের উদ্দেশ্য, quick start, একটা উদাহরণ আর সীমাবদ্ধতাসহ README।
- লাইসেন্স: না থাকলে অন্যরা আইনত আপনার কোড ব্যবহার করতে নাও পারে। GitHub-এ: Add file → Create new file, নাম দিন
LICENSE, আর একটা টেমপ্লেট বাছুন (MIT ছোট ও উদার)। ব্যবহার করা কোনো ডেটাসেট বা মডেল ওয়েটের লাইসেন্সও উল্লেখ করুন। .gitignoreআর হিস্ট্রিতে কোনো সিক্রেট নেই:git log -p -S "sk-"(এবং অন্য কি-র প্রিফিক্সের জন্যও) কিছু পায় না, আর.env.exampleসেটিংগুলোর তালিকা দেয়।- ডিপেন্ডেন্সি ঘোষিত:
requirements.txtবাpyproject.toml(uv হলে লকফাইলও), যাতে নতুন মেশিনে quick start সত্যিই কাজ করে। পরীক্ষা করুন: নতুন ফোল্ডারে ক্লোন করে নিজের README অনুসরণ করুন। - রিপোজিটরিতে ছোট স্যাম্পল ডেটা; বড় ডেটা ও মডেল লিংক বা ডাউনলোডযোগ্য, কখনো কমিট করা নয়।
- রিপোজিটরির পাতায় About বক্স (গিয়ার আইকন): একটা বিবরণ,
nlp,sentiment-analysis,python-এর মতো টপিক, আর ডেমো থাকলে ওয়েবসাইটের লিংক। - ওপরের সব ঠিক হলে ভিজিবিলিটি পাবলিক। তারপর GitHub প্রোফাইলে এটা পিন করুন (Customize your pins)। আপনার ইউজারনেমের ঠিক একই নামের রিপোজিটরিতে README থাকলে সেটাই আপনার প্রোফাইল পাতা হয়ে যায়।
gh-এর প্রথম পরিচয়, GitHub CLI
ব্রাউজারে যা করেছেন তার সবই টার্মিনাল থেকেও করা যায় gh (সংস্করণ ২.x) দিয়ে, যা GitHub-এর অফিশিয়াল কমান্ড-লাইন টুল। cli.github.com থেকে (বা winget install GitHub.cli, brew install gh দিয়ে) ইনস্টল করুন, তারপর একবার লগ ইন করুন। এই কমান্ডগুলো আসল GitHub-এর সাথে কথা বলে, তাই এখানে শুধু দেখানো হলো, চালানো হয়নি:
gh auth login # GitHub.com, HTTPS, ব্রাউজারে লগ ইন
gh repo create review-analyser --public --source=. --remote=origin --push
gh issue create --title '"not good" is labelled positive' --body "Review 3 is wrong." --label bug
gh pr create --base main --head fix/1-negation --title "Handle negation" --body "Closes #1" --reviewer rafi-ahmed
gh pr list # খোলা পুল রিকোয়েস্ট
gh pr checkout 2 # রিভিউয়ার PR-এর ব্রাঞ্চ লোকালে আনে
gh pr review 2 --approve
gh pr merge 2 --merge --delete-branch # অথবা --squash / --rebasegh repo create … --source=. --push আপনার লোকাল রিপোজিটরি থেকে GitHub রিপোজিটরি বানায়, origin যোগ করে এবং এক ধাপে পুশ করে। অপশন ছাড়া gh pr create সবকিছু ইন্টারঅ্যাক্টিভলি জিজ্ঞেস করে, আর gh pr view --web PR-টা ব্রাউজারে খোলে। gh auth login HTTPS পুশের জন্য Git-কেও আপনার GitHub লগ ইন ব্যবহার করতে সেট করে, ফলে টোকেন হাতে সামলাতে হয় না।
আসল AI কাজে এটা কোথায় দেখা যায়
- প্রোডাকশন AI সিস্টেমের প্রতিটা পরিবর্তন (নতুন প্রম্পট, মডেল সংস্করণ বাড়ানো, ইনফারেন্স API-তে নতুন ফিচার) PR-এর মধ্য দিয়ে যায়, ফলে অন্তত আরেকজন সেটা দেখেছেন এবং টেস্ট চলেছে।
- মডেল ও প্রম্পটের পরিবর্তন PR-এ আসে বিবরণে ইভ্যালুয়েশনের ফল নিয়ে: আগে ও পরে accuracy বা win rate, আর যে উদাহরণগুলো বদলেছে।
- ওপেন সোর্স: Hugging Face Transformers, scikit-learn, FastAPI ও LangChain অবদান নেয় শুধু ফর্ক থেকে আসা পুল রিকোয়েস্টে (ফর্ক অ্যাডভান্সড টিউটোরিয়ালে)। তাদের PR আলোচনা পড়া ইঞ্জিনিয়ারিং শেখার বিনামূল্যের পাঠ।
- AI কোডিং অ্যাসিস্ট্যান্ট ক্রমেই নিজেরাই PR খুলছে; কোড যে-ই লিখুক, মনোযোগ দিয়ে PR রিভিউ করা এখন একটা মূল দক্ষতা।
সাধারণ ভুল
- পুরোনো
mainথেকে ব্রাঞ্চ করা। তখন PR-এ সম্পর্কহীন পরিবর্তন বা কনফ্লিক্ট দেখা যায়। সমাধান:git switch main,git pull, তারপর ব্রাঞ্চ বানান। - বিশাল পুল রিকোয়েস্ট। ৪০টা ফাইল কেউ ঠিকমতো রিভিউ করতে পারে না। সমাধান: প্রতি PR-এ একটা বিষয়, বড়জোর কয়েকশো লাইন; রিফ্যাক্টর ও ফিচার আলাদা করুন।
- ফাঁকা বিবরণ। "Fixed stuff" রিভিউয়ারকে আন্দাজ করতে বাধ্য করে। সমাধান: কী, কেন, কীভাবে পরীক্ষা, কোথায় দেখতে হবে, এবং
Closes #N। - প্রতি দফা মতামতে নতুন PR খোলা। আলোচনা ছড়িয়ে যায়। সমাধান: একই ব্রাঞ্চে নতুন কমিট পুশ করুন; PR হালনাগাদ হয়।
- গোছাতে ভুলে যাওয়া। ডজন ডজন পুরোনো ব্রাঞ্চ জীবন্ত ব্রাঞ্চগুলো আড়াল করে। সমাধান: মার্জের পর GitHub-এ ব্রাঞ্চ মুছুন, লোকালে
git branch -dকরুন, আরfetch.pruneচালু রাখুন।
নিজে চেষ্টা করুন
- সহজ: এই পরিবর্তনের জন্য একটা PR শিরোনাম ও বিবরণ লিখুন: "Adds excellent to the positive words and awful to the negative words, because 12 of 200 hand-labelled reviews used them and were labelled neutral; fixes issue #4."
- মাঝারি: হালনাগাদ
mainথেকেdocs/negationনামে একটা ব্রাঞ্চ শুরু করুন,README.md-এ একটা লাইন যোগ করুন যা ব্যাখ্যা করে "not" ও "never" পরের কীওয়ার্ডকে উল্টে দেয়, কমিট করুন এবং আপস্ট্রিমসহ পুশ করুন। তারপর দেখান একজন রিভিউয়ার কী দেখবেন: PR-এর কমিট আর বদলানো ফাইল। - কঠিন: এবার PR মার্জ হয় Squash and merge দিয়ে। রাফির ক্লোনে সেটা অনুকরণ করুন (
git merge --squash, তারপরExplain negation in the README (#3)শিরোনামের একটা কমিট, পুশ, রিমোট ব্রাঞ্চ মুছে ফেলা)। তারপর নাদিয়ার রিপোজিটরিতে গুছিয়ে নিন।git branch -d docs/negationকেন রাজি হয় না, আর তখন কী করবেন?
উত্তর
সহজ, একটা ভালো উত্তর:
Title: Add "excellent" and "awful" to the keyword lists
## What
Adds "excellent" to POSITIVE and "awful" to NEGATIVE in words.py.
## Why
12 of 200 hand-labelled reviews contain one of these words and were
labelled neutral. Closes #4
## How I tested it
python analyse.py on the labelled sample: those 12 reviews now get
the right label; no other label changed.# মাঝারি
cd ~/projects/review-analyser
git switch main
git pull -q
git switch -c docs/negation
printf '\n"not" and "never" flip the score of the keyword after them.\n' >> README.md
git commit -q -am "Explain negation in the README"
git push -q -u origin docs/negation
git log --oneline main..docs/negation
git diff --stat main...docs/negationAlready on 'main'
Your branch is up to date with 'origin/main'.
Switched to a new branch 'docs/negation'
dc49360 Explain negation in the README
README.md | 2 ++
1 file changed, 2 insertions(+)# কঠিন: Rafi "Squash and merge" চাপে
cd ~/rafi/review-analyser
git pull -q
git merge --squash origin/docs/negation
git commit -q -m "Explain negation in the README (#3)"
git push -q
git push -q origin --delete docs/negation
# Nadia গুছিয়ে নেয়
cd ~/projects/review-analyser
git switch -q main
git pull -q
git fetch -q --prune
git branch -d docs/negationUpdating 153381b..dc49360
Fast-forward
Squash commit -- not updating HEAD
README.md | 2 ++
1 file changed, 2 insertions(+)
error: the branch 'docs/negation' is not fully merged.
If you are sure you want to delete it, run 'git branch -D docs/negation'(git merge --squash জানায় Squash commit -- not updating HEAD: এটা একত্র করা পরিবর্তনগুলো স্টেজ করে কিন্তু কমিট করে না, আর পরের git commit একটাই স্কোয়াশ কমিট বানায়।) স্কোয়াশ মার্জ একই পরিবর্তন নিয়ে একটা নতুন কমিট বানায়; ব্রাঞ্চের নিজের কমিট কখনো main-এর অংশ হয়নি, তাই -d সেটাকে অমার্জড মনে করে অস্বীকার করে (মেসেজের ঠিক শব্দ Git সংস্করণভেদে আলাদা)। আপনি নিজে দেখে নিয়েছেন PR মার্জ হয়েছে, তাই জোর করে মুছুন:
git branch -D docs/negation
git log --oneline -3Deleted branch docs/negation (was dc49360).
a482060 Explain negation in the README (#3)
153381b Merge pull request #2 from nadia-rahman/fix/1-negation
cd2ea36 Write a README with quick start, example and limitationsসারসংক্ষেপ
- README বলে প্রজেক্ট কী করে, কীভাবে চালাতে হয় (কপি করা যায় এমন কমান্ড), একটা উদাহরণ, কীভাবে কাজ করে, সীমাবদ্ধতা আর লাইসেন্স।
- PR ওয়ার্কফ্লো: ইস্যু → হালনাগাদ
mainথেকে ব্রাঞ্চ → কমিট →git push -u→ পুল রিকোয়েস্ট → রিভিউ → একই ব্রাঞ্চে আরও কমিট → মার্জ → ব্রাঞ্চ মুছেgit pull। - ভালো PR ছোট হয়, স্পষ্ট শিরোনাম থাকে, আর বিবরণে থাকে কী, কেন, কীভাবে পরীক্ষা এবং
Closes #N। - GitHub মার্জ করে মার্জ কমিট (ডিফল্ট), স্কোয়াশ কমিট বা রিবেস দিয়ে; স্কোয়াশের পর লোকাল ব্রাঞ্চ মুছতে
-Dলাগে। - প্রকাশের আগে: README, লাইসেন্স,
.gitignore, হিস্ট্রিতে সিক্রেট নেই, ডিপেন্ডেন্সি, স্যাম্পল ডেটা, About বক্স ও টপিক।ghদিয়ে এর সবই টার্মিনাল থেকে করা যায়।
এরপর: ওয়েব কীভাবে কাজ করে: ক্লায়েন্ট, সার্ভার ও HTTP। আপনার কোড এখন GitHub-এ; এবার এই টপিকের অন্য অর্ধেক শুরু করবেন: একটা প্রোগ্রাম ওয়েবের মাধ্যমে আরেকটার সাথে কথা বললে আসলে কী ঘটে, যা আপনার কল করা ও বানানো প্রতিটা API-র ভিত্তি।