
একটি প্রজেক্টে দুই জন মানুষ একসাথে কাজ করলেই প্রশ্নটা চলে আসে, কে কোন ফাইল বদলালো আর কার বদলটা আগে বসবে। আমাদের দেশে অনেকেই এই সমস্যার সমাধান করেন ফোল্ডার কপি করে। নাম হয় প্রজেক্ট নতুন, প্রজেক্ট নতুন ২, প্রজেক্ট একেবারে ফাইনাল। কয়েক দিন পরে আর মনে থাকে না কোনটা আসল।
Git ঠিক এই জায়গাটাতেই কাজ করে। এটি আপনার প্রতিটি বদলের একটি সময়রেখা তৈরি করে রাখে, ফলে যেকোনো দিনের অবস্থায় ফিরে যাওয়া যায়। আর GitHub সেই সময়রেখাটিকে অনলাইনে রেখে টিমের সবার জন্য খুলে দেয়।
এই টিউনে আমি একটি বাস্তব ওপেন সোর্স প্রজেক্টের আসল স্ক্রিনশট দিয়ে দেখাবো ব্রাঞ্চ, Pull Request আর Merge Conflict জিনিসগুলো আসলে কেমন দেখতে হয়, আর কমান্ড লাইনে কী লিখে সেগুলো সামলাতে হয়। প্রতিটি ধাপ আপনি নিজের কম্পিউটারে করে দেখতে পারবেন।
ফোল্ডার কপি করলে আপনি শুধু একটি মুহূর্তের ছবি রেখে দেন। কিন্তু আপনি জানতে পারেন না কে কী বদলেছে, কেন বদলেছে, আর দুই জনের বদল একসাথে মেলাতে হলে কী করতে হবে। Git এই তিনটি প্রশ্নেরই উত্তর রাখে।
Git ইনস্টল করার পর সবার আগে নিজের নাম আর ইমেইল বসিয়ে দিতে হয়। কারণ প্রতিটি কমিটের গায়ে এই দুইটি তথ্য সিল হিসেবে বসে যায়। একবার ঠিক করে দিলে পরে আর ভাবতে হয় না।
git --version git config --global user.name "Nasirul Hoque" git config --global user.email "nasirul.hoque@example.com" git config --global init.defaultBranch main git config --list
শেষ কমান্ডটি দিলে এখন পর্যন্ত সেট করা সব মান একসাথে দেখা যায়। এখানে ইমেইলটি এমন দিন যেটি আপনার GitHub হিসাবেও যুক্ত আছে, তাহলে কমিটগুলো আপনার নামের সাথে মিলে যাবে।
একটি ফোল্ডারকে Git এর নজরে আনার নাম রিপোজিটরি তৈরি করা। এরপর কাজ চলে তিনটি ধাপে। আপনি ফাইল বদলান, তারপর কোন কোন বদল এবার সংরক্ষণ করতে চান সেগুলো আলাদা করে রাখেন, তারপর সেই দলটিকে একটি নামসহ ইতিহাসে বসিয়ে দেন।
git init git status git add index.html style.css git commit -m "প্রথম পাতার কাঠামো যোগ করা হলো" git status
ধরুন আপনি একই সময়ে একটি বাগ ঠিক করেছেন আর একটি নতুন ফিচারও শুরু করেছেন। দুইটি এক কমিটে ঢুকে গেলে পরে শুধু বাগ ঠিক করা অংশটুকু আলাদা করে ফেরত নেওয়া কঠিন হয়ে যায়। স্টেজিং এরিয়া আপনাকে বেছে নেওয়ার সুযোগ দেয়, ফলে প্রতিটি কমিট একটি করে কাজ বোঝায়।
ইতিহাস পড়তে না জানলে Git এর আসল শক্তি কাজে লাগে না। নিচের ছবিটি একটি বাস্তব প্রজেক্টের কমিট তালিকা, যেখানে প্রতিটি কমিটের সাথে লেখা আছে সেটি কোন Pull Request থেকে এসেছে এবং তার ছোট হ্যাশ কী।

কমান্ড লাইনে একই ইতিহাস আরও ছোট করে দেখা যায়। নিচের কমান্ডগুলো মুখস্থ করার দরকার নেই, কাজ করতে করতে হাতে বসে যাবে।
git log --oneline --graph --decorate -n 15 git show 6177d5f git diff HEAD~1 HEAD git blame index.html
ব্রাঞ্চ শুনতে জটিল লাগে, কিন্তু ব্যাপারটি খুব সহজ। ব্রাঞ্চ হলো ইতিহাসের একটি নির্দিষ্ট কমিটকে দেখিয়ে রাখা একটি নাম মাত্র। নতুন ব্রাঞ্চ তৈরি করলে কোনো ফাইল কপি হয় না, শুধু একটি নতুন নাম তৈরি হয়। তাই এটি প্রায় সাথে সাথেই হয়ে যায়।

