গাইড

git add ও git commit: পরিবর্তন সংরক্ষণের সঠিক উপায়

হালনাগাদ: · Skillaria.Top

Git-এ পরিবর্তন সংরক্ষণ হয় দুই ধাপে: git add প্রয়োজনীয় সম্পাদনা ইনডেক্সে (staging area) যোগ করে, আর git commit -m "বার্তা" সেগুলো একটি স্ন্যাপশট হিসেবে ইতিহাসে লেখে। git status দেখায় কী বদলেছে এবং কী প্রস্তুত। শেষ কমিট ঠিক করতে git commit --amend ব্যবহার করুন।

Git-এ "সেভ" বোতাম নেই। পরিবর্তন দুই ধাপে লেখা হয়: প্রথমে git add ঠিক করে দেয় পরের স্ন্যাপশটে কোন সম্পাদনাগুলো যাবে, তারপর git commit সেই স্ন্যাপশটটি ইতিহাসে লিখে দেয়। এ দুইয়ের মাঝের স্তরটিকে বলা হয় ইনডেক্স, বা staging area। অনেকেই বছরের পর বছর এটি ঠিকভাবে বোঝেন না, অথচ এই স্তরটিই কমিটগুলোকে অর্থবহ করে।

ফাইলের তিনটি অবস্থা: ওয়ার্কিং ফোল্ডার, ইনডেক্স, ইতিহাস

যেকোনো পরিবর্তন তিনটি জায়গা দিয়ে যায়:

  1. ওয়ার্কিং ডিরেক্টরি — আপনি এডিটরে ফাইল সম্পাদনা করেন।
  2. ইনডেক্স (stage) — git add ফাইলের বর্তমান সংস্করণ পরের কমিটের খসড়ায় রাখে।
  3. ইতিহাস — git commit ইনডেক্সের বিষয়বস্তুকে লেখক, তারিখ ও বার্তাসহ একটি কমিটে পরিণত করে।

একটি সহজ উপমা হলো প্যাকেজ। ওয়ার্কিং ফোল্ডার হলো জিনিসপত্রে ভরা ঘর, ইনডেক্স হলো খোলা বাক্স, যেখানে পাঠাতে চাওয়া জিনিস রাখেন, আর কমিট হলো সিল করা ও স্বাক্ষরিত প্যাকেজ। বাক্সে কী যাবে, তা আপনি ঠিক করেন, সব একসাথে পাঠাতে হয় না।

ইনডেক্স কেন দরকার

ধরুন, এক ঘণ্টায় আপনি অথেনটিকেশনের একটি বাগ ঠিক করেছেন, সঙ্গে README-র একটি বানান ভুল সারিয়েছেন, আর একটি নতুন ফিচার শুরু করেছেন। ইনডেক্স ছাড়া এই সবকিছু একটি "বিবিধ" কমিটে ঢুকে যেত। ইনডেক্স থাকলে আপনি তিনটি আলাদা কমিট করতে পারেন। প্রতিটি সহজে বোঝা যায়, রিভিউতে যাচাই করা যায় এবং প্রয়োজনে অন্যটিকে প্রভাবিত না করে ফেরানো যায়।

git status: কী বদলেছে এবং কী প্রস্তুত

প্রতিটি add ও commit-এর আগে git status দেখা ভালো। এটি Git-এর সবচেয়ে নিরাপদ কমান্ড, কারণ এটি কিছুই বদলায় না।

$ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   src/auth.js

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   README.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        src/profile.js
  • Changes to be committed — ইনডেক্সে আছে, কমিটে যাবে;
  • Changes not staged — বদলেছে, কিন্তু যোগ করা হয়নি;
  • Untracked files — নতুন ফাইল, যেগুলো সম্পর্কে Git এখনো জানে না।

ফাইল অনেক হলে ছোট আকারটি বেশি সুবিধাজনক:

$ git status -s
M  src/auth.js
 M README.md
?? src/profile.js

প্রথম কলাম ইনডেক্সের অবস্থা, দ্বিতীয়টি ওয়ার্কিং ফোল্ডারের। বাঁদিকে M মানে "বদলেছে ও যোগ করা হয়েছে", ডানদিকে M মানে "বদলেছে, কিন্তু যোগ করা হয়নি", ?? মানে "ট্র্যাক করা হচ্ছে না"।

git add: ইনডেক্সে পরিবর্তন যোগ করা

