অধ্যায় 2 · Git ও GitHub
ব্রাঞ্চ, মার্জ ও মার্জ কনফ্লিক্ট
- পৃষ্ঠা 8 / 22
- 16 মিনিট পড়া
এ পর্যন্ত প্রতিটা কমিট সরাসরি main-এ গেছে। যতক্ষণ না আপনি ঝুঁকিপূর্ণ কিছু চেষ্টা করতে চান (নতুন লেবেলিং রুল, অন্য মডেল, প্রম্পট নতুন করে লেখা) আর চান main ঠিকঠাক চলুক, কিংবা দুজন একসাথে প্রজেক্ট বদলান, ততক্ষণ এভাবে চলে। ব্রাঞ্চ (branch) দুটো সমস্যারই সমাধান: প্রতিটা কাজের ধারা নিজস্ব ব্রাঞ্চ পায়, সেখানে ইচ্ছামতো কমিট করেন, আর ভালো হলে সেটা আবার মার্জ (merge) করে দেন।
Git-এ ব্রাঞ্চ সস্তা আর দ্রুত; পেশাদার টিমগুলো দিনে কয়েকটা বানায়। এই পাতা দেখায় ব্রাঞ্চ আসলে কী, দুই ধরনের মার্জ কী, আর দুটো ব্রাঞ্চ একই লাইন বদলালে মার্জ কনফ্লিক্ট (merge conflict) কীভাবে শান্তভাবে মেটাবেন।
যা শিখবেন
- ব্রাঞ্চ কী (একটা কমিটের দিকে নির্দেশ করা সরানো যায় এমন পয়েন্টার) এবং
HEADকী। git switch -c,git branchআরgit switchদিয়ে ব্রাঞ্চ বানানো, দেখা এবং বদলানো।- ফাস্ট-ফরওয়ার্ড মার্জ আর থ্রি-ওয়ে মার্জ, এবং
git log --graph-এ সেগুলো পড়া। - সত্যিকারের একটা মার্জ কনফ্লিক্ট বানানো, কনফ্লিক্ট মার্কার পড়া এবং সেটা মেটানো।
git branch -dদিয়ে নিরাপদে ব্রাঞ্চ মোছা, আর-Dদিয়ে এক্সপেরিমেন্ট ফেলে দেওয়া।
উদাহরণ প্রজেক্ট সাজানো
আরও একবার সেই রিভিউ অ্যানালাইজার, main-এ একটা কমিটসহ:
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,it works
EOF
git add .
git commit -q -m "Add keyword review analyser"
git log --oneline7f5e38e Add keyword review analyserব্রাঞ্চ আসলে কী
ব্রাঞ্চ আপনার ফাইলের কপি নয়। এটা একটা কমিটের দিকে নির্দেশ করা একটা নাম, যা .git-এর ভেতরে ছোট একটা ফাইলে রাখা থাকে। ব্রাঞ্চে কমিট করলে Git নতুন কমিট বানায় আর ব্রাঞ্চের নামটা সেটার দিকে এগিয়ে দেয়। HEAD হলো Git-এর "আপনি এখানে আছেন" চিহ্ন: আপনি যে ব্রাঞ্চে আছেন, এটা সেদিকে নির্দেশ করে।
git branch
git log --oneline --decorate
git rev-parse main* main
7f5e38e (HEAD -> main) Add keyword review analyser
7f5e38e11b46dd79dfd7f805148d947b79a782a8git branch ব্রাঞ্চগুলো তালিকা করে এবং বর্তমানটায় তারকাচিহ্ন (*) বসায়। (HEAD -> main) মানে "HEAD main-এ আছে, আর main এখানে নির্দেশ করছে"। git rev-parse নামটা যে পুরো হ্যাশে নির্দেশ করছে সেটা দেখায়: ব্রাঞ্চ বলতে এটুকুই। একটা ব্রাঞ্চ বানাতে খরচ হয় ৪১ বাইটের একটা ফাইল (Git-এর ডিফল্ট স্টোরেজে), তাই ব্রাঞ্চ বানাতে কখনো দ্বিধা করবেন না।
ব্রাঞ্চ বানানো ও বদলানো
নাদিয়া main-এ হাত না দিয়ে আরও স্যাম্পল রিভিউ যোগ করতে চায়, যতক্ষণ না সে সন্তুষ্ট হয়। git switch -c NAME বর্তমান কমিটে একটা ব্রাঞ্চ বানায় এবং তাতে সুইচ করে:
git switch -c feature/more-reviews
cat >> reviews.csv <<'EOF'
4,not good at all
5,love the camera
EOF
git commit -q -am "Add two more sample reviews"
git log --oneline --graph --all --decorateSwitched to a new branch 'feature/more-reviews'
* 331faf2 (HEAD -> feature/more-reviews) Add two more sample reviews
* 7f5e38e (main) Add keyword review analyser--all শুধু বর্তমানটা নয়, সব ব্রাঞ্চ দেখায়, আর --decorate কমিটগুলোর পাশে সেগুলোর দিকে নির্দেশ করা ব্রাঞ্চের নাম বসায় (টার্মিনালে Git সাধারণত এই অপশন ছাড়াই এটা করে)। feature/more-reviews এক কমিট এগিয়ে গেছে; main এখনো প্রথম কমিটে আছে। ব্রাঞ্চ বদলালে আপনার ফোল্ডারের ফাইলগুলো সেই ব্রাঞ্চের কমিটের সাথে মিলে যায়:
git switch main
wc -l reviews.csv
git switch feature/more-reviews
wc -l reviews.csvSwitched to branch 'main'
4 reviews.csv
Switched to branch 'feature/more-reviews'
6 reviews.csvএকই ফোল্ডার, একই ফাইলের নাম, কিন্তু আলাদা কনটেন্ট: প্রতিবার সুইচ করার সময় Git reviews.csv নতুন করে লিখেছে। (ব্রাঞ্চের নামে স্ল্যাশ শুধু নামকরণের রীতি; feature/…, fix/… আর exp/… লম্বা ব্রাঞ্চ তালিকা পড়তে সুবিধা দেয়।)
ফাস্ট-ফরওয়ার্ড মার্জ
নতুন রিভিউগুলো ঠিকই আছে, তাই সেগুলো main-এ যাবে। আপনি সবসময় যে ব্রাঞ্চে আছেন সেটার ভেতরে মার্জ করেন: আগে গ্রহণকারী ব্রাঞ্চে সুইচ করুন, তারপর যে ব্রাঞ্চ আনতে চান তার নাম দিন।
git switch main
git merge feature/more-reviewsSwitched to branch 'main'
Updating 7f5e38e..331faf2
Fast-forward
reviews.csv | 2 ++
1 file changed, 2 insertions(+)ফাস্ট-ফরওয়ার্ড (fast-forward) মানে ব্রাঞ্চ শুরু হওয়ার পর main-এ নিজস্ব কোনো নতুন কমিট ছিল না, তাই Git-কে কিছু মেলাতে হয়নি: শুধু main পয়েন্টারটা ব্রাঞ্চের কমিট পর্যন্ত এগিয়ে দিয়েছে। কোনো নতুন কমিট তৈরি হয়নি।
before: A <- main
\
B <- feature/more-reviews
after: A --- B <- main, feature/more-reviewsনতুন ডেটায় অ্যানালাইজার চালালে একটা আসল বাগ ধরা পড়ে:
python analyse.pypositive | great phone and fast delivery
negative | battery is bad and the box was broken
neutral | it works
positive | not good at all
positive | love the camera"not good at all" positive লেবেল পেয়েছে, কারণ অ্যানালাইজার শুধু শব্দ গোনে আর "not" উপেক্ষা করে। এটা পরের ব্রাঞ্চের কাজ।
থ্রি-ওয়ে মার্জ
নাদিয়া নেগেশন (না-বাচক) সামলানোর জন্য একটা ব্রাঞ্চ শুরু করে এবং label() এমনভাবে নতুন করে লেখে যাতে "not"-এর ঠিক পরের শব্দ উল্টো অর্থে গোনা হয়:
git switch -c feature/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
git commit -q -am "Handle negation: not good is negative"এর মধ্যে main-ও এগিয়ে যায়: সেখানে একটা README যোগ হয় (টিমে এটা হতো আপনি যখন ব্যস্ত ছিলেন, তখন মার্জ হওয়া কোনো সহকর্মীর কাজ):
git switch main
echo "# Review analyser" > README.md
git add README.md
git commit -q -m "Add README"
git log --oneline --graph --all --decorateSwitched to branch 'main'
* 5fdf51b (feature/negation) Handle negation: not good is negative
| * b6e78ff (HEAD -> main) Add README
|/
* 331faf2 (feature/more-reviews) Add two more sample reviews
* 7f5e38e Add keyword review analyserহিস্ট্রি এখন ডাইভার্জ (diverge) করেছে: দুই ব্রাঞ্চেই এমন কমিট আছে যা অন্যটায় নেই। ফাস্ট-ফরওয়ার্ড সম্ভব নয়, তাই Git থ্রি-ওয়ে মার্জ (three-way merge) করে: দুই ব্রাঞ্চের মাথাকে তাদের সাধারণ পূর্বপুরুষের (মার্জ বেস, এখানে "Add two more sample reviews" কমিট) সাথে তুলনা করে, পরিবর্তনগুলো মেলায়, আর ফলাফল রাখে দুটো প্যারেন্টসহ একটা নতুন মার্জ কমিটে।
git merge --no-edit feature/negationMerge made by the 'ort' strategy.
analyse.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)ort হলো Git-এর ডিফল্ট মার্জ স্ট্র্যাটেজির নাম। --no-edit না দিলে Git আপনার এডিটর খুলে Merge branch 'feature/negation' মেসেজ দেখায়; সেভ করে বন্ধ করলে মার্জ শেষ হয়। এবার গ্রাফ আর ফলাফল দেখুন:
git log --oneline --graph --all --decorate
python analyse.py* a67180e (HEAD -> main) Merge branch 'feature/negation'
|\
| * 5fdf51b (feature/negation) Handle negation: not good is negative
* | b6e78ff Add README
|/
* 331faf2 (feature/more-reviews) Add two more sample reviews
* 7f5e38e Add keyword review analyser
positive | great phone and fast delivery
negative | battery is bad and the box was broken
neutral | it works
negative | not good at all
positive | love the cameraদুই ধারা মার্জ কমিটে এসে মিলেছে, main-এ README আর নেগেশন ফিক্স দুটোই আছে, এবং "not good at all" এখন negative। গ্রাফে * একটা কমিট, আর |, \ ও / কমিটকে তার প্যারেন্টের সাথে জোড়ে।
C <- feature/negation C
/ / \
A --- B A --- B M <- main
\ \ /
D <- main Dফাস্ট-ফরওয়ার্ড সম্ভব হলেও টিমগুলো মাঝে মাঝে মার্জ কমিট চায়, যাতে হিস্ট্রিতে দেখা যায় একটা ফিচার কোথায় শুরু আর কোথায় শেষ হয়েছিল। git merge --no-ff BRANCH সেটাই করে; GitHub-এর ডিফল্ট "Merge pull request" বোতামও একইভাবে কাজ করে, যা পুল রিকোয়েস্টের পাতায় দেখবেন।
মার্জ হয়ে যাওয়া ব্রাঞ্চ গুছিয়ে ফেলা
ব্রাঞ্চ মার্জ হয়ে গেলে তার কমিটগুলো main-এর অংশ, নামটার আর দরকার নেই। git branch --merged সেই ব্রাঞ্চগুলো তালিকা করে যাদের সব কমিট বর্তমান ব্রাঞ্চে আছে; git branch -d সেগুলো মোছে:
git branch --merged
git branch -d feature/more-reviews feature/negation
git branch feature/more-reviews
feature/negation
* main
Deleted branch feature/more-reviews (was 331faf2).
Deleted branch feature/negation (was 5fdf51b).
* mainব্রাঞ্চ মোছা মানে শুধু নামটা মোছা; কমিটগুলো main-এর হিস্ট্রিতে থেকে যায়। -d নিরাপদ রূপ: যে ব্রাঞ্চের কমিট কোথাও মার্জ হয়নি সেটা মুছতে অস্বীকার করে, আর সত্যিই চাইলে -D ব্যবহার করতে বলে। ব্যর্থ এক্সপেরিমেন্টের জন্য ঠিক এটাই দরকার:
git switch -q -c exp/remove-stopwords
echo "STOPWORDS = {\"the\", \"and\", \"is\"}" >> words.py
git commit -q -am "Experiment: stopword list"
git switch -q main
git branch -D exp/remove-stopwordsDeleted branch exp/remove-stopwords (was 937aec5).(-q git switch-কে চুপ রাখে।) এক্সপেরিমেন্টের কমিট আর কোনো ব্রাঞ্চে নেই; আগের পাতার reflog আরও কয়েক সপ্তাহ সেটা খুঁজে পেতে পারে।
মার্জ কনফ্লিক্ট
আলাদা লাইনে বা আলাদা ফাইলে করা পরিবর্তন Git নিজে নিজেই মার্জ করে। দুই ব্রাঞ্চ একই লাইন আলাদাভাবে বদলালে Git জানে না কোন সংস্করণ ঠিক, তাই থেমে গিয়ে আপনাকে জিজ্ঞেস করে। এটাই মার্জ কনফ্লিক্ট। এটা স্বাভাবিক, কোনো এরর নয়, আর মার্কার পড়তে পারলে মেটাতে এক মিনিটও লাগে না।
চলুন একটা বানাই। একটা ব্রাঞ্চে নাদিয়া positive শব্দে "excellent" যোগ করে। main-এ একজন সহকর্মী একই লাইনে "perfect" যোগ করে:
git switch -c feature/more-positive
cat > words.py <<'EOF'
POSITIVE = {"good", "great", "fast", "love", "excellent"}
NEGATIVE = {"bad", "slow", "broken", "late"}
EOF
git commit -q -am "Add excellent to positive words"
git switch main
cat > words.py <<'EOF'
POSITIVE = {"good", "great", "fast", "love", "perfect"}
NEGATIVE = {"bad", "slow", "broken", "late"}
EOF
git commit -q -am "Add perfect to positive words"কমিট না করা পরিবর্তন নিয়ে সুইচ করা
মার্জের আগে git switch সম্পর্কে একটা কথা। অন্য ব্রাঞ্চে ফাইলটার সংস্করণ একই থাকলে কমিট না করা এডিট আপনার সাথে সাথে চলে আসে। সুইচ করলে সেগুলো ওভাররাইট হয়ে যাবে এমন হলে Git আপনার কাজ হারানোর বদলে অস্বীকার করে:
echo "# TODO: more words" >> words.py
git switch feature/more-positiveerror: Your local changes to the following files would be overwritten by checkout:
words.py
Please commit your changes or stash them before you switch branches.
Abortingএডিটটা কমিট করুন, অথবা এখানকার মতো git restore দিয়ে ফেলে দিন (কিংবা git stash দিয়ে একপাশে রাখুন, যা অ্যাডভান্সড টিউটোরিয়ালে আছে):
git restore words.pyকনফ্লিক্ট
git merge feature/more-positiveAuto-merging words.py
CONFLICT (content): Merge conflict in words.py
Automatic merge failed; fix conflicts and then commit the result.মার্জ মাঝপথে থেমে গেছে। git status বলে দেয় আপনি কোথায় আছেন আর কী করতে হবে:
git statusOn branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: words.py
no changes added to commit (use "git add" and/or "git commit -a")Git দুটো সংস্করণই ফাইলে লিখে দিয়েছে, কনফ্লিক্ট মার্কারের (conflict markers) মাঝে:
cat words.py<<<<<<< HEAD
POSITIVE = {"good", "great", "fast", "love", "perfect"}
=======
POSITIVE = {"good", "great", "fast", "love", "excellent"}
>>>>>>> feature/more-positive
NEGATIVE = {"bad", "slow", "broken", "late"}| মার্কার | মানে |
|---|---|
<<<<<<< HEAD | আপনার দিকের শুরু: আপনি যে ব্রাঞ্চে আছেন এবং যার ভেতরে মার্জ করছেন (main) |
======= | দুই দিকের মাঝের বিভাজক |
>>>>>>> feature/more-positive | তাদের দিকের শেষ: যে ব্রাঞ্চ মার্জ করে আনা হচ্ছে |
শুধু কনফ্লিক্টের লাইনগুলো চিহ্নিত হয়; NEGATIVE লাইনটা, যা কোনো পক্ষই বদলায়নি, যেমন ছিল তেমনই আছে। মেটাতে হলে ফাইলটা এমনভাবে এডিট করুন যেন প্রজেক্টের যা বলা উচিত তাই বলে, আর তিনটা মার্কার লাইনই মুছে দিন। এখানে দুটো শব্দই চাই। আপনার এডিটরে words.py এভাবে বানান (আমরা cat দিয়ে লিখছি যাতে ধাপটা কপি করতে পারেন):
cat > words.py <<'EOF'
POSITIVE = {"good", "great", "fast", "love", "perfect", "excellent"}
NEGATIVE = {"bad", "slow", "broken", "late"}
EOF
grep -c '<<<<<<<\|>>>>>>>' words.py
python -c "import words; print(sorted(words.POSITIVE))"0
['excellent', 'fast', 'good', 'great', 'love', 'perfect']কোনো মার্কার নেই (গণনা ০) এবং ফাইলটা আবার বৈধ Python। কনফ্লিক্ট মেটানোর পর সবসময় কোড বা টেস্ট চালান: মার্কার ছাড়াও একটা সমাধান ভুল হতে পারে। তারপর ফাইলটা স্টেজ করে সমাধান হয়েছে বলে চিহ্নিত করুন এবং কমিট দিয়ে মার্জ শেষ করুন:
git add words.py
git commit --no-edit
git log --oneline --graph --decorate -5[main 9e4c744] Merge branch 'feature/more-positive'
* 9e4c744 (HEAD -> main) Merge branch 'feature/more-positive'
|\
| * 5290990 (feature/more-positive) Add excellent to positive words
* | 95e91ff Add perfect to positive words
|/
* a67180e Merge branch 'feature/negation'
|\
| * 5fdf51b Handle negation: not good is negativeএখানে এডিটর অনেক সাহায্য করে। VS Code, PyCharm ইত্যাদি কনফ্লিক্ট হাইলাইট করে এবং Accept Current Change (আপনার দিক, HEAD), Accept Incoming Change (তাদের দিক) আর Accept Both Changes বোতাম দেয়; তবুও ফলাফলটা আপনাকেই দেখে নিতে হবে। মার্জ ভুল পথে গেলে এবং নতুন করে শুরু করতে চাইলে git merge --abort সবকিছু ঠিক git merge-এর আগের অবস্থায় ফিরিয়ে দেয়।
কনফ্লিক্ট ছোট রাখা
- দীর্ঘদিন চলা ব্রাঞ্চে ঘন ঘন
mainমার্জ করুন (অথবা ব্রাঞ্চ অল্পদিনের রাখুন), যাতে সেগুলো বেশি দূরে সরে না যায়। - কমিট আর ব্রাঞ্চ একটা বিষয়ে কেন্দ্রীভূত রাখুন; যে ব্রাঞ্চ সব ফাইল রিফরম্যাট করে সেটা সবার সাথে কনফ্লিক্ট করবে।
- একটা ফরম্যাটার ঠিক করে নিন (Python-এর জন্য Ruff বা Black), যাতে হোয়াইটস্পেস আর কোটের ধরন কখনো কনফ্লিক্ট না ঘটায়।
- নোটবুক (
.ipynb) হলো আউটপুটসহ JSON, এবং খুব খারাপভাবে কনফ্লিক্ট করে; লজিক.pyফাইলে রাখুন এবং নোটবুক কমিটের আগে আউটপুট মুছে ফেলুন।
বাস্তব AI কাজে কোথায় লাগে
- এক্সপেরিমেন্ট ব্রাঞ্চ:
exp/bigger-context,exp/new-prompt-v3:mainনা ভেঙে একটা আইডিয়া চেষ্টা করুন, ইভ্যালুয়েশন ভালো হলে মার্জ করুন, না হলে-Dদিয়ে মুছে দিন। - ফিচার ব্রাঞ্চ ও পুল রিকোয়েস্ট: প্রায় প্রতিটা টিম অল্পদিনের ব্রাঞ্চে কাজ করে এবং পুল রিকোয়েস্টের মাধ্যমে সেগুলো
main-এ মার্জ করে (এখান থেকে দুই পাতা পরে), ফলেmainসবসময় ডিপ্লয়যোগ্য থাকে। - হটফিক্স: ডিপ্লয় করা মডেল API ভেঙে গেলে
mainথেকে একটাfix/…ব্রাঞ্চে ছোট ফিক্সটা করা হয়, আর বড় ফিচারগুলো নিজ নিজ ব্রাঞ্চে চলতে থাকে। - প্রম্পট ও কনফিগ ফাইল LLM অ্যাপে কনফ্লিক্টের পরিচিত জায়গা, কারণ সবাই এগুলো টিউন করে। ছোট, কেন্দ্রীভূত পরিবর্তন আর ঘন ঘন মার্জ কনফ্লিক্ট বিরল রাখে।
সাধারণ ভুল
- উল্টো দিকে মার্জ করা। ফিচার ব্রাঞ্চে থাকা অবস্থায়
git merge mainচালালেmainফিচারে ঢোকে, উল্টোটা নয়। সমাধান: আগেgit switch main, তারপরgit merge feature/…; কোন ব্রাঞ্চে তারকাচিহ্ন (*) আছেgit branchদিয়ে দেখে নিন। - কনফ্লিক্ট মার্কার রয়ে গেছে এমন ফাইল কমিট করা। সবার জন্য কোড ভেঙে যায়। সমাধান:
git add-এর আগে<<<<<<<খুঁজে দেখুন, এবং প্রোগ্রাম বা টেস্ট চালান। - অন্য দিকটা না পড়েই মুছে দিয়ে সমাধান করা। চুপচাপ সহকর্মীর কাজ আনডু করে ফেলেন। সমাধান: দুটো পরিবর্তনই বুঝুন; প্রায়ই সঠিক উত্তর দুটোকে মেলানো, যেমন এখানে।
- সপ্তাহের পর সপ্তাহ একটা ব্রাঞ্চে কাজ করা।
mainথেকে যত দূরে সরে যায়, শেষ মার্জ তত বড় আর কঠিন হয়। সমাধান: ছোট ব্রাঞ্চ, কয়েক দিনের মধ্যে মার্জ; নিয়মিতmainমার্জ করে আনুন। - অভ্যাসবশে
-Dব্যবহার করা। এটা জিজ্ঞেস না করেই মার্জ না হওয়া কাজ মুছে দেয়। সমাধান:-dব্যবহার করুন;-Dশুধু সেই এক্সপেরিমেন্টের জন্য, যা ফেলে দেবেন বলে ঠিক করেছেন।
নিজে চেষ্টা করুন
একই রিপোজিটরিতে, ক্রমানুসারে চালিয়ে যান।
- সহজ:
fix/readmeনামে একটা ব্রাঞ্চ বানান,README.md-তেLabels reviews as positive, negative or neutral.লাইনটা যোগ করে কমিট করুন, তারপরmain-এ মার্জ করুন। কোন ধরনের মার্জ হয়, আর কেন? ব্রাঞ্চটা মুছে দিন। - মাঝারি:
mainথেকে দুটো ব্রাঞ্চ বানান:feature/neg-wordsNEGATIVE-এ"terrible"যোগ করে, আরfeature/samplereviews.csv-এর শেষে6,terrible batteryরিভিউ যোগ করে। দুটোইmain-এ মার্জ করুন (দ্বিতীয় মার্জে মার্জ কমিট লাগবে) এবং গ্রাফ দেখান। - কঠিন: ইচ্ছা করে একটা কনফ্লিক্ট বানান:
feature/strong-negব্রাঞ্চNEGATIVEলাইনে"awful"যোগ করে, আরmainএকই লাইনে"poor"যোগ করে। মার্জ করুন, দুটো শব্দই রেখে সমাধান করুন, দেখুন কোনো মার্কার নেই, এবং মার্জ শেষ করুন।
উত্তর
# সহজ
git switch -c fix/readme
echo "Labels reviews as positive, negative or neutral." >> README.md
git commit -q -am "Describe the project in the README"
git switch main
git merge fix/readme
git branch -d fix/readmeSwitched to a new branch 'fix/readme'
Switched to branch 'main'
Updating 9e4c744..74fad10
Fast-forward
README.md | 1 +
1 file changed, 1 insertion(+)
Deleted branch fix/readme (was 74fad10).একটা ফাস্ট-ফরওয়ার্ড: ব্রাঞ্চ বানানোর পর main-এ কোনো নতুন কমিট ছিল না, তাই Git শুধু পয়েন্টার সরিয়েছে।
# মাঝারি
git switch -q -c feature/neg-words
cat > words.py <<'EOF'
POSITIVE = {"good", "great", "fast", "love", "perfect", "excellent"}
NEGATIVE = {"bad", "slow", "broken", "late", "terrible"}
EOF
git commit -q -am "Add terrible to negative words"
git switch -q main
git switch -q -c feature/sample
echo "6,terrible battery" >> reviews.csv
git commit -q -am "Add a terrible battery review"
git switch -q main
git merge -q feature/neg-words
git merge -q --no-edit feature/sample
git log --oneline --graph --decorate -4
python analyse.py | tail -n 1* 11e6553 (HEAD -> main) Merge branch 'feature/sample'
|\
| * bb5b471 (feature/sample) Add a terrible battery review
* | 468c878 (feature/neg-words) Add terrible to negative words
|/
* 74fad10 Describe the project in the README
negative | terrible batteryপ্রথম মার্জ ফাস্ট-ফরওয়ার্ড ছিল; দ্বিতীয়টায় মার্জ কমিট লেগেছে, কারণ তখন main সেই বিন্দু পেরিয়ে এগিয়ে গেছে যেখান থেকে feature/sample শুরু হয়েছিল।
# কঠিন
git switch -q -c feature/strong-neg
cat > words.py <<'EOF'
POSITIVE = {"good", "great", "fast", "love", "perfect", "excellent"}
NEGATIVE = {"bad", "slow", "broken", "late", "terrible", "awful"}
EOF
git commit -q -am "Add awful to negative words"
git switch -q main
cat > words.py <<'EOF'
POSITIVE = {"good", "great", "fast", "love", "perfect", "excellent"}
NEGATIVE = {"bad", "slow", "broken", "late", "terrible", "poor"}
EOF
git commit -q -am "Add poor to negative words"
git merge feature/strong-negAuto-merging words.py
CONFLICT (content): Merge conflict in words.py
Automatic merge failed; fix conflicts and then commit the result.cat > words.py <<'EOF'
POSITIVE = {"good", "great", "fast", "love", "perfect", "excellent"}
NEGATIVE = {"bad", "slow", "broken", "late", "terrible", "poor", "awful"}
EOF
grep -c '<<<<<<<' words.py
git add words.py
git commit -q --no-edit
git branch -d feature/strong-neg feature/neg-words feature/sample feature/more-positive
git log --oneline -10
Deleted branch feature/strong-neg (was c9e3323).
Deleted branch feature/neg-words (was 468c878).
Deleted branch feature/sample (was bb5b471).
Deleted branch feature/more-positive (was 5290990).
0b814d7 Merge branch 'feature/strong-neg'সারসংক্ষেপ
- ব্রাঞ্চ একটা কমিটের সরানো যায় এমন নাম;
HEADচিহ্নিত করে আপনি কোন ব্রাঞ্চে আছেন। ব্রাঞ্চ সস্তা: প্রতিটা ফিচার, ফিক্স আর এক্সপেরিমেন্টের জন্য একটা করে ব্যবহার করুন। git switch -c NAMEবানায় ও সুইচ করে;git switch NAMEসুইচ করে;git branchতালিকা দেখায়;git log --oneline --graph --allছবিটা দেখায়।- যে ব্রাঞ্চে আছেন তার ভেতরে মার্জ করুন। সেটা না এগোলে মার্জ ফাস্ট-ফরওয়ার্ড; দুই দিকেই নতুন কমিট থাকলে Git দুটো প্যারেন্টসহ থ্রি-ওয়ে মার্জ কমিট বানায়।
- কনফ্লিক্ট মানে দুই দিকই একই লাইন বদলেছে। ফাইলটা সঠিক ফলাফলে এডিট করুন, মার্কার সরান, কোড চালান,
git add,git commit; অথবা নতুন করে শুরু করতেgit merge --abort। git branch -dমার্জ হওয়া ব্রাঞ্চ নিরাপদে মোছে;-Dমার্জ না হওয়া এক্সপেরিমেন্ট জোর করে মোছে।
এরপর: GitHub: রিমোট, push, pull ও clone। আপনার ব্রাঞ্চ আর কমিট এখনো শুধু আপনার ল্যাপটপে। এরপর রিপোজিটরিকে একটা রিমোটের সাথে জুড়বেন, পুশ করবেন, অন্য কোথাও ক্লোন করবেন, এবং দুটো কপি সিঙ্কে রাখবেন।