ছবিতে খেয়াল করুন Behind ও Ahead নামে দুইটি ঘর আছে। Ahead মানে ওই ব্রাঞ্চে মূল ব্রাঞ্চের চেয়ে কত কমিট বেশি আছে, আর Behind মানে মূল ব্রাঞ্চে এমন কত কমিট আছে যেগুলো ওই ব্রাঞ্চ এখনো পায়নি। Behind সংখ্যাটি বড় হয়ে গেলেই কনফ্লিক্টের ঝুঁকি বাড়তে থাকে।
git switch -c feature/login git branch git switch main git merge feature/login git branch -d feature/login
নিজের কম্পিউটারের রিপোজিটরিকে GitHub এর রিপোজিটরির সাথে যুক্ত করার নাম রিমোট যোগ করা। সাধারণত এই রিমোটের নাম রাখা হয় origin। একবার যুক্ত করলে পরে শুধু পুশ আর পুল করলেই চলে।
git remote add origin https://github.com/username/project.git git remote -v git push -u origin main git switch -c feature/login git push -u origin feature/login
এখানে -u অংশটি একবারই দিতে হয়। এটি স্থানীয় ব্রাঞ্চ আর অনলাইন ব্রাঞ্চের মধ্যে একটি সম্পর্ক তৈরি করে দেয়, ফলে পরের বার শুধু পুশ লিখলেই কাজ হয়। মনে রাখবেন, পাসওয়ার্ডের বদলে এখন টোকেন লাগে, আর সেই টোকেন কখনো কোডের ভেতরে রাখবেন না।
নতুনদের সবচেয়ে বেশি গোলমাল হয় এই তিনটি শব্দ নিয়ে। তিনটিই কোড আনার কাজ করে, কিন্তু উদ্দেশ্য আলাদা।
git clone https://github.com/username/project.git cd project git pull origin main git fetch origin git log origin/main --oneline -n 5
এখানে fetch আর pull এর তফাতটিও মনে রাখার মতো। fetch শুধু খবর নিয়ে আসে, আপনার ফাইলে হাত দেয় না। pull খবর নিয়ে এসে সাথে সাথে আপনার ব্রাঞ্চে মিলিয়েও দেয়।
ব্রাঞ্চ পুশ করার পরের কাজ হলো Pull Request খোলা। এটি মূলত একটি অনুরোধ, যেখানে আপনি বলছেন আমার ব্রাঞ্চের কাজ মূল ব্রাঞ্চে নিয়ে নিন। এই পাতাটিতেই আলোচনা হয়, কোড দেখা হয় এবং অটোমেটেড পরীক্ষা চলে।

ডিফ পড়তে শিখে গেলে কোড রিভিউ আর ভয়ের বিষয় থাকে না। লাল রঙের লাইনগুলো বাদ গেছে আর সবুজ রঙের লাইনগুলো নতুন যোগ হয়েছে। উপরে নীল রঙের যে লাইনটিতে কিছু সংখ্যা থাকে, সেটি বলে দেয় ফাইলের কোন লাইন থেকে কতটুকু অংশ এখানে দেখানো হচ্ছে।

বড় প্রজেক্টে Pull Request খোলার সাথে সাথেই কিছু পরীক্ষা নিজে নিজে চলতে শুরু করে। এগুলো কোডের গঠন দেখে, পরীক্ষা চালায়, কখনো সাইটটি তৈরি করে দেখে। কোনো একটি ফেল করলে সবুজ টিকের বদলে লাল ক্রস আসে।

দুই জন যদি একই ফাইলের একই লাইনে আলাদা বদল করে, তখন Git নিজে সিদ্ধান্ত নিতে পারে না কোনটি রাখা উচিত। এই অবস্থাটিরই নাম Merge Conflict। নিচের ছবিতে দুইটি বাস্তব ব্রাঞ্চের তুলনা করা হয়েছে, আর GitHub স্পষ্ট করে বলে দিয়েছে সে নিজে মার্জ করতে পারছে না।

কনফ্লিক্ট হলে Git ওই ফাইলটির ভেতরে বিশেষ চিহ্ন বসিয়ে দেয়, যাতে আপনি দুই পক্ষের লেখা পাশাপাশি দেখতে পান। উপরের অংশটি আপনার বর্তমান ব্রাঞ্চের, আর নিচের অংশটি যে ব্রাঞ্চ মেলাতে চাইছেন তার।
<<<<<<< HEAD const shopName = "আমাদের দোকান" ======= const shopName = "আমাদের অনলাইন দোকান" >>>>>>> feature/login
কাজটি এখন সহজ। চিহ্নসহ লাইনগুলো মুছে দিয়ে যেটি রাখতে চান সেটি রাখুন, দরকার হলে দুইটি মিলিয়ে নতুন একটি লাইন লিখুন। তারপর ফাইলটি স্টেজে দিয়ে মার্জ শেষ করুন।
git merge feature/login git status git add index.html git commit -m "login ব্রাঞ্চের সাথে শিরোনামের কনফ্লিক্ট মেলানো হলো" git merge --abort
ভুল হবেই, তাই ঠিক করার উপায় জানা থাকলে সাহস বাড়ে। এখানে নিরাপদ আর ঝুঁকিপূর্ণ উপায় আলাদা করে বুঝে নেওয়া দরকার।
git restore index.html git restore --staged index.html git commit --amend -m "ঠিক করা মেসেজ" git revert 6177d5f git reset --hard HEAD~1
রিপোজিটরিতে সব ফাইল রাখতে হয় না। যেগুলো নিজে নিজেই তৈরি হয় বা যেগুলোতে গোপন তথ্য থাকে সেগুলো বাদ দিতে হয়। এর জন্য প্রজেক্টের গোড়ায় .gitignore নামের একটি ছোট ফাইল বানাতে হয়।
node_modules/ dist/ .env *.log Thumbs.db
কমান্ড জানা এক জিনিস, আর সেগুলো কোন ক্রমে চালাতে হয় সেটি আরেক জিনিস। নিচের ছোট রুটিনটি ধরে চললে দিনের শেষে ঝামেলা অনেক কমে যায়।
git switch main git pull origin main git switch -c fix/cart-total git add -A git commit -m "কার্টের যোগফলের হিসাব ঠিক করা হলো" git push -u origin fix/cart-total
Git শেখার আসল উপায় হলো একটি ছোট প্রজেক্ট নিয়ে ইচ্ছে করে ঝামেলা তৈরি করা। নিজেই দুইটি ব্রাঞ্চে একই লাইন বদলে কনফ্লিক্ট বানান, তারপর সেটি মিলিয়ে দেখুন। একবার নিজের হাতে সমাধান করলে ভয়টা একেবারে চলে যাবে।
উপরের প্রতিটি ছবি বাস্তব একটি ওপেন সোর্স প্রজেক্টের পাতা থেকে নেওয়া আসল স্ক্রিনশট, শুধু বোঝার সুবিধার জন্য আমি লাল ঘর আর বাংলা নাম বসিয়ে দিয়েছি। আপনিও যেকোনো বড় প্রজেক্টের পাতা খুলে একই জিনিসগুলো নিজের চোখে দেখতে পারেন।
আপনার কোন ধাপে আটকে যাচ্ছে তা টিউমেন্টে লিখে জানাতে পারেন। পরের টিউনে Rebase আর Cherry Pick নিয়ে হাতে কলমে আলোচনা করার ইচ্ছা আছে।
আমি নাছিরুল হক। বিশ্বের সর্ববৃহৎ বিজ্ঞান ও প্রযুক্তির সৌশল নেটওয়ার্ক - টেকটিউনস এ আমি 2 দিন 9 ঘন্টা যাবৎ যুক্ত আছি। টেকটিউনস আমি এ পর্যন্ত 13 টি টিউন ও 0 টি টিউমেন্ট করেছি। টেকটিউনসে আমার 0 ফলোয়ার আছে এবং আমি টেকটিউনসে 0 টিউনারকে ফলো করি।
আমি নাছিরুল হক। প্রোগ্রামিং আর প্রযুক্তি নিয়ে ঘাঁটাঘাঁটি করতে ভালোবাসি। টেকটিউনসে মূলত Java প্রোগ্রামিং নিয়ে ধাপে ধাপে হাতে কলমে টিউটোরিয়াল লিখি — JDK ইনস্টল ও এনভায়রনমেন্ট সেটআপ থেকে শুরু করে IntelliJ IDEA, Exception Handling, OOP, Java Swing ও ফাইল হ্যান্ডলিং পর্যন্ত। এছাড়া স্মার্টফোন, ব্যাটারি ও নেটওয়ার্ক নিয়ে সহজ ভাষায় ব্যাখ্যামূলক...