যদি Git রিপোর্ট করে যে আপনার Mac-এ কোনো ফাইল এক্সিকিউটেবল হয়ে গেছে—অথবা এক্সিকিউটেবল থাকা বন্ধ হয়ে গেছে—তবে প্রথমে খুঁজে বের করুন কোন স্তরে পরিবর্তন হয়েছে: ওয়ার্কিং ফাইল, স্টেজিং ইনডেক্স, নাকি কোনো কমিট। অনুমতি বা Git কনফিগারেশন পরিবর্তন করার আগে সেই অবস্থাগুলোর তুলনা করুন। Git সাধারণ ফাইলগুলোকে মোড 100644 (এক্সিকিউটেবল নয়) বা 100755 (এক্সিকিউটেবল) হিসেবে রেকর্ড করে; এগুলোর মধ্যে একটি বিচ্ছিন্ন পরিবর্তন সাধারণত এক্সিকিউটেবল বিটের দিকে নির্দেশ করে, পরিবর্তিত ফাইল বিষয়বস্তুর দিকে নয়। Git-এর diff সংক্রান্ত ডকুমেন্টেশন
১. পরিবর্তনটি স্টেজ করা হয়েছে কি না তা পরীক্ষা করুন
Terminal-এ রিপোজিটরিতে যান এবং এর স্ট্যাটাস ও উভয় diff পরীক্ষা করুন:
git status --short
git diff --summary
git diff --cached --summary
git diff ওয়ার্কিং ট্রির সাথে ইনডেক্সের তুলনা করে; git diff --cached ইনডেক্সের সাথে HEAD-এর তুলনা করে। Git status এই স্তরগুলোকে আলাদাভাবে চিহ্নিত করে, ফলে স্টেজ করা পরিবর্তন আনস্টেজড পরিবর্তন থেকে পৃথকভাবে প্রদর্শিত হয়। Git status সংক্রান্ত ডকুমেন্টেশন
mode change 100644 => 100755 path/to/file-এর মতো আউটপুট খুঁজুন। এটি যদি কেবল git diff --summary-তে প্রদর্শিত হয়, তবে ওয়ার্কিং ফাইলের সাথে ইনডেক্সের অমিল রয়েছে। এটি যদি git diff --cached --summary-তে প্রদর্শিত হয়, তবে মোড পরিবর্তনটি স্টেজ করা হয়েছে এবং কমিট করা যেতে পারে। উভয়টিই যদি খালি থাকে কিন্তু কোনো সহকর্মী কমিট করা পরিবর্তনের কথা জানান, তবে পরবর্তীতে ইতিহাস পরীক্ষা করুন।
২. ইনডেক্সের সাথে Mac ফাইলের তুলনা করুন
ট্র্যাক করা কোনো পাথের জন্য, ইনডেক্সে রেকর্ড করা মোড এবং ফাইলের বর্তমান অনুমতিগুলো পরীক্ষা করুন:
git ls-files --stage -- "scripts/build.sh"
ls -l "scripts/build.sh"
scripts/build.sh-এর পরিবর্তে রিপোজিটরি-সম্পর্কিত সঠিক পাথটি লিখুন; স্পেস এবং শেল ক্যারেক্টারগুলো যাতে আক্ষরিক অর্থে বিবেচিত হয় সেজন্য এটি কোটেশনের মধ্যে রাখুন। git ls-files --stage আউটপুটে, প্রথম ক্ষেত্রটি হলো ইনডেক্সে সংরক্ষিত মোড: 100644 মানে Git ফাইলটিকে এক্সিকিউটেবল হিসেবে রেকর্ড করেনি, আর 100755 মানে এটি করেছে। ls -l আউটপুট স্থানীয় পারমিশন বিটগুলো দেখায়; পারমিশন ট্রিপলেটে একটি x সেই শ্রেণির ব্যবহারকারীর জন্য এক্সিকিউট পারমিশন নির্দেশ করে। Git ls-files সংক্রান্ত ডকুমেন্টেশন এবং Apple-এর পারমিশন নির্দেশিকা এই দুটি দিক ব্যাখ্যা করে।
এই তুলনাটি মূল কারণ চিহ্নিত করতে সাহায্য করে। ইনডেক্সে যদি 100644 থাকে, কিন্তু ls -l এক্সিকিউট পারমিশন দেখায়, তবে অসঙ্গতিটি ওয়ার্কিং ফাইলে রয়েছে (অথবা ফাইল-মোড সংক্রান্ত পার্থক্য উপেক্ষা করার জন্য Git কনফিগার করা আছে)। ইনডেক্সে যদি 100755 থাকে, তবে আপনি ফাইলটিকে যা-ই করতে চান না কেন, Git ইতিমধ্যেই একটি এক্সিকিউটেবল মোড স্টেজ বা চেকআউট করে ফেলেছে।
৩. যে কমিটটি মোডটি যুক্ত করেছিল তা খুঁজুন
পরিবর্তনটি যদি ইতিমধ্যেই ইতিহাসে থেকে থাকে, তবে সংশ্লিষ্ট ফাইলের কমিট সারাংশগুলো পরীক্ষা করুন:
git log --summary -- "scripts/build.sh"
কোনো ফাইলের মোড পরিবর্তিত হলে Git-এর প্যাচ ফরম্যাট আলাদাভাবে old mode এবং new mode হেডার প্রিন্ট করে। যে কমিটে এই মানগুলো পরিবর্তিত হয়েছে তা পর্যালোচনা করুন, তারপর এর প্যারেন্ট এবং আশেপাশের কাজের ধারা (ওয়ার্কফ্লো) তুলনা করুন: ফাইলটি কি ইচ্ছাকৃতভাবে রানযোগ্য করা হয়েছিল, কোনো এডিটর বা স্ক্রিপ্ট কি পারমিশন পরিবর্তন করেছে, নাকি রিপোজিটরিটি অন্য কোনো ফাইলসিস্টেম বা অপারেটিং সিস্টেমে ব্যবহার করা হয়েছিল? কমিটটি নির্দেশ করে কখন Git পরিবর্তনটি রেকর্ড করেছিল; কিন্তু কোন অ্যাপ্লিকেশন বা ব্যক্তি এর জন্য দায়ী তা প্রমাণ করে না। Git diff ফরম্যাট সংক্রান্ত ডকুমেন্টেশন
সম্পর্কহীন বেশ কয়েকটি ফাইলে মোড পরিবর্তন হওয়া একটি সামগ্রিক পারমিশন-নির্ধারণ অপারেশন বা ফাইলসিস্টেম/পরিবেশগত রূপান্তরকে নির্দেশ করতে পারে। Git নথিভুক্ত করে যে কিছু ফাইলসিস্টেম এক্সিকিউটেবল বিট সংরক্ষণ করতে ব্যর্থ হয়, এবং বিভিন্ন পরিবেশের মধ্যে স্থানান্তরিত কোনো রিপোজিটরি ভিন্ন ভিন্ন ফাইল-মোড আচরণের সম্মুখীন হতে পারে। এটিকে অনুসন্ধানের জন্য একটি সূত্র হিসেবে বিবেচনা করুন, কোনো নির্দিষ্ট কারণের চূড়ান্ত প্রমাণ হিসেবে নয়। Git কনফিগারেশন ডকুমেন্টেশন
৪. Git-এর ফাইল-মোড সেটিংস পরীক্ষা করুন
সেটিংসটি এবং এটি কোথা থেকে আসছে তা পরীক্ষা করুন:
git config --show-origin --get core.filemode
core.filemode নিয়ন্ত্রণ করে যে Git ওয়ার্কিং ট্রির এক্সিকিউটেবল-বিট পার্থক্যগুলো গ্রহণ করবে কি না। নির্দিষ্ট করা না থাকলে Git এটিকে ডিফল্টভাবে true হিসেবে রাখে এবং কোনো রিপোজিটরি শুরু (initialize) বা ক্লোন করার সময় ফাইলসিস্টেমের আচরণ পরীক্ষা করতে পারে। কমান্ডটি যদি false প্রিন্ট করে, তবে Git স্থানীয় এক্সিকিউটেবল-বিট পরিবর্তনগুলো উপেক্ষা করতে পারে; তবে সেই সেটিং কোনো কমিটে ইতিমধ্যে রেকর্ড করা মোড ব্যাখ্যা করে না। এটি যদি কিছুই প্রিন্ট না করে, তবে সেটিংটি হয়তো আনসেট করা আছে, সেক্ষেত্রে Git-এর অফিসিয়াল ডিফল্ট প্রযোজ্য হবে। Git কনফিগারেশন ডকুমেন্টেশন
কেবলমাত্র একটি অপ্রত্যাশিত diff আড়াল করার জন্য এই অপশনটি false-এ সেট করা এড়িয়ে চলুন। প্রথমে নিশ্চিত করুন যে রিপোজিটরিটি এমন কোনো ফাইলসিস্টেম বা শেয়ার্ড সেটআপে রয়েছে কি না যা নির্ভরযোগ্যভাবে এক্সিকিউটেবল বিট সংরক্ষণ করে না, এবং সহযোগীরা মোড ট্র্যাকিংয়ের ওপর নির্ভর করে কি না। সেটিংটি পরিবর্তন করলে মোডের পার্থক্যের ক্ষেত্রে Git-এর আচরণ পরিবর্তিত হয়; এটি ইনডেক্স বা কমিটে ভুলভাবে রেকর্ড করা মোড সংশোধন করে না।
৫. কাঙ্ক্ষিত মোড শনাক্ত করার পরেই কেবল সংশোধন করুন
ফাইলটি যদি এক্সিকিউটেবল হওয়ার কথা না হয় এবং পরিবর্তনটি আনস্টেজড থাকে, তবে chmod দিয়ে স্থানীয় পারমিশন পুনরুদ্ধার করুন:
chmod a-x "scripts/build.sh"
git diff --summary
কাঙ্ক্ষিত মোডটি যদি এক্সিকিউটেবল হয়, তবে তার বদলে chmod a+x "scripts/build.sh" ব্যবহার করুন। macOS-এ, chmod নির্দিষ্ট আইটেমের পারমিশন পরিবর্তন করে; কেবল diff দূর করার জন্য নয়, ফাইলের ভূমিকা এবং রিপোজিটরির নিয়মের ওপর ভিত্তি করে কাঙ্ক্ষিত মোডটি বেছে নিন। Apple-এর পারমিশন নির্দেশিকা
যদি কোনো ভুল মোড স্টেজ করা থাকে, তবে কাঙ্ক্ষিত স্থানীয় পারমিশন সেট করুন, তারপর সেই পাথটি আবার স্টেজ করুন এবং স্টেজ করা সারাংশটি পর্যালোচনা করুন:
chmod a-x "scripts/build.sh"
git add -- "scripts/build.sh"
git diff --cached --summary
ফাইলটি এক্সিকিউটেবল করার প্রয়োজন হলে a-x-এর পরিবর্তে a+x ব্যবহার করুন। বিদ্যমান কোনো কমিটে মোড ভুল থাকলে, শেয়ার্ড ইতিহাস পুনরায় লেখার চেয়ে একটি নতুন সংশোধনমূলক কমিট সাধারণত অধিকতর স্পষ্ট হয়; অন্যরা ইতিমধ্যে ব্যবহার করতে পারে এমন কমিট পুনরায় লেখার আগে সমন্বয় করে নিন। প্রতিটি ক্ষেত্রে, পরে git diff এবং git diff --cached পরীক্ষা করুন যাতে পারমিশন পরিবর্তনের পাশাপাশি কোনো কনটেন্ট এডিট আপনার চোখ এড়িয়ে না যায়।
উৎস
BSD Permissions and Ownership — Apple Developer