প্রদত্ত ফাইলে পরিবর্তনযুক্ত একটি গিট শাখা পান


91

আমার 57 টি স্থানীয় শাখা রয়েছে। আমি জানি আমি তাদের একটির মধ্যে একটি নির্দিষ্ট ফাইলে পরিবর্তন করেছি, তবে আমি নিশ্চিত না যে কোনটি। কোন শাখায় একটি নির্দিষ্ট ফাইলে পরিবর্তন রয়েছে তা অনুসন্ধান করার জন্য আমি চালাতে পারি এমন কোনও আদেশ রয়েছে?

উত্তর:


89

সমস্ত শাখাগুলি সন্ধান করুন যার মধ্যে FILENAME এ পরিবর্তন রয়েছে (এমনকি (নথিভুক্ত নয়) শাখার পয়েন্টের আগেও)

FILENAME="<filename>"
git log --all --format=%H $FILENAME | while read f; do git branch --contains $f; done | sort -u

ম্যানুয়ালি পরিদর্শন করুন:

gitk --all --date-order -- $FILENAME

FILENAME- এ সমস্ত পরিবর্তন সন্ধান করুন যে মাস্টারটিতে মার্জ করা হয়নি:

git for-each-ref --format="%(refname:short)" refs/heads | grep -v master | while read br; do git cherry master $br | while read x h; do if [ "`git log -n 1 --format=%H $h -- $FILENAME`" = "$h" ]; then echo $br; fi; done; done | sort -u

আমার কি এই কমান্ডের মধ্যে FILENAME ছাড়াও কিছু প্রতিস্থাপন করতে হবে? এটি সমস্ত 57 শাখার নাম দেয়।
ডাস্টিন

@ ডাস্টিন: যদি সমস্ত 57 টি শাখায় সেই ফাইলের নাম থাকে তবে সমস্ত 57 টি শাখায় একটি ফাইল থাকে যা সেই ফাইলের নাম অন্তর্ভুক্ত করে। শাখাগুলি সেই শাখায় প্রাচীনতম পুনর্বিবেচনা থেকে পৌঁছনীয় থেকে শুরু হয়, যদিও আপনি যদি শাখাটি তৈরি করার আগে পুনর্বিবেচনাটি বিদ্যমান ছিল (শাখাটি কিছু সংশ্লেষে পূর্ববর্তীভাবে তৈরি হয়েছিল)। আমি মনে করি আপনার সমস্যার আরও ভাল সংজ্ঞা দেওয়া দরকার। আপনি কি জানেন যে পরিবর্তনটি কি? আপনি ব্যবহার গেল git log -Schange …বা git log --grep LOGMESSAGE …(সঙ্গে ... কমান্ড আমি উল্লেখ বাকি প্রতিনিধিত্বমূলক)।
শেঠ রবার্টসন

4
@ ডাস্টিন: আরেকটি বিকল্প ব্যবহার করা হচ্ছে gitk --all -- filenameযা আপনাকে সেই ফাইলের সমস্ত পরিবর্তনগুলি গ্রাফিক্যালি দেখিয়ে দেবে। যদি আপনি প্রশ্নে প্রতিশ্রুতিবদ্ধ শনাক্ত করতে পারেন তবে git branch --containsকমিটটি কোন শাখায় স্থানান্তরিত হয়েছে তা দেখতে আপনি ব্যবহার করতে পারেন। যদি আপনি দেখতে চান যে প্রশ্নে কমিটটি মূলত কোন শাখাটি তৈরি হয়েছিল, তবে গুগল গিট-হোয়াট ব্রাঞ্চ, তবে সচেতন থাকুন যে দ্রুত-ফরোয়ার্ড মার্জগুলি সেই তথ্যটিকে অস্পষ্ট করতে পারে।
শেঠ রবার্টসন

@ শেঠ: আমি প্রতিশ্রুতিবদ্ধ বার্তা বা সঠিক কোড পরিবর্তন মনে করতে পারিনি। আমি শুধু একটি সাধারণ ধারণা আছে। সমস্যাটি হ'ল এটি এখনও মাস্টারের সাথে একীভূত হয়নি, তাই গিটক ব্যবহার করার জন্য আমি যা খুঁজছি তা খুঁজে পাওয়ার জন্য প্রতিটি শাখাটি চেকআউট করতে হবে। ভাল লাগবে যদি আমি বলতে পারি, "গিট, আমাকে শাখাগুলি ফাইলে নাম পরিবর্তনের যে শাখাগুলি তার শাখা পয়েন্ট থেকে হয়েছে"
ডাস্টিন