কমান্ডকী যোগ করে
git add file.jsনির্দিষ্ট একটি ফাইল
git add src/ফোল্ডারের ভেতরের সব বদলানো ফাইল
git add .বর্তমান ফোল্ডার ও তার ভেতরের সব পরিবর্তন, নতুন ও মোছা ফাইলসহ
git add -Aপুরো রিপোজিটরির সব পরিবর্তন
git add -uশুধু আগে থেকে ট্র্যাক করা ফাইল, নতুন ফাইল নয়
git add -pইন্টারঅ্যাকটিভভাবে, অংশ ধরে ধরে (hunks)
git add '*.css'প্যাটার্ন অনুযায়ী ফাইল

git add-এর সমার্থক git stage: দুটি একই কমান্ড, তাই "stage" বা "স্টেজ করা" শব্দটি এসেছে।

git add -p: ফাইলের একটি অংশ যোগ করা

এটি সবচেয়ে কম ব্যবহৃত কৌশল। একটি ফাইলে দুটি ভিন্ন সম্পাদনা মিশে থাকলে git add -p প্রতিটি অংশ দেখায় এবং জিজ্ঞেস করে সেটি যোগ করবেন কি না:

$ git add -p src/auth.js
@@ -12,7 +12,7 @@ function login(user) {
-  if (user.password = input) {
+  if (user.password === input) {
(1/2) Stage this hunk [y,n,q,a,d,s,e,?]?

y — যোগ করুন, n — বাদ দিন, s — অংশটিকে আরও ছোট ভাগে ভাঙুন, q — বের হন। এভাবে একটি ফাইল থেকেই দুটি পরিষ্কার কমিট তৈরি হয়।

কমিটে কী যাবে, তা কীভাবে যাচাই করবেন

git diff            # যেসব বদল এখনো ইনডেক্সে যোগ হয়নি
git diff --staged   # ইনডেক্সে থাকা, কমিটে যাওয়া বদলগুলো

একটি সাধারণ বিভ্রান্তি: git add-এর পর সাধারণ git diff কিছু দেখায় না। এর মানে পরিবর্তন হারায়নি, সেগুলো ইনডেক্সে আছে; git diff --staged (সমার্থক --cached) দিয়ে দেখুন।

ইনডেক্স থেকে ফাইল সরানো

git restore --staged file.js

এতে ফাইলের সম্পাদনা থেকে যায়, শুধু ফাইলটি আর কমিটের জন্য প্রস্তুত থাকে না। পুরনো Git সংস্করণে এর জন্য git reset HEAD file.js ব্যবহার হতো, সেটি এখনো কাজ করে।

git commit: পরিবর্তন রেকর্ড করা

git commit -m "লগইনে পাসওয়ার্ড যাচাইয়ের ভুল ঠিক করা"
[main 3f2a9c1] লগইনে পাসওয়ার্ড যাচাইয়ের ভুল ঠিক করা
 1 file changed, 1 insertion(+), 1 deletion(-)

উত্তরে থাকে ব্রাঞ্চ, নতুন কমিটের ছোট হ্যাশ এবং পরিসংখ্যান। কমিটে শুধু ইনডেক্সের বিষয়বস্তু যায়। git add-এর পর ফাইলটি আবার বদলালে নতুন সম্পাদনা কমিটে যাবে না, যতক্ষণ না আবার যোগ করেন।

git commit-এর কয়েকটি কাজের ফ্ল্যাগ

কমান্ডকী করে
git commitবহু-লাইনের বার্তার জন্য এডিটর খোলে
git commit -m "..."বার্তা সরাসরি কমান্ডে
git commit -am "..."সব বদলানো ট্র্যাক করা ফাইল যোগ করে কমিট করে; নতুন ফাইল যায় না
git commit -vবার্তা লেখার সময় এডিটরে diff দেখায়
git commit --amendশেষ কমিটটি আবার লেখে
git commit --allow-empty -m "..."খালি কমিট, যেমন CI আবার চালাতে

ডিফল্ট এডিটর Vim হলে এবং সেখানে আটকে গেলে: বার্তা লিখুন, Esc চাপুন, তারপর :wq লিখে Enter দিন। এডিটর বদলাতে: git config --global core.editor "code --wait" বা nano।

ভালো কমিট বার্তা কীভাবে লিখবেন

ছয় মাস পরে কেউ যখন বাগের উৎস খুঁজবে, তখন এই বার্তাটি পড়বে। বার্তাকে উত্তর দিতে হবে "কী এবং কেন", "আজ আমি কী করেছি" নয়।

  • প্রথম লাইন — ৫০–৭২ অক্ষরের মধ্যে, পরিবর্তনের মূল কথা;
  • আদেশসূচক বা নিরপেক্ষ ভঙ্গিতে: "ইমেইল যাচাই যোগ করা", "Fix login redirect";
  • প্রয়োজনে একটি ফাঁকা লাইন এবং বিস্তারিত: কেন এভাবে করা হলো, কী সীমাবদ্ধতা আছে;
  • এক কমিট — এক যৌক্তিক পরিবর্তন।

খারাপ: fix, ঠিক করলাম, wip, asdf। ভালো: খালি কার্টে পণ্য থাকলে কার্ট ভেঙে পড়ার সমস্যা ঠিক করা। অনেক দল Conventional Commits ফরম্যাট ব্যবহার করে: feat: ..., fix: ..., docs: ...।

git commit --amend: শেষ কমিট কীভাবে ঠিক করবেন

বার্তায় বানান ভুল হলো, বা একটি ফাইল যোগ করতে ভুলে গেছেন, তাহলে "ফাইল ভুলে গেছি" নামে আলাদা কমিট করার দরকার নেই। এর জন্য আছে amend।

বার্তা ঠিক করা

git commit --amend -m "লগইনে পাসওয়ার্ড যাচাইয়ের ভুল ঠিক করা"

ভুলে যাওয়া ফাইল যোগ করা

git add forgotten.js
git commit --amend --no-edit

--no-edit ফ্ল্যাগ আগের বার্তাটিই রেখে দেয়।

amend সম্পর্কে গুরুত্বপূর্ণ কথা

--amend কমিটকে "সম্পাদনা" করে না, বরং একটি নতুন কমিট বানায় যার হ্যাশ আলাদা, এবং সেটি পুরনোটির জায়গায় বসে। কমিটটি শুধু আপনার কাছে থাকলে এটি নিরাপদ। git push হয়ে গেলে amend-এর পর সাধারণ push প্রত্যাখ্যাত হবে, তখন git push --force-with-lease লাগবে। অন্য সবাই যে ব্রাঞ্চে কাজ করে, সেখানে এমনটি করবেন না: আপনি এমন ইতিহাস বদলে দেবেন, যার ওপর তারা ইতিমধ্যে কাজ গড়ে তুলেছে।

ভুল করে amend হয়ে গেলে পুরনো কমিটটি git reflog-এ পাওয়া যায়, এবং git reset --soft HEAD@{1} দিয়ে সেখানে ফেরা যায়।

সাধারণ ভুল

«nothing to commit, working tree clean»

কোনো পরিবর্তন নেই: হয় সব আগে কমিট হয়ে গেছে, নয়তো আপনি অন্য ফোল্ডারের ফাইল বদলাচ্ছেন। git status ও প্রজেক্টের পথ যাচাই করুন।

«no changes added to commit»

ফাইল বদলেছে, কিন্তু ইনডেক্সে যোগ হয়নি। git add চালান, অথবা আগে থেকে ট্র্যাক করা ফাইলের জন্য git commit -am ব্যবহার করুন।

«Please tell me who you are»

নাম ও ইমেইল সেট করা নেই। একবার চালান: git config --global user.name "আপনার নাম" এবং git config --global user.email "ইমেইল"।

ভুল করে অতিরিক্ত কিছু কমিট হয়ে গেছে

কমিট যদি এখনো push না হয়ে থাকে, তাহলে পরিবর্তনগুলো ইনডেক্সে রেখে কমিটটি বাতিল করুন: git reset --soft HEAD~1। তারপর git restore --staged দিয়ে অতিরিক্ত অংশ সরিয়ে আবার কমিট করুন। কমিটে গোপন তথ্য (secret) ঢুকে গেলে ধরে নিন সেটি ফাঁস হয়েছে, এবং নতুন করে তৈরি করুন।

git add . অপ্রয়োজনীয় ফাইল যোগ করেছে

আগেই .gitignore ঠিক করে নিন এবং কমিটের আগে git status দেখুন। আগে থেকে ট্র্যাক হওয়া ফাইল তখনই ট্র্যাকিং থেকে বাদ যায়, যখন git rm --cached ফাইল চালানো হয়।

কমিট আসলে কী

কমিট আগের সংস্করণের সঙ্গে পার্থক্য রাখে না, বরং পুরো প্রকল্পের একটি স্ন্যাপশট রাখে: ফাইলের ট্রির রেফারেন্স, প্যারেন্ট কমিটের রেফারেন্স, লেখক, তারিখ ও বার্তা। যেসব ফাইল বদলায়নি, সেগুলো নতুন করে কপি হয় না; Git আগে সংরক্ষিত অবজেক্টের দিকে ইশারা করে, তাই ইতিহাস কম জায়গা নেয়।

কমিটের হ্যাশ (যেমন 3f2a9c1) এই সব বিষয়বস্তু থেকে হিসাব করা হয়। বার্তার একটি অক্ষর বদলালেও হ্যাশ বদলে যায়। এ কারণেই --amend ও rebase পুরনো কমিট সম্পাদনা না করে নতুন কমিট বানায়, এবং লেখা ইতিহাস সহকর্মীদের কপির সঙ্গে সংঘর্ষ তৈরি করে।

সংক্ষেপে ইতিহাস দেখতে:

git log --oneline --graph -10

প্রতিটি লাইন একটি কমিট। আপনার ইতিহাসের বার্তাগুলো যদি diff না খুলেই বোঝা যায়, তাহলে আপনি সঠিকভাবেই কাজ করছেন।

প্রতিদিনের কাজের চক্র

git status                 # কী বদলেছে
git diff                   # সম্পাদনা দেখা
git add -p                 # দরকারি অংশ বাছা
git diff --staged          # কমিটে কী যাবে যাচাই
git commit -m "স্পষ্ট বিবরণ"
git log --oneline -5       # কমিট ঠিক জায়গায় আছে কি না দেখা
git push                   # সার্ভারে পাঠানো

কমিট পরিবর্তন শুধু লোকালি সংরক্ষণ করে। GitHub বা অন্য সার্ভারে পৌঁছাতে git push লাগে।

সারসংক্ষেপ

git add ইনডেক্সে পরের স্ন্যাপশট জমা করে, git status ও git diff --staged দেখায় তাতে কী যাবে, আর git commit স্ন্যাপশটটি ইতিহাসে লেখে। ছোট ও যৌক্তিক কমিট করুন, পরিষ্কার বার্তা লিখুন, এবং ছোট সংশোধনের জন্য push-এর আগে git commit --amend ব্যবহার করুন। ইনডেক্স এবং add → commit এই দুই ধাপের পদ্ধতি Git কোর্সে বাস্তব অনুশীলনের মাধ্যমে শেখানো হয়।

সাধারণ প্রশ্ন

কত ঘন ঘন কমিট করা উচিত?

যখনই একটি যৌক্তিক পরিবর্তন শেষ হয় এবং প্রকল্প কাজের অবস্থায় থাকে। দিনের শেষে একটি বিশাল কমিটের চেয়ে অনেকগুলো ছোট কমিট ভালো।

Git-এ কি git save নামে কোনো কমান্ড আছে?

না, এমন কোনো কমান্ড নেই। সংরক্ষণ মানে git add ও git commit, আর অসমাপ্ত কাজ সাময়িকভাবে সরিয়ে রাখতে ব্যবহার হয় git stash।

কমিটে কী ছিল, তা কীভাবে দেখবেন?

git show হ্যাশ লিখে চালালে লেখক, বার্তা ও কমিটের সব পরিবর্তন দেখা যায়। হ্যাশ না দিলে শেষ কমিটটি দেখায়।

git add . ও git add -A-এর মধ্যে পার্থক্য কী?

আধুনিক Git-এ দুটিই নতুন, বদলানো ও মোছা ফাইল যোগ করে। পার্থক্য এলাকায়: git add . বর্তমান ফোল্ডার ও তার ভেতরে কাজ করে, আর git add -A পুরো রিপোজিটরিতে।

পুরনো, শেষের নয় এমন কমিট বদলানো যায়?

হ্যাঁ, ইন্টারঅ্যাকটিভ rebase দিয়ে: git rebase -i প্যারেন্ট-হ্যাশ, তারপর দরকারি কমিটটিকে edit বা reword হিসেবে চিহ্নিত করুন। এটি শুধু সেই কমিটে করুন, যেগুলো এখনো কোনো দলীয় ব্রাঞ্চে push হয়নি।

ভিডিওতে বিষয়টি শিখুন

“শূন্য থেকে আত্মবিশ্বাসী ডেভেলপার পর্যন্ত গিট” কোর্সে বিষয়টি অনুশীলনসহ বিস্তারিত শেখানো হয়েছে।

কোর্সে যান