ভূমিকা

প্রোগ্রামিং বা সফটওয়্যার ইঞ্জিনিয়ারিংয়ের জগতে Git এবং GitHub হলো অক্সিজেন। এটি ছাড়া টিম ওয়ার্ক এবং কোড ম্যানেজমেন্ট প্রায় অসম্ভব। আমরা অনেকেই গিট এর বেসিক কমান্ডগুলো জানি, কিন্তু অ্যাডভান্সড ফিচারগুলো কিভাবে কাজ করে বা গিটের ভেতরে আসলে কী হয়, তা অনেক সময় অজানা থেকে যায়। চলুন খুব সহজ ভাষায়, বিস্তারিত এবং ভিজ্যুয়ালের সাহায্যে গিট এবং গিটহাবের বেসিক থেকে অ্যাডভান্সড সবকিছু বুঝে নিই।


১. Git কী এবং কেন প্রয়োজন?

Git হলো একটি Distributed Version Control System (VCS)। সহজ ভাষায়, এটি আপনার প্রজেক্টের কোডের একটি টাইমমেশিন। আপনি কখন, কোথায়, কী কোড লিখেছেন, কোন লাইনে পরিবর্তন করেছেন, তার পুরো হিস্ট্রি গিট মনে রাখে। যদি কোনো কারণে কোড নষ্ট হয়ে যায় বা ভুল কোড লেখা হয়, আপনি চাইলেই আগের ভার্সনে ফিরে যেতে পারবেন। গিটের ডিস্ট্রিবিউটেড হওয়ার অর্থ হলো, টিমের সবার কাছেই প্রজেক্টের পুরো হিস্ট্রি বা রিপোজিটরি থাকে।

২. GitHub কী?

Git হলো আপনার কম্পিউটারের লোকাল সফটওয়্যার, আর GitHub হলো ক্লাউড স্টোরেজ (যেমন Google Drive বা Dropbox) যেখানে আপনি আপনার গিট রিপোজিটরি (প্রজেক্ট) অনলাইনে হোস্ট করে রাখতে পারেন। এটি টিম কোলাবোরেশন বা অন্যদের সাথে প্রজেক্টে কাজ করার সুবিধা দেয়।


৩. Git এর ইন্টারনালস: ভেতরে কীভাবে কাজ করে? (Blobs, Trees, Commits)

গিট আসলে শুধু ফাইল সেভ করে না, এটি ফাইলের অবস্থার স্ন্যাপশট (Snapshot) তৈরি করে। গিটের ভেতরে মূলত তিনটি প্রধান অবজেক্ট থাকে:

  1. Blob (Binary Large Object): এটি হলো আপনার ফাইলের কন্টেন্ট। গিট ফাইলের নাম মনে রাখে না, বরং ফাইলের কন্টেন্টের ওপর ভিত্তি করে একটি SHA-1 হ্যাশ তৈরি করে এবং সেই হ্যাশের সাহায্যে কন্টেন্ট সেভ করে।
  2. Tree: ট্রি অবজেক্ট হলো ডিরেক্টরি বা ফোল্ডারের মতো। এটি বিভিন্ন Blob এবং অন্যান্য Tree এর রেফারেন্স বা লিঙ্ক সংরক্ষণ করে। এতে ফাইলের নাম এবং পারমিশন থাকে।
  3. Commit: কমিট অবজেক্ট একটি নির্দিষ্ট Tree কে পয়েন্ট করে। পাশাপাশি এটিতে মেটাডেটা থাকে, যেমন: কমিট মেসেজ, অথারের নাম, সময় এবং আগের কমিটের (Parent Commit) রেফারেন্স।
Commit (Hash: 9f4d...)
│
├── Tree (Directory)
│   ├── Blob (index.html)
│   ├── Blob (style.css)
│   └── Tree (assets/)
│       └── Blob (logo.png)

এই স্ট্রাকচারের কারণেই গিট এত দ্রুত কাজ করতে পারে।


৪. Git এর প্রধান ৪টি স্টেজ (Visual Workflow)

আপনার কোড গিটহাবে পৌঁছানোর আগে সাধারণত ৪টি স্টেপ পার করে:

 💻 Working Directory   👉   📦 Staging Area   👉   🏠 Local Repository   👉   ☁️ Remote (GitHub)
     (আপনার পিসি)              (প্রস্তুতি)                 (কমিট)                    (পুশ)
         │                         │                          │                         │
         ├──── git add ───────────>│                          │                         │
         │                         ├───── git commit ────────>│                         │
         │                         │                          ├───── git push ─────────>│