4
আপনি আরও দক্ষতার সাথে প্রথম লাইনটি লিখতে পারেনgit log --all --format='--contains %H' "$file" | xargs git branch
কোজিরো

53

তোমার যা দরকার তা হল

git log --all -- path/to/file/filename

আপনি যদি এখনই শাখাটি জানতে চান তবে আপনি এটি ব্যবহার করতে পারেন:

git log --all --format=%5 -- path/to/file/filename | xargs -I{} -n 1 echo {} found in && git branch --contains {}

তদ্ব্যতীত, আপনার যদি কোনও নামকরণ হয়, আপনি --followগিট লগ কমান্ডের জন্য অন্তর্ভুক্ত করতে চাইতে পারেন ।


16
এটি কমিটগুলি দেখায়, তবে তিনি কোন শাখাটি জিজ্ঞাসা করেছিলেন। --sourceসেখানে একটি যোগ করুন এবং আপনি সোনার।
কার্ল বিলেফেল্ড

ধন্যবাদ, তবে আমি মনে করি না যে এটি প্রতিটি প্রতিশ্রুতির জন্য সমস্ত শাখা দেখায়। তবে এটি সাহায্য করবে।
অ্যাডাম ডাইমিট্রুক

4
সত্য, তবে এই বিশেষ ক্ষেত্রে তিনি কেবল একজনকেই খুঁজছিলেন।
কার্ল বিলেফেল্ড

এসপি নেট পাথের জন্য বিটিডব্লিউটি অ্যাপনাম / নিয়ন্ত্রক / এক্সকন্ট্রোলার.সি এর মতো ফর্ম্যাটে হওয়া উচিত
আলী

8

দেখে মনে হচ্ছে এটি উপযুক্ত সমাধান ব্যতীত এখনও একটি সমস্যা। আমার কাছে মন্তব্য করার মতো পর্যাপ্ত ক্রেডিট নেই, তাই এখানে আমার সামান্য অবদান।

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

অ্যাডাম ডাইমিত্রুকের ২ য় সমাধান আমার পক্ষে মোটেও কার্যকর হয়নি। প্রারম্ভিকদের জন্য, - ফর্ম্যাট =% 5 কি? এটি গিট দ্বারা স্বীকৃত নয়, আমি এটি সম্পর্কে কিছুই খুঁজে পেলাম না এবং এটি অন্য ফর্ম্যাট বিকল্পগুলির সাথে কাজ করার জন্য পেলাম না।

তবে তার 1 ম সমাধানটি - উত্স বিকল্পের সাথে এবং একটি সহজ গ্রেপের সাহায্যে কার্যকর প্রমাণিত হয়েছে:

git log --all --source -- <filename> | grep -o "refs/.*" | sort -u

এটি আমাকে বেশ কয়েকটি দূরবর্তী ট্যাগ এবং শাখা এবং একটি স্থানীয় শাখা দেয়, যেখানে আমি ফাইলে সর্বশেষ পরিবর্তন করেছি। এটি কতটা সম্পূর্ণ তা নিশ্চিত নয়।

@Nemcb এর অনুরোধ অনুসারে আপডেট করুন , অতি সাম্প্রতিক পরিবর্তন অনুসারে শাখাগুলি বাছাই:

প্রথমত, আপনি গ্রেপটিকে "রেফ / হেড /.*" এ পরিবর্তন করতে পারেন যা আপনাকে কেবল স্থানীয় শাখা দেয়। যদি কয়েকটি সংখ্যক শাখা থাকে তবে আপনি প্রত্যেকটির সাম্প্রতিক প্রতিশ্রুতি পরীক্ষা করতে পারেন:

git log -1 <branch> -- <filename>

