TL;DR: .gitignore কাজ না করলে প্রায় প্রতিবারই কারণ এক — ফাইলটা আগে থেকেই ট্র্যাক করা। Git কখনো না দেখা ফাইলই শুধু উপেক্ষা করে; index-এ থাকা ফাইল আপনার লেখা যেকোনো রুলের বাইরে থাকে। সত্যটা বের করুন git check-ignore -v <path> দিয়ে: নিঃশব্দ আউটপুট মানে পাথটা ট্র্যাক করা এবং কোনো রুল প্রযোজ্য নয়। সমাধান git rm --cached <path>, তারপর কমিট — ওই কমিট থেকেই ignore রুল কাজ করা শুরু করে। বাকি ক্ষেত্রগুলো রুলের ক্রম, negation ফাঁদ আর VS Code-এর বিভ্রান্তির হিসাবে।
.gitignore কেন কাজ করছে না?
বেশিরভাগ ক্ষেত্রই একটাই ব্যাখ্যায় মেলে: রুলটা লেখার আগেই ফাইলটা কমিট হয়ে গিয়েছিল। .gitignore কোনো ফিল্টার নয় যা git-এর চোখের আড়ালে ফাইল লুকিয়ে রাখে — এটা আনট্র্যাক অবস্থা থেকে git add কী তুলবে, তার রুল মাত্র। ফাইল একবার index-এ ঢুকে গেলে আপনি স্পষ্টভাবে আনট্র্যাক না করা পর্যন্ত git তার কনটেন্ট পরিবর্তন চিরকাল ট্র্যাক করে। পরে .gitignore এডিট করলে ট্র্যাক করা ফাইলের কিছুই বদলায় না — তাই “commit .env, আতঙ্ক, .env-কে .gitignore-এ যোগ, আবার কমিট” — এই চিরায়ত ক্রমটাও প্রতিবার পুশে সিক্রেটটা পাঠিয়েই দেয়।
এটা সবাইকে কামড়ে দেয়, কারণ git প্রায় সর্বজনীন — Stack Overflow 2022 সার্ভেতে প্রফেশনাল ডেভেলপারদের ৯৩%-এর বেশি Git ব্যবহার করতে দেখা গেছে (survey.stackoverflow.co) — আর ওই ডেভেলপারদের প্রত্যেকে একদিন গত সপ্তাহে কমিট করা কোনো ফাইলের জন্য রুল লেখে।
এই পোস্টের বাকি অংশ সংখ্যালঘু ক্ষেত্রগুলো নিয়ে: রুলের ক্রমে ভুল, negation ফাঁদ, ফোল্ডারের এজ কেস আর IDE প্রশ্ন। তবে আগে পরের সেকশনের হেলথ চেকটা চালান — দশবারে অন্তত ন’বার এটাই তদন্ত শেষ করে দেয়।
কোন gitignore রুল কোন ফাইলে ম্যাচ করছে তা কীভাবে দেখবেন?
ডায়াগনস্টিক টুল হলো git check-ignore, আর এর নিঃশব্দতাই ডায়াগনোসিস:
# রুল প্রযোজ্য হলে ম্যাচিং রুল + ফাইল + লাইন নম্বর প্রিন্ট করে
git check-ignore -v debug.log
# .gitignore:3:*.log debug.log
# কোনো রুল প্রযোজ্য না হলে কিছুই প্রিন্ট করে না — ফাইলটা ট্র্যাক করা (বা কোনো রুল নেই)
git check-ignore -v src/.env
# (নিঃশব্দতা = .gitignore এই পাথ উপেক্ষা করছে না, আপনি যা-ই লিখুন)
# Exit কোড: 0 = ignored, 1 = ignored নয় — স্ক্রিপ্টযোগ্য
git check-ignore -q debug.log && echo "ignored" || echo "tracked or unruly" -v আউটপুট পড়া: প্রথমে ignore সোর্স (.gitignore, .git/info/exclude, বা আপনার গ্লোবাল ignore ফাইল), তারপর line-number:pattern, তারপর পাথ। পরের কোনো রুল চমকে দিলে অগ্রাধিকার মনে রাখুন: শেষ ম্যাচিং রুলই জেতে, তাই *.log-এর পরে !important.log লিখলে শুধু ওই এক ফাইল আবার অন্তর্ভুক্ত হয়।
কমিট করা ফাইলের ক্ষেত্রে gitignore কেন কাজ করছে না?
ফাইলটা আনট্র্যাক করুন, ডিস্কে রেখে দিন, সরানোটা কমিট করুন:
# একটা ফাইল আনট্র্যাক (লোকাল কপি অক্ষত থাকে — --cached শুধু index ধরে)
git rm --cached .env
git commit -m "stop tracking .env"
# ignore রুল এখন প্রযোজ্য হয় কি না যাচাই করুন
git check-ignore -v .env এই কমিটের পর থেকে পাথটার মালিক .gitignore: এডিট আর git status-এ দেখাবে না, git add .-ও আর তুলে নেবে। তবে ফাইলটা হিস্ট্রিতে থেকেই যায় — সিক্রেট হলে শেষ কমিট থেকে সরানোই যথেষ্ট নয়। আসল সমাধান ক্রেডেনশিয়াল ঘুরিয়ে দেওয়া; হিস্ট্রি রিরাইট কেবল সাজসজ্জা (আর শেষ কমিট আনডু তখনই কাজে দেয় যখন খারাপ কমিটটা এখনো টিপে বসে আছে)।
আগে থেকে কমিট হয়ে থাকা জাবড়ে ভরা রিপোর ক্ষেত্রে — build আউটপুট, এডিটরের ময়লা, ভেসে ঢোকা node_modules — গুচ্ছ আনট্র্যাক দুই লাইনের কাজ:
git rm -r --cached .
git add .
git commit -m "apply .gitignore to tracked files" এটা বর্তমান রুল ধরে index নতুন করে সাজায়: উপেক্ষিত পাথ বাদ পড়ে, বাকি সব অপরিবর্তিত অবস্থায় আবার যোগ হয়। diff নাটকীয় দেখায় (হাজার হাজার ডিলিশন) কিন্তু ডিস্ক থেকে কিছুই মোছে না। উদ্দেশ্য যদি ফাইলগুলোই মোছা হয়, শুধু আনট্র্যাক নয়, সেটা git clean -fdx-এর এলাকা — দেখুন git remove untracked files, safely।
Git কখনো না দেখা ফাইলই উপেক্ষা করে। index-এ ঢুকে থাকা ফাইল
.gitignore-এর নাগালের বাইরে — আপনি যে রুলই লিখুন, git তাকে আর ‘অজানা’ বলবে না।
ফোল্ডারের ক্ষেত্রে gitignore কেন কাজ করছে না?
ফোল্ডার-নির্দিষ্ট তিনটে ফাঁদ:
1. ট্রেইলিং স্ল্যাশ ইচ্ছা প্রকাশ করে, ম্যাচিং নয়। build আর build/ দুটোই ডিরেক্টরি ম্যাচ করে, কিন্তু build/ লিখলে স্পষ্ট হয় আপনার চোখে ওটা শুধু ডিরেক্টরি — build নামের কোনো ফাইল রুলটা টিকে যাবে। তবে এই সমতা re-inclusion-এ ভাঙে (পরের ফাঁদ)।
2. Negation বাদ দেওয়া ডিরেক্টরির ভেতরের ফাইলকে উদ্ধার করতে পারে না। git ডকুমেন্টেশন স্পষ্ট: “It is not possible to re-include a file if a parent directory of that file is excluded” (git-scm.com/docs/gitignore)। এটা পারফরম্যান্সের সিদ্ধান্ত — git বাদ দেওয়া ডিরেক্টরির ভেতরে ঢোকে না, পুরোটা এড়িয়ে যায়। তাই নিচেরটা কাজ করে না:
build/
!build/keep.me # মৃত রুল — git build/-এর ভেতরে কখনো তাকায় না সমাধান ডিরেক্টরি নয়, ওর ভেতরটা বাদ দেওয়া:
build/*
!build/keep.me # কাজ করে — build/ নিজে এখনো পরিদর্শনের জন্য খোলা 3. নেস্ট করা .gitignore নিজের স্কোপে জেতে। subdir/.gitignore-এর রুল subdir-এর অন্দরের পাথে রুট ফাইলকে override করে। git check-ignore -v যখন অপ্রত্যাশিত কোনো ignore সোর্সের নাম ধরে, সাধারণত এটাই কারণ।
VS Code-এ gitignore কেন কাজ করছে না?
প্রায় কখনোই VS Code-এর দোষে নয়। এডিটরের Source Control ভিউ একই index পড়ে যেটা git পড়ে, তাই লক্ষণ এক: ফাইলটা আগেই কমিট হয়ে গেছে, আর IDE রিস্টার্ট করলে index বদলায় না। VS Code-ঘেঁষা দুটো বাস্তবতা জেনে রাখা ভালো:
- Explorer-এ ধূসর = ignored; কমলা/হলুদ = ট্র্যাক করা, পরিবর্তনসহ। আপনি ignore করার পরেও ফাইলটা modified দেখালে সেটাই প্রমাণ ওটা ট্র্যাক করা — উপরের
git rm --cachedসমাধানটা চালান। - Explorer-এর changed তালিকায়
.gitignore-করা ফাইল না থাকা মানে রুল কাজ করছে — ফাইলটা প্রথম স্থানেই আনট্র্যাক হিসেবে আসে না। “VS Code আমার gitignore মানে না” রকম রিপোর্টের সিংহভাগেই CLI-রgit statusআর বাসি SCM ভিউ মিলছে না; git-কে দোষ দেওয়ার আগে উইন্ডো রিলোড করুন (Cmd/Ctrl+Shift+P→ “Reload Window”)।
.gitignore বনাম .git/info/exclude বনাম গ্লোবাল: কোনটা কখন?
| ফাইল | স্কোপ | কমিট হয়? | কাজে লাগে |
|---|---|---|---|
.gitignore (repo) | যে কেউ ক্লোন করবে | হ্যাঁ | build আউটপুট, ডিপেন্ডেন্সি, .env — শেয়ার্ড রুল |
.git/info/exclude | শুধু আপনার ক্লোন | না | ব্যক্তিগত জঞ্জাল: .scratch/, এডিটরের ময়লা |
core.excludesFile (global) | আপনার সব রিপো | না | OS জাবড়ে: .DS_Store, Thumbs.db, *.swp |
.gitignore + negation | রিপো | হ্যাঁ | ট্র্যাক করা কনফিগের ব্যতিক্রম আবার অন্তর্ভুক্ত করতে |
বেশিরভাগ ডেভেলপার যে গ্লোবাল ফাইল কখনো সেট করে না, অথচ করা উচিত:
git config --global core.excludesFile ~/.gitignore_global
printf '.DS_Store\nThumbs.db\n*.swp\n' >> ~/.gitignore_global কপি করার মতো ঘরোয়া নিয়ম: রুলটা পুরো টিমের উপকারে লাগলে তার জায়গা রিপো; শুধু আপনার লাগলে তার জায়গা exclude বা গ্লোবাল ফাইল। ব্যক্তিগত ignore রুল কমিট করতে করতেই .gitignore 300 লাইনে গিয়ে দাঁড়ায়, আর কেউ জানে না কোন অর্ধেক এখনো কাজের।
ট্র্যাক করা ফাইলের পরিবর্তন কীভাবে উপেক্ষা করবেন?
মাঝে মাঝে ট্র্যাক করা ফাইল দরকারই আছে (কনফিগ টেমপ্লেট, IDE সেটিংস ফাইল), কিন্তু লোকাল এডিট যেন git status-এ না দেখায়। git update-index-এর দুটো ফ্ল্যাগ — টিম ওয়ার্কফ্লোতে কোনোটারই জায়গা নেই:
git update-index --skip-worktree config/local.dev # লোকাল এডিট চুপ
git update-index --no-skip-worktree config/local.dev # ...আর আবার ফেরে --skip-worktree-ই রক্ষণযোগ্য — এর ভাষ্য “আমার লোকাল ভার্সন ইচ্ছাকৃতভাবে আলাদা।” এর কাজিন --assume-unchanged পারফরম্যান্সের প্রতিশ্রুতি (“এই ফাইল বদলাবে না”), ignore ব্যবস্থা নয়, আর git চুপচাপ এটা ভাঙেও দিতে পারে। দুই ফ্ল্যাগই pull-এর সময় জোরে ব্যর্থ হয় যদি upstream-ও ফাইলটা বদলে থাকে — টেকসই সমাধান দুটো: ফাইল বানানোর সময় থেকেই exclude-এ রাখা লোকাল-অনলি কনফিগ, নয়তো এমন টেমপ্লেট ফাইল (config.example) যেটা git ট্র্যাক করে আর আপনি কপি করেন।
30 সেকেন্ডের gitignore হেলথ চেক
git check-ignore -v <path> # কোন রুল? (নিঃশব্দ = ট্র্যাক করা, রুল নেই)
git ls-files --error-unmatch <path> # মোটেই কি ট্র্যাক করা?
git rm --cached <path> # আনট্র্যাক, ডিস্কে রাখুন
git commit -m "stop tracking <path>"
git check-ignore -v <path> # রুল এবার দেখায় ডায়াগনোজ, আনট্র্যাক, যাচাই। প্রতিটা “gitignore কাজ করছে না” রিপোর্টের পেছনে একই ফাইল দুটো টুপি পরে — index-এর এক পাশে ট্র্যাক করা, অন্য পাশে ignored — আর একটা --cached ফ্ল্যাগই দ্বিতীয় টুপিটা খুলে দেয়।
FAQ
Gitignore কেন কাজ করছে না?
বেশিরভাগ ক্ষেত্রে ফাইলটি আগে থেকেই ট্র্যাক করা। Git শুধু আনট্র্যাক ফাইল উপেক্ষা করে; index-এ থাকা ফাইল git rm --cached দিয়ে আনট্র্যাক করে কমিট না করা পর্যন্ত .gitignore তাকে স্পর্শই করে না।
কোন ফাইলের সঙ্গে কোন gitignore রুল ম্যাচ করে তা কীভাবে দেখবেন?
git check-ignore -v <path> চালান। এটি .gitignore-এর সঠিক লাইন ও রুল নম্বর দেখায়; ফাইল ট্র্যাক করা থাকলে বা কোনো রুল না মিললে নিঃশব্দে বেরিয়ে যায়।
git rm --cached কি আমার লোকাল ফাইল মুছে দেয়?
না। --cached শুধু index থেকে ফাইল সরায়; ডিস্কের কপি থেকে যায়। সরানোটা কমিট করুন, ফাইল আনট্র্যাক হবে, তখন থেকে .gitignore কাজ করে।
উপেক্ষিত ফোল্ডারের ভেতরের ফাইল gitignore আবার কেন অন্তর্ভুক্ত করতে পারে না?
পারফরম্যান্সের জন্য Git বাদ দেওয়া ডিরেক্টরি পুরোটা এড়িয়ে যায়। git ডকুমেন্টেশন অনুযায়ী, ফাইলের প্যারেন্ট ডিরেক্টরি বাদ থাকলে সেই ফাইল আর অন্তর্ভুক্ত করা অসম্ভব।
— mrsaynothing
— mrsaynothing
AI, Linux ও self-hosting নিয়ে ফিল্ড নোটস।
পোস্টটি নিয়ে dev.to-তে আলোচনা করুন dev.to ↗
পরের হাউ-টু ইমেইলে পান
প্রতি পোস্টে একটি ইমেইল। সমাধান করুন, এগিয়ে যান।
এটা কী?Ollama GPU ব্যবহার করছে না? Linux, Windows ও WSL-এ সমাধান
লেখাগুলো ভালো লাগছে? এমন জিনিস বানানোই আমার পেশা। আমাকে নিন