স্টেপগুলো বিস্তারিত:

  1. Working Directory: আপনি ভিএস কোডে (VS Code) বা এডিটরে যে ফাইলগুলো নিয়ে কাজ করছেন। এটি আপনার রানিং প্রজেক্ট ফোল্ডার।
  2. Staging Area (git add): আপনার কোড কমিট করার আগে একটি নির্দিষ্ট জায়গায় জমা হয়। এটি একটি চেকপয়েন্ট। আপনি চাইলে কিছু ফাইল কমিট না করে শুধু নির্দিষ্ট ফাইল স্টেজ করতে পারেন।
  3. Local Repository (git commit): কোডের একটি পার্মানেন্ট স্ন্যাপশট আপনার পিসিতে সেভ হলো। এখন গিট আপনার পরিবর্তনটি ট্র্যাকিংয়ে রেখেছে।
  4. Remote Repository (git push): পিসির লোকাল রিপোজিটরি ইন্টারনেটে (GitHub/GitLab) আপলোড করা হলো, যাতে টিমের অন্য সদস্যরাও তা দেখতে পারে।

৫. দরকারি কমান্ডসমূহ (Basics)

🔹 প্রজেক্ট শুরু করা (Initialize)

নতুন প্রজেক্টে গিট চালু করতে:

git init

এটি একটি গোপন .git ফোল্ডার তৈরি করবে, যেখানে গিট তার সকল ডেটা সেভ করে।

🔹 কোড স্টেজিং এরিয়ায় নেওয়া

git add index.html  # একটি ফাইল অ্যাড করতে
git add .           # ফোল্ডারের সব ফাইল অ্যাড করতে

🔹 কোড সেভ করা (Commit)

git commit -m "Added index.html and style.css"

🔹 বর্তমান অবস্থা চেক করা

git status

🔹 হিস্ট্রি দেখা

git log
git log --oneline  # সংক্ষেপে দেখতে

৬. ব্রাঞ্চিং (Branching)

ব্রাঞ্চিং হলো গিটের সবচেয়ে পাওয়ারফুল ফিচার। ধরুন, আপনার একটি রানিং প্রজেক্ট বা ওয়েবসাইট আছে। আপনি নতুন একটি ফিচার বানাতে চান কিন্তু মেইন কোড নষ্ট করতে চান না। তখন আপনি একটি নতুন 'Branch' তৈরি করে কাজ করবেন।

(main)           A ─── B ─── C ─── F (merge)
                              \   /
(new-feature)                  D ─ E

ব্রাঞ্চ কমান্ডসমূহ:

git branch              # সব ব্রাঞ্চ দেখতে
git branch feature-x    # নতুন ব্রাঞ্চ খুলতে
git checkout feature-x  # নতুন ব্রাঞ্চে যেতে (পুরানো কমান্ড)
git switch feature-x    # নতুন ব্রাঞ্চে যেতে (নতুন কমান্ড)

# শর্টকাট (ব্রাঞ্চ তৈরি এবং যাওয়া):
git checkout -b feature-x
# বা
git switch -c feature-x

৭. Merging vs Rebasing (মার্জিং বনাম রিবেসিং)

দুটি ব্রাঞ্চের কোড একসাথে মেলানোর দুটি উপায় আছে: Merge এবং Rebase।

🔹 Merge (মার্জ):

মার্জ করলে দুটি ব্রাঞ্চের হিস্ট্রি একত্রিত হয় এবং একটি নতুন "Merge Commit" তৈরি হয়।

  • সুবিধা: হিস্ট্রি সম্পূর্ণ অটুট থাকে। কবে কোন ব্রাঞ্চ তৈরি হয়েছিল তা দেখা যায়।
  • অসুবিধা: হিস্ট্রি অনেক সময় জগাখিচুড়ি বা খুব জটিল মনে হতে পারে।
git switch main
git merge feature-x

🔹 Rebase (রিবেস):

রিবেস করলে আপনার ব্রাঞ্চের বেস (Base) পরিবর্তন হয়ে যায়। অর্থাৎ, মনে হবে যেন আপনি মেইন ব্রাঞ্চের সর্বশেষ কমিটের পরেই আপনার ফিচার ব্রাঞ্চের কাজ শুরু করেছেন।

  • সুবিধা: হিস্ট্রি একদম লিনিয়ার এবং সোজা থাকে (Linear History)। কোনো এক্সট্রা Merge Commit তৈরি হয় কনফ্লিক্ট দেখা গেলে তা সমাধান করে রিবেস সম্পূর্ণ করতে হয়।
  • অসুবিধা: পাবলিক ব্রাঞ্চে রিবেস করলে কনফ্লিক্ট এবং হিস্ট্রি হারানোর ঝুঁকি থাকে।
git switch feature-x
git rebase main

টিপস: নিজের লোকাল ব্রাঞ্চে Rebase ব্যবহার করুন, আর টিমের সাথে শেয়ার করা ব্রাঞ্চে Merge ব্যবহার করুন।


৮. Merge Conflicts সমাধান (Resolving Merge Conflicts)

কখনো কখনো দুটি ব্রাঞ্চ মার্জ করার সময় গিট কনফিউজড হয়ে যায়। ধরুন, main ব্রাঞ্চে এক ব্যক্তি index.html এর ১০ নাম্বার লাইন পরিবর্তন করেছে, আবার feature-x ব্রাঞ্চেও অন্য ব্যক্তি একই লাইনে অন্য কিছু লিখেছে। তখন গিট কার কোড রাখবে তা বুঝতে না পেরে Conflict তৈরি করে।

কনফ্লিক্ট দেখতে কেমন হয়?

<<<<<<< HEAD
<h1>Welcome to My Website</h1>
=======
<h1>Welcome to Our Awesome App</h1>
>>>>>>> feature-x

কনফ্লিক্ট সমাধানের উপায়:

  1. কোড এডিটরে (যেমন VS Code) কনফ্লিক্ট হওয়া ফাইলটি খুলুন।
  2. গিট আপনাকে Accept Current Change, Accept Incoming Change, অথবা Accept Both Changes অপশন দিবে।
  3. আপনি যেটা রাখতে চান সেটা সিলেক্ট করুন অথবা ম্যানুয়ালি কোড এডিট করে ঠিক করুন।
  4. এরপর ফাইল সেভ করে নিচের কমান্ডগুলো দিন:
git add index.html
git commit -m "Resolved merge conflict in index.html"

ব্যাস! কনফ্লিক্ট সমাধান হয়ে গেল।


৯. Stash (স্ট্যাশ)

ধরুন, আপনি একটি ব্রাঞ্চে কাজ করছেন কিন্তু কাজ অর্ধেক হওয়া অবস্থায় আপনাকে জরুরি অন্য একটি ব্রাঞ্চে যেতে হবে। আপনি অর্ধেক কাজ কমিট করতে চান না, কারণ সেটি এখনো অসম্পূর্ণ। তখন git stash আপনাকে বাঁচিয়ে দিতে পারে। এটি আপনার অসম্পূর্ণ কাজগুলোকে একটি অস্থায়ী জায়গায় লুকিয়ে রাখে।

# কাজ লুকিয়ে রাখতে:
git stash

# লুকিয়ে রাখা কাজের লিস্ট দেখতে:
git stash list

# লুকিয়ে রাখা কাজ পুনরায় ফেরত আনতে (এবং স্ট্যাশ থেকে মুছে ফেলতে):
git stash pop

# লুকিয়ে রাখা কাজ ফেরত আনতে (কিন্তু স্ট্যাশ লিস্টে রেখে দিতে):
git stash apply

১০. Cherry-Pick (চেরি-পিক)

কখনো কখনো আপনাকে অন্য একটি ব্রাঞ্চের পুরো কোড মার্জ করতে হয় না, বরং ওই ব্রাঞ্চের নির্দিষ্ট একটি Commit দরকার হয়। এই কাজটি করার জন্য cherry-pick ব্যবহার করা হয়।

main:    A --- B --- C --- D
feature:       \ --- X --- Y --- Z

ধরুন, আপনি শুধু Y কমিটটি main ব্রাঞ্চে আনতে চান।

git switch main
git cherry-pick <commit-hash-of-Y>

এতে করে শুধু Y এর পরিবর্তনগুলো আপনার বর্তমান ব্রাঞ্চে যুক্ত হয়ে যাবে এবং একটি নতুন কমিট তৈরি হবে।


১১. Pull Request (PR) Workflow

ওপেন সোর্স প্রোজেক্ট বা কোম্পানিতে কাজ করার সময় সরাসরি main ব্রাঞ্চে পুশ করা হয় না। এর বদলে একটি নির্দিষ্ট প্রসেস ফলো করা হয়:

  1. Fork / Branch: মেইন প্রজেক্ট ফর্ক করুন (ওপেন সোর্সের ক্ষেত্রে) অথবা নতুন একটি ব্রাঞ্চ খুলুন।
  2. Work & Commit: আপনার নতুন ফিচারের কাজ করুন এবং কোড কমিট করুন।
  3. Push: আপনার ব্রাঞ্চটি রিমোট গিটহাবে পুশ করুন।
  4. Create Pull Request (PR): গিটহাবে গিয়ে main ব্রাঞ্চের সাথে আপনার ব্রাঞ্চটি মার্জ করার রিকোয়েস্ট বা আবেদন করুন।
  5. Code Review: টিমের অন্য সদস্যরা বা সিনিয়র ডেভেলপাররা আপনার কোড রিভিউ করবে, ভুল থাকলে তা কমেন্ট করে জানাবে।
  6. Merge: সবকিছু ঠিক থাকলে এবং টেস্ট পাস করলে প্রোজেক্ট মেইনটেইনার আপনার PR টি মার্জ করে নিবেন।

১২. GitHub Actions এবং CI/CD Basics

GitHub Actions হলো গিটহাবের একটি ফিচার যার মাধ্যমে আপনি আপনার প্রোজেক্টের বিভিন্ন কাজ অটোমেট করতে পারেন। একে সফটওয়্যার ডেভেলপমেন্টের ভাষায় Continuous Integration and Continuous Deployment (CI/CD) বলা হয়।

ধরুন, আপনি চান কেউ যখনই আপনার গিটহাবে কোড পুশ করবে বা PR তৈরি করবে, তখন অটোমেটিকভাবে:

  • কোডের টেস্টিং (Unit tests, Integration tests) রান হবে।
  • কোডে লিন্টার (Linter) চেক হবে।
  • টেস্ট পাস করলে কোডটি অটোমেটিক লাইভ সার্ভারে ডেপ্লয় (Deploy) হবে।

এই কাজগুলো গিটহাব অ্যাকশনস দিয়ে খুব সহজেই করা সম্ভব। এর জন্য প্রজেক্টের রুট ডিরেক্টরিতে .github/workflows/ ফোল্ডার তৈরি করে একটি .yml (YAML) ফাইল লিখতে হয়।

সাধারণ একটি CI/CD Workflow উদাহরণ:

name: Node.js CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18.x'
    - run: npm install
    - run: npm test

এই স্ক্রিপ্টটি বলে দিচ্ছে যে, যখনই main ব্রাঞ্চে কোড পুশ হবে বা কোনো পুল রিকোয়েস্ট আসবে, তখন একটি উবুন্টু সার্ভার চালু হবে, নোডজেএস ইনস্টল হবে, ডিপেন্ডেন্সি ইনস্টল হবে এবং অটোমেটিকভাবে npm test রান করবে। যদি টেস্ট ফেইল করে, তবে গিটহাব ওই পুশ বা PR কে রেড মার্ক করে দিবে।


উপসংহার

Git এবং GitHub আধুনিক সফটওয়্যার ডেভেলপমেন্টের অবিচ্ছেদ্য অংশ। শুধু অ্যাড, কমিট আর পুশ জানলেই কাজ চলে যায়, তবে Rebase, Stash, Cherry-Pick, Conflict Resolution, এবং GitHub Actions এর মতো অ্যাডভান্সড ফিচারগুলো জানা থাকলে আপনি একজন প্রো-ডেভেলপারে পরিণত হবেন। এই টুলগুলো টিমের সাথে কাজ করার সময় আপনাকে অনেক বাঁচিয়ে দিবে। শুরুতে একটু জটিল মনে হলেও, প্রতিদিন ব্যবহার করলে এগুলো আপনার আয়ত্তে চলে আসবে। হ্যাপি কোডিং!