যদি আরও শাখা থাকে এবং আপনি সত্যই এটি স্বয়ংক্রিয় করতে চান তবে আপনি এই এক-লাইনারে এক্সার্গস, গিট লগ বিন্যাস এবং অন্য সাজানোর সাহায্যে দুটি কমান্ড একত্রিত করতে পারেন:

git log --all --source -- <filename> | grep -o "refs/heads/.*" | sort -u | xargs -I '{}' git log -1 --format=%aI%x20%S '{}' -- <filename> | sort -r

এর ফলে এর ফলাফল হবে:

2020-05-07T15:10:59+02:00 refs/heads/branch1
2020-05-05T16:11:52+02:00 refs/heads/branch3
2020-03-27T11:45:48+00:00 refs/heads/branch2

দুর্দান্ত - আপনাকে ধন্যবাদ। এখন কিভাবে সাম্প্রতিক পরিবর্তন অনুসারে বাছাই সম্পর্কে?
নীলামাকবি 4'20

1

আমি জানি এই প্রশ্নটি প্রাচীন, তবে আমি আমার নিজের সমাধানটি বিকাশের আগে এটিতে ফিরে আসতে থাকি। আমি মনে করি এটি আরও মার্জিত এবং অযাচিত শাখাগুলি মেশানো বেস ফিল্টারগুলি ব্যবহার করার জন্য ধন্যবাদ।

#!/bin/bash

file=$1
base=${2:-master}

b=$(tput bold) # Pretty print
n=$(tput sgr0)

echo "Searching for branches with changes to $file related to the $base branch"

# We look through all the local branches using plumbing
for branch in $(git for-each-ref --format='%(refname:short)' refs/heads/); do
  # We're establishing a shared ancestor between base and branch, to only find forward changes.  
  merge_base=$(git merge-base $base $branch)
  # Check if there are any changes in a given path.
  changes=$(git diff $merge_base..$branch --stat -- $file)

  if [[ ! -z $changes ]]; then
    echo "Branch: ${b}$branch${n} | Merge Base: $merge_base"
    # Show change statistics pretty formatted
    git diff $merge_base..$branch --stat -- $file
  fi
done

যদি আপনি এটিকে git-find-changes(এক্সিকিউটেবল অনুমতি সহ) হিসাবে পাঠাতে থাকেন - তবে আপনি এটির সাথে কল করতে পারেনgit find-changes /path

উদাহরণস্বরূপ আউটপুট git find-changes app/models/

Branch: update_callbacks | Merge base: db07d23b5d9600d88ba0864aca8fe79aad14e55b
 app/models/api/callback_config.rb | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
Branch: repackaging | Merge base: 76578b9b7ee373fbe541a9e39cf93cf5ff150c73
 app/models/order.rb                 | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

খুব আকর্ষণীয় স্ক্রিপ্ট। উত্সাহিত। এটি কি শো-পরিবর্তন বা সন্ধান-পরিবর্তনগুলি?
ভোনসি

@ ভনসি ধন্যবাদ, সঠিক ব্যবহার, সর্বত্র খুঁজে পাওয়া উচিত
মার্সিন র্যাকজকোভস্কি

0

নিম্নলিখিতটি একটি অকার্যকর ব্রুট-ফোর্স পদ্ধতি, তবে আমি আশা করি এটি কার্যকর হবে। আপনি বর্তমানে কোন শাখায় আছেন তা স্যুইচ করবে বলে নিশ্চিত হয়ে নিন যে আপনি যে কোনও অনির্ধারিত পরিবর্তনকে প্রথমে স্থির করেছেন।

for branch in $(git for-each-ref --format="%(refname:short)" refs/heads); do
    git checkout $branch && git grep SOMETHING
done

4
কারণ আপনি যদি পরিবর্তনটি জানেন তবে আপনি ব্যবহার করতে পারেনgit log -S
শেঠ রবার্টসন

আপনি কোন শেল ধরে নিচ্ছেন? বাশ?
পিটার মর্টেনসেন

কোনও বাশিজম নেই, এটি পসিক্সে কাজ করা উচিত। আমি নিশ্চিত না যে for-each-refএখনও এই shortপতাকাটিকে সম্মান করে । বলেছিল, আমার উত্তর উপেক্ষা করুন; অন্য উত্তরগুলি আরও ভাল।
হোয়াইটইঞ্জ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.