স্ক্রিপ্ট থেকে গিট ওয়ার্কিং ডিরেক্টরিটি পরিষ্কার কিনা তা নির্ধারণ করুন


82

আমার কাছে একটি স্ক্রিপ্ট রয়েছে যা rsyncগিট ওয়ার্কিং ডিরেক্টরি সহ গন্তব্য হিসাবে চলে। আমি চাই যে ওয়ার্কিং ডিরেক্টরিটি পরিষ্কার (কমিট করার কোনও পরিবর্তন নেই), না তার উপর নির্ভর করে স্ক্রিপ্টটির আলাদা আচরণ হোক। উদাহরণস্বরূপ, যদি আউটপুট git statusনীচের মতো হয় তবে আমি স্ক্রিপ্টটি প্রস্থান করতে চাই:

git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date

যদি ডিরেক্টরিটি পরিষ্কার না হয় তবে আমি এটি আরও কিছু কমান্ড প্রয়োগ করতে চাই।

আমি কীভাবে শেল স্ক্রিপ্টে উপরের মতো আউটপুট পরীক্ষা করতে পারি?


সর্বশেষ কমান্ডের সাহায্যে কোনও স্থিতি পরীক্ষা করা এখানে সহায়তা করবে? ($?)
ইউভিভি

আপনি আরও বিশদ দিতে পারেন দয়া করে? আপনার স্ক্রিপ্টের মূল ধারণাটি কী?
টাকোমি

@ টাকোমি আমি সম্পাদনাতে প্রসঙ্গটি যুক্ত করেছি
ব্রেন্টপিউটারসন

আপনি কেবল ধরে নিতে পারেন যে এটি পরিষ্কার নয় এবং আপনি git reset --hard origin/branchযদি যা করছেন ঠিক তেমন একটি করুন ... যেমন আপনি যদি কিছু সংকলনের পরে পরিষ্কার করার চেষ্টা করছেন ইত্যাদি।
স্নেকডোক

1
@ স্নেকডোক আপনি পারতেন, তবে আমি ধরে নিই যে বিপরীত ঘটনাটি বেশি সাধারণ হবে, যদি স্থানীয় পরিবর্তনগুলি এড়ানোর জন্য ওয়ার্কিং ডিরেক্টরিটি নোংরা হয় তবে প্রস্থান করুন। উভয় ক্ষেত্রে বিবেচনা করা ভবিষ্যতের পাঠকদের জন্য প্রশ্নকে আরও কার্যকর করে তুলবে।
থমাস নাইম্যান

উত্তর:


133

আউটপুট পার্সিং git statusকরা একটি খারাপ ধারণা কারণ আউটপুটটি মানুষের পাঠযোগ্য, মেশিন-পঠনযোগ্য নয়। গিটারের ভবিষ্যতের সংস্করণগুলিতে বা আলাদাভাবে কনফিগার করা পরিবেশে আউটপুট একই থাকবে এমন কোনও গ্যারান্টি নেই।

ইউভিভি মন্তব্য সঠিক ট্র্যাকের উপর রয়েছে, তবে দুর্ভাগ্যক্রমে git statusযখন অনির্দিষ্ট পরিবর্তন রয়েছে তখন রিটার্ন কোডের পরিবর্তন হয় না। তবে এটি --porcelainঅপশন সরবরাহ করে, যার ফলে git status --porcelainস্ক্রিপ্টগুলির জন্য আউটপুটটিকে সহজে পার্সে ফর্ম্যাটে ফর্ম্যাট করা যায় এবং গিট সংস্করণ জুড়ে এবং ব্যবহারকারী কনফিগারেশন নির্বিশেষে স্থিতিশীল থাকবে।

আমরা git status --porcelainএকটি নির্দেশক হিসাবে খালি আউটপুট ব্যবহার করতে পারি যে প্রতিশ্রুতিবদ্ধ হওয়ার কোনও পরিবর্তন নেই:

if [ -z "$(git status --porcelain)" ]; then 
  # Working directory clean
else 
  # Uncommitted changes
fi

যদি আমরা ওয়ার্কিং ডিরেক্টরিতে তালিকার চিহ্নবিহীন ফাইলগুলি যত্ন না করি তবে আমরা --untracked-files=noসেগুলি উপেক্ষা করার বিকল্পটি ব্যবহার করতে পারি :

if [ -z "$(git status --untracked-files=no --porcelain)" ]; then 
  # Working directory clean excluding untracked files
else 
  # Uncommitted changes in tracked files
fi

এই বেশি শর্ত বিরুদ্ধে জোরালো করতে আসলে কারণ git statusআউটপুট ছাড়া ব্যর্থ করার জন্য stdout, আমরা চেক পরিমার্জন করতে পারেন:

if output=$(git status --porcelain) && [ -z "$output" ]; then
  # Working directory clean
else 
  # Uncommitted changes
fi

এটা যে এর মূল্য যদিও git statusযখন কাজ ডিরেক্টরি অশুচি অর্থপূর্ণ প্রস্থান কোড দেয় না, git diffপ্রদান করে --exit-codeবিকল্প, যা এটি অনুরূপ আচরণ তোলে পরিবর্তন ইউটিলিটি, যে, অবস্থা সঙ্গে থেকে প্রস্থান হয় 1যখন পার্থক্য ছিল এবং 0যখন কেউ খুঁজে পাওয়া যায়নি।

এটি ব্যবহার করে, আমরা এগুলি ছাড়াই পরিবর্তনগুলি পরীক্ষা করতে পারি:

git diff --exit-code

এবং মঞ্চস্থ হয়েছে, তবে এর সাথে প্রতিশ্রুতিবদ্ধ পরিবর্তনগুলি করা হয়নি:

git diff --cached --exit-code

যদিও git diffউপযুক্ত আর্গুমেন্টের মাধ্যমে সাবমডিউলগুলিতে অন্যাক্র্যাকড ফাইলগুলির বিষয়ে প্রতিবেদন করতে পারেন --ignore-submodules, দুর্ভাগ্যবশত মনে হচ্ছে এটি প্রকৃত কার্যকারী ডিরেক্টরিতে তালিকার চিহ্নবিহীন ফাইলগুলিতে রিপোর্ট করার কোনও উপায় নেই। যদি ওয়ার্কিং ডিরেক্টরিতে তালিকাভুক্ত ফাইলগুলি প্রাসঙ্গিক git status --porcelainহয় তবে সম্ভবত সেরা বেট।


4
git status --porcelainকমিট এবং অ-ট্রেড করা ফাইলের জন্য মঞ্চ পরিবর্তন না থাকলেও ughhh কোড 0 দিয়ে প্রস্থান করবে।
আলেকজান্ডার মিলস 21

আমি git stashকিছু করতে চাইলে সময়ের আগে নির্ধারণ করতে আগ্রহী (এটি কোনও কার্যকর রিটার্ন কোড আউটপুট দেয় না)। আমি --ignore-submodulesঅন্যথায় git statusসাবডমডিউল পরিবর্তনগুলি git stashউপেক্ষা করে যা ইঙ্গিত করে তা যুক্ত করতে হয়েছিল।
ডেভিন লেন

1
@ আলেকজান্ডারমিলস: আমিও এটি পর্যবেক্ষণ করেছি। কিন্তু তারপরে কী if [ -zকরছিল তা যাচাই করে নিলেন। এর -zমানে হল যে নিম্নলিখিত স্ট্রিংটি ফাঁকা থাকলে, যদি এটির মূল্যায়ন হয় true। অন্য কথায়, এর git status --porcelainফলাফল যদি কোনও স্ট্রিং না হয়, রেপো পরিষ্কার। যদি তা না হয় তবে এটি সংশোধিত / যুক্ত / সরানো ফাইলগুলি তালিকাভুক্ত করে এবং এটি আর খালি স্ট্রিং নয়। ifতারপর মূল্যায়ণ false
এডিন্যাক

19

ব্যবহার করুন:

git diff-index --quiet HEAD

রিটার্ন কোডটি কার্যক্ষম ডিরেক্টরিটির অবস্থা প্রতিফলিত করে (0 = পরিষ্কার, 1 = নোংরা)। অবিরত ফাইলগুলি উপেক্ষা করা হয়।


6
বর্তমান ডিরেক্টরিতে যদি তালিকার বাইরে থাকা ফাইল থাকা অবস্থায় 0 ফেরত দেয়।
অ্যাডাম পার্কিন

2
যদি ফাইলগুলি স্পর্শ করা / ওভাররাইট করা হয়ে থাকে তবে অন্যথায় সূচকের অনুরূপ হয়, আপনাকে প্রথমে git update-index --refreshআগে চালানো দরকার git diff-index HEAD। আরো তথ্য: stackoverflow.com/q/34807971/1407170
sffc

@ অ্যাডাম পারকিন আমি git add .জারি করার আগে কেবল সমস্ত ফাইল যুক্ত করে রেখেছি । সাধারণত এটি কোনও স্ক্রিপ্টে ব্যবহার করার উপায়
ceztko

এটা অসাধারণ. নোট করুন যে শূন্য-বিহীন একটি রিটার্ন / প্রস্থান কোডটিকে একটি 'ত্রুটি' হিসাবেও ব্যাখ্যা করা হয়, যা আপনি যদি সেট-ই সহ কোনও স্ক্রিপ্টে থাকেন তবে আপনার স্ক্রিপ্টটি 'নোংরা' হলে প্রস্থান করবে। এটি set +eকল করার আগে করা gitএবং set -eমূল্যায়ন করার পরে আবার যুক্ত করে এড়ানো যায় $?
ওরিওন এলিজিল

1

অ্যান্ড্রির দুর্দান্ত উত্তরের গৌণ প্রসার ।

ফলাফলগুলি মূল্যায়নের একটি উপায় এটির আগে আপনি সেট-ই ইস্যু করেছেন এমন কোনও স্ক্রিপ্টে থাকলে কোনও ক্ষতি এড়ানোও

অবিরত ফাইলগুলি উপেক্ষা করা হয়।

set +e
git diff-index --quiet HEAD

if [ $? == 1 ] ; then
  set -e
  GIT_MODS="dirty"
else
  set -e
  GIT_MODS="clean"
fi
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.