Git হল একটি ওপেন সোর্স ডিস্ট্রিবিউটেড ভার্সন কন্ট্রোল সিস্টেম, যা লিনাস টরভাল্ডস ২০০৫ সালে লিনাক্স কার্নেল ডেভেলপমেন্টের জন্য তৈরি করেছিলেন। SVN-এর মতো সেন্ট্রালাইজড সিস্টেমের বিপরীতে, Git ডেভেলপারের প্রতিটি ডিভাইসে রিপোজিটরির একটি সম্পূর্ণ কপি সংরক্ষণ করে, যা সার্ভারের সাথে ধ্রুবক সংযোগ ছাড়াই কাজ করতে দেয়। Git SCM, 2024 অনুসারে, Git সমস্ত বাণিজ্যিক সফটওয়্যার ডেভেলপমেন্ট প্রকল্পের 90% এরও বেশি ব্যবহৃত হয়।
মূল বিষয়
Git হল একটি ডিস্ট্রিবিউটেড ভার্সন কন্ট্রোল সিস্টেম (VCS) যা ফাইলের পরিবর্তন ট্র্যাক করে এবং একাধিক ডেভেলপারকে একই প্রকল্পে একসাথে কাজ করতে দেয়। সেন্ট্রালাইজড সিস্টেমের বিপরীতে, Git-এ প্রতিটি ডেভেলপারের কাছে সম্পূর্ণ পরিবর্তনের ইতিহাসসহ রিপোজিটরির একটি সম্পূর্ণ কপি থাকে, যা সিস্টেমকে ডেটা ক্ষতির জন্য প্রতিরোধী করে তোলে এবং একটি কেন্দ্রীয় সার্ভারের সাথে ধ্রুবক সংযোগের প্রয়োজন হয় না।
Git-এর ইতিহাস শুরু হয়েছিল ২০০৫ সালে, যখন লিনাস টরভাল্ডস BitKeeper লিনাক্স কার্নেল ডেভেলপারদের জন্য তার বিনামূল্যের লাইসেন্স প্রত্যাহার করার পরে একটি নতুন VCS তৈরি করেছিলেন। লক্ষ্যগুলি ছিল: গতি, আর্কিটেকচারের সরলতা, ব্রাঞ্চিংয়ের মাধ্যমে অ-রৈখিক ডেভেলপমেন্টের সমর্থন এবং সম্পূর্ণ বিতরণ। ৩ মাসের মধ্যে টরভাল্ডস Git-এর কার্নেল লিখেছিলেন, এবং এক বছরের মধ্যে প্রকল্পটি জুনিও হামানোর নেতৃত্বে স্ব-পরিচালিত হয়।
Stack Overflow জরিপ (2024) অনুসারে, Git 93.9% পেশাদার ডেভেলপার ব্যবহার করেন, যা এটিকে শিল্পে প্রভাবশালী ভার্সন কন্ট্রোল সিস্টেমে পরিণত করেছে। নিকটতম প্রতিযোগী — Subversion (SVN) — শুধুমাত্র 5.2% প্রকল্পে ব্যবহৃত হয়, প্রধানত কেন্দ্রীভূত প্রক্রিয়া সহ বৃহৎ কর্পোরেট পরিবেশে।
Git রিপোজিটরি হল একটি ডিরেক্টরি যেখানে Git সমস্ত ফাইলের পরিবর্তন ট্র্যাক করে। ডিরেক্টরির ভিতরে একটি লুকানো ফোল্ডার .git রয়েছে যা সমস্ত সিস্টেম অবজেক্ট সংরক্ষণ করে: কমিট, ট্রি, ব্লব এবং রেফারেন্স। যখন একজন ডেভেলপার একটি কমিট তৈরি করেন, Git ফাইলগুলি সম্পূর্ণভাবে কপি করে না — এটি একটি স্ন্যাপশট তৈরি করে এবং এটির একটি রেফারেন্স সংরক্ষণ করে।
প্রতিটি কমিট ধারণ করে: একটি অনন্য SHA-1 হ্যাশ (৪০ অক্ষর), পূর্ববর্তী কমিটের রেফারেন্স (parent), লেখক, তারিখ, কমিট বার্তা এবং একটি ট্রির রেফারেন্স যা কমিটের সময় ফাইলের অবস্থা বর্ণনা করে। কমিটের চেইন একটি নির্দেশিত অ্যাসাইক্লিক গ্রাফ গঠন করে যেখানে প্রতিটি কমিট এক বা একাধিক প্যারেন্টের দিকে নির্দেশ করে।
# রিপোজিটরি আরম্ভ
git init my-project
cd my-project
# কমিট তৈরি
echo "হ্যালো, Git" > README.md
git add README.md
git commit -m "Initial commit"
# ইতিহাস দেখা
git log --oneline --graph --all
Git তিনটি প্রধান এলাকা ব্যবহার করে: working directory (ডিস্কে ফাইল), staging area (ইনডেক্স যেখানে প্রস্তুত ফাইল যায়) এবং repository (কমিট ইতিহাস)। git add কমান্ড ওয়ার্কিং ডিরেক্টরি থেকে স্টেজিং-এ পরিবর্তন স্থানান্তর করে, এবং git commit স্টেজিং-এর বিষয়বস্তু রিপোজিটরিতে রেকর্ড করে। এই বিভাজন ডেভেলপারকে প্রতিটি সম্পাদনা আলাদাভাবে কমিট না করেই পরিবর্তনের সেট থেকে একটি অর্থপূর্ণ কমিট একত্রিত করতে দেয়।
Git-এর মৌলিক কমান্ড একজন ডেভেলপারের দৈনন্দিন কাজের 90% কভার করে। git clone কমান্ড একটি রিমোট রিপোজিটরির স্থানীয় কপি তৈরি করে, git pull সার্ভার থেকে পরিবর্তন এনে বর্তমান ব্রাঞ্চের সাথে মার্জ করে, এবং git push স্থানীয় কমিট সার্ভারে পাঠায়। এই তিনটি কমান্ড Git-এর সাথে কাজের প্রধান চক্র গঠন করে।
অবস্থা দেখতে git status ব্যবহার করা হয় — এটি দেখায় কোন ফাইলগুলি পরিবর্তিত হয়েছে, কোনটি স্টেজিং-এ যোগ করা হয়েছে এবং কোনটি ট্র্যাক করা হচ্ছে না। git diff স্টেজিং-এ যোগ করার আগে ফাইলগুলিতে নির্দিষ্ট পরিবর্তন প্রদর্শন করে। নীচে সবচেয়ে বেশি ব্যবহৃত কমান্ডগুলির একটি টেবিল দেওয়া হল:
| কমান্ড | কাজ | উদাহরণ |
|---|---|---|
| git clone | রিমোট রিপোজিটরি কপি করে | git clone https://example.com/repo |
| git add | স্টেজিং-এ ফাইল যোগ করে | git add src/main.kt |
| git commit | ইতিহাসে পরিবর্তন রেকর্ড করে | git commit -m “লগইন বাগ ঠিক করুন” |
| git push | সার্ভারে কমিট পাঠায় | git push origin main |
| git pull | সার্ভার থেকে পরিবর্তন আনে | git pull origin feature |
পরিবর্তন পূর্বাবস্থায় ফেরাতে, Git বেশ কয়েকটি বিকল্প সরবরাহ করে। git reset ব্রাঞ্চ পয়েন্টারকে নির্দিষ্ট কমিটে নিয়ে যায় এবং স্টেজিং বা ওয়ার্কিং ডিরেক্টরি রিসেট করতে পারে। git revert একটি নতুন কমিট তৈরি করে যা নির্দিষ্ট কমিটের পরিবর্তনগুলি পূর্বাবস্থায় ফেরায় — এটি শেয়ার্ড ব্রাঞ্চের জন্য পূর্বাবস্থায় ফেরানোর একটি নিরাপদ উপায় কারণ ইতিহাস পুনরায় লেখা হয় না।
Git-এ ব্রাঞ্চ হল একটি নির্দিষ্ট কমিটের দিকে হালকা চলমান পয়েন্টার। একটি নতুন ব্রাঞ্চ তৈরি করা ফাইল কপি করে না, বরং শুধুমাত্র একটি নতুন পয়েন্টার তৈরি করে, যা ব্রাঞ্চিংকে প্রায় তাৎক্ষণিক করে তোলে। main ব্রাঞ্চ (পূর্বে master) প্রকল্পের প্রধান ব্রাঞ্চ যা স্থিতিশীল, রিলিজ-রেডি কোড ধারণ করে।
মানক অনুশীলন হল Git Flow বা GitHub Flow ব্যবহার করা। Git Flow ব্রাঞ্চ ব্যবহার করে: main (রিলিজ কোড), develop(ইন্টিগ্রেশন ব্রাঞ্চ), feature/* (নতুন ফিচার), release/*(রিলিজ প্রস্তুতি) এবং hotfix/* (জরুরি সংশোধন)। GitHub Flow সহজ: শুধুমাত্র main এবং ফিচার ব্রাঞ্চ, এবং সমস্ত পরিবর্তন Pull Request-এর মাধ্যমে বিতরণ করা হয়।
# ব্রাঞ্চ তৈরি এবং স্যুইচ করা
git branch feature-auth
git checkout feature-auth
# অথবা একটি কমান্ড দিয়ে:
git checkout -b feature-auth
# ব্রাঞ্চের তালিকা
git branch --list
git branch -a # সব ব্রাঞ্চ, মুছে ফেলা সহ
# ব্রাঞ্চ মুছে ফেলা
git branch -d feature-auth
Git ব্রাঞ্চিং-এর একটি গুরুত্বপূর্ণ বৈশিষ্ট্য হল cherry-pick: git cherry-pick <hash> কমান্ড ব্যবহার করে একটি পৃথক কমিট এক ব্রাঞ্চ থেকে অন্যটিতে সরানো। এটি উপযোগী যখন আপনাকে সম্পূর্ণ ব্রাঞ্চ মার্জ না করে একটি ফিচার ব্রাঞ্চ থেকে রিলিজে বাগ ফিক্স স্থানান্তর করতে হবে। Git কমিট স্কোয়াশ, পুনর্বিন্যাস এবং সম্পাদনার জন্য রিবেস এবং ইন্টারঅ্যাকটিভ রিবেস (git rebase -i) সমর্থন করে।
Merge (মার্জ) একটি বিশেষ মার্জ কমিট তৈরি করে যার দুটি প্যারেন্ট থাকে। এই কমিট দুটি ব্রাঞ্চের একীভূত হওয়ার ঘটনা রেকর্ড করে এবং সম্পূর্ণ ইতিহাস সংরক্ষণ করে — দেখা যায় কোথায় এবং কখন মার্জ হয়েছিল। Merge ইতিহাসকে যেমন তৈরি করা হয়েছিল তেমনই সংরক্ষণ করে, যা অডিট সহজ করে কিন্তু কমিট গ্রাফকে আরও জটিল করে তোলে।
Rebase (রিবেস) মার্জ কমিট তৈরি করার পরিবর্তে বর্তমান ব্রাঞ্চের কমিটগুলিকে লক্ষ্য ব্রাঞ্চের শীর্ষে স্থানান্তর করে। ইতিহাস রৈখিক হয়ে যায় — ধারণা তৈরি করে যে ডেভেলপমেন্ট ক্রমিক ছিল। তবে, রিবেস ইতিহাস পুনরায় লেখে, কমিটের SHA-1 হ্যাশ পরিবর্তন করে, যা এটিকে শেয়ার্ড ব্রাঞ্চের জন্য বিপজ্জনক করে তোলে যেখানে অন্যান্য ডেভেলপারদের অ্যাক্সেস রয়েছে।
সুপারিশ: পাবলিক ব্রাঞ্চের জন্য merge ব্যবহার করুন যেখানে ইতিহাস অন্যান্য ডেভেলপারদের কাছে দৃশ্যমান (feature → develop), এবং স্থানীয় কাজের জন্য rebase ব্যবহার করুন যখন আপনি Pull Request তৈরি করার আগে আপনার ফিচার ব্রাঞ্চে main থেকে নতুন পরিবর্তন প্রয়োগ করতে চান। নিয়মটি সহজ: যদি একটি কমিট ইতিমধ্যে সার্ভারে পুশ করা হয়ে থাকে — তবে এটি রিবেস করবেন না।
মার্জ দ্বন্দ্ব ঘটে যখন Git একটি ফাইলের পরিবর্তনগুলি স্বয়ংক্রিয়ভাবে মার্জ করতে পারে না। Git ফাইলে দ্বন্দ্বযুক্ত বিভাগগুলি বিশেষ মার্কার দিয়ে চিহ্নিত করে: <<<<<<< (আমাদের পরিবর্তন), ======= (বিভাজক), >>>>>>> (তাদের পরিবর্তন)। ডেভেলপার ম্যানুয়ালি ফাইলটি সম্পাদনা করে, পছন্দসই বিকল্প বেছে নেয় বা উভয়কে একত্রিত করে, এবং একটি কমিটের মাধ্যমে মার্জ সম্পূর্ণ করে।
রিমোট রিপোজিটরি (remote) হল সার্ভারে অবস্থিত একটি Git রিপোজিটরির কপি। GitHub, GitLab এবং Bitbucket রিমোট রিপোজিটরি হোস্টিংয়ের জন্য সবচেয়ে জনপ্রিয় প্ল্যাটফর্ম। তারা কোড দেখার, অ্যাক্সেস ব্যবস্থাপনা, কোড রিভিউ এবং CI/CD সিস্টেমের সাথে ইন্টিগ্রেশনের জন্য ওয়েব ইন্টারফেস সরবরাহ করে।
Git-এ, আপনি একটি প্রকল্পের জন্য একাধিক রিমোট রিপোজিটরি কনফিগার করতে পারেন। ডিফল্টরূপে, প্রধান রিমোটকে origin বলা হয়। git remote add কমান্ড একটি নতুন রিমোট যোগ করে, git fetch মার্জ না করেই পরিবর্তন আনে, এবং git pull হল git fetch + git merge-এর সংক্ষিপ্ত রূপ। Pull Request-এর মাধ্যমে কোড নিয়ে কাজ করতে, একজন ডেভেলপার রিপোজিটরির একটি ফর্ক তৈরি করে, এটি ক্লোন করে, একটি ফিচার ব্রাঞ্চে কাজ করে এবং মূল রিপোজিটরিতে একটি মার্জ অনুরোধ পাঠায়।
# রিমোট রিপোজিটরি যোগ করা
git remote add origin https://github.com/user/repo.git
# রিমোট রিপোজিটরি দেখা
git remote -v
# সার্ভারে ব্রাঞ্চ পাঠানো
git push -u origin feature-auth
# রিমোট ব্রাঞ্চ থেকে পরিবর্তন আনা
git pull origin main
রিমোট রিপোজিটরি রিলিজ ভার্সন চিহ্নিত করার জন্য ট্যাগিং সমর্থন করে। ট্যাগ হালকা (শুধু একটি কমিটের দিকে পয়েন্টার) বা অ্যানোটেটেড (মেটাডেটা ধারণ করে: লেখক, তারিখ, বার্তা) হতে পারে। রিলিজ ভার্সনের জন্য অ্যানোটেটেড ট্যাগ সুপারিশ করা হয় কারণ তারা সম্পূর্ণ ভার্সন তথ্য বহন করে এবং লেখকত্বের যাচাইকরণের জন্য GPG কী দিয়ে স্বাক্ষর করা যেতে পারে।
Git Worktree আপনাকে বিভিন্ন ডিরেক্টরিতে একসাথে একাধিক ব্রাঞ্চ নিয়ে কাজ করতে দেয় সেগুলির মধ্যে স্যুইচ না করেই। git worktree add ../feature-auth feature-auth কমান্ড একটি নতুন ওয়ার্কিং ডিরেক্টরি feature-auth তৈরি করে যেখানে আপনি প্রধান ডিরেক্টরিতে ব্রাঞ্চ স্যুইচ না করেই কোড লিখতে পারেন। Worktree রিলিজ ব্রাঞ্চে দ্রুত ফিক্সের জন্য উপযোগী যখন প্রধান ডিরেক্টরি দীর্ঘমেয়াদী ডেভেলপমেন্টে ব্যস্ত থাকে।
Git Submodules হল একটি Git রিপোজিটরিকে অন্যটির ভিতরে অন্তর্ভুক্ত করার একটি পদ্ধতি। Submodule একটি বাহ্যিক রিপোজিটরির একটি নির্দিষ্ট কমিটের রেফারেন্স সংরক্ষণ করে, যা বিল্ড পুনরুৎপাদনযোগ্যতা নিশ্চিত করে। git submodule add https://github.com/example/lib.git কমান্ড একটি বাহ্যিক লাইব্রেরিকে সাবমডিউল হিসেবে যোগ করে। সাবমডিউল সহ একটি প্রকল্প ক্লোন করার সময়, সমস্ত নির্ভরতা ডাউনলোড করতে git submodule update --init --recursive চালানো প্রয়োজন।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Git হল একটি ডিস্ট্রিবিউটেড VCS যার স্থানীয় ইতিহাস এবং অফলাইনে কাজ করার ক্ষমতা রয়েছে। SVN হল একটি কেন্দ্রীভূত সিস্টেম যার ফাইল দেখানো ছাড়া যেকোনো কাজের জন্য সার্ভারের সাথে ধ্রুবক সংযোগ প্রয়োজন।
নিরাপদ পূর্বাবস্থায় ফেরানোর জন্য git revert HEAD ব্যবহার করুন (একটি নতুন কমিট তৈরি করে)। যদি কমিটটি এখনও সার্ভারে পুশ না করা হয়ে থাকে, আপনি git reset --soft HEAD~1 ব্যবহার করতে পারেন।
.gitignore হল একটি ফাইল যা ফাইল এবং ডিরেক্টরির প্যাটার্ন তালিকাভুক্ত করে যা Git উপেক্ষা করবে। এটি অস্থায়ী ফাইল, বিল্ড এবং IDE কনফিগারেশন রিপোজিটরি থেকে বাদ দিতে ব্যবহৃত হয়।
git fetch সার্ভার থেকে পরিবর্তন ডাউনলোড করে কিন্তু সেগুলি বর্তমান ব্রাঞ্চের সাথে মার্জ করে না। git pull fetch করে এবং সাথে সাথে মার্জ সম্পাদন করে। নিয়ন্ত্রণের জন্য, fetch + diff রিভিউ ব্যবহার করুন, তারপর ম্যানুয়ালি মার্জ করুন।
git commit --amend ব্যবহার করুন — এই কমান্ড কমিট বার্তা পরিবর্তনের জন্য একটি এডিটর খোলে। যদি কমিটটি ইতিমধ্যে সার্ভারে থাকে, তাহলে আপনার git push --force প্রয়োজন হবে, যা শেয়ার্ড ব্রাঞ্চের জন্য বিপজ্জনক।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন