मैं फ़ाइल या निर्देशिका के लिए Git शाखाओं को कैसे खोज सकता हूं?


323

Git में, मैं कई शाखाओं में पथ द्वारा फ़ाइल या निर्देशिका कैसे खोज सकता हूं?

मैंने एक शाखा में कुछ लिखा है, लेकिन मुझे याद नहीं है कि कौन सा है। अब मुझे इसे खोजने की जरूरत है।

स्पष्टता : मैं एक ऐसी फाइल की तलाश में हूं, जिसे मैंने अपनी एक शाखा पर बनाया हो। मैं इसे पथ से खोजना चाहता हूं, और इसकी सामग्री से नहीं, क्योंकि मुझे याद नहीं है कि सामग्री क्या है।


मैं सवाल के बारे में स्पष्ट नहीं हूँ। क्या यह फ़ाइल उस शाखा में थी जिसे अब हटा दिया गया है? क्या फ़ाइल को हटाया गया था?
२०'०

जवाबों:


444

git log+ git branchयह तुम्हारे लिए मिल जाएगा:

% git log --all -- somefile

commit 55d2069a092e07c56a6b4d321509ba7620664c63
Author: Dustin Sallings <dustin@spy.net>
Date:   Tue Dec 16 14:16:22 2008 -0800

    added somefile


% git branch -a --contains 55d2069
  otherbranch

ग्लोबिंग का समर्थन करता है, भी:

% git log --all -- '**/my_file.png'

सिंगल कोट्स आवश्यक हैं (कम से कम अगर बैश शेल का उपयोग कर रहे हैं) तो शेल ग्लिट ​​पैटर्न को अपरिवर्तित करने के लिए पास करता है, बजाय इसे विस्तार करने के (यूनिक्स की तरह find)।


2
यह काम करता है यदि आप सटीक मार्ग जानते हैं somefile: उदाहरण के लिए, यदि आपको पथ / फ़ाइल नाम पर regex खोज की आवश्यकता है, तो आप ididak के उत्तर का उपयोग कर सकते हैं।
श्रीवत्सआर

70
git log --all -- **/my_file.png
ग्लोबिंग

3
मैंने इसे थोड़ी अलग समस्या के लिए इस्तेमाल किया। मैं सभी * .sql फ़ाइलों को खोजने की कोशिश कर रहा था जो मैंने एक विशेष शाखा के लिए प्रतिबद्ध की थीं। इसलिए मैंने इस्तेमाल किया git log --grep='branch' --author='me' -- *.sql। एक जादू की तरह काम किया। git संस्करण 1.7.11.1
thepriebe

1
ध्यान दें कि gitkग्लोबिंग का भी समर्थन करता है। यह एक उत्कृष्ट उत्तर है @webmat! यदि आप यह देखना चाहते हैं कि इसे कहाँ से हटाया गया / बनाया गया / आदि, तो आप इसका उपयोग कर सकते हैं git log --all --stat -- **/my_file.png, इस तरह से आपको यह अनुमान लगाने की ज़रूरत नहीं होगी कि आप इसे हटाए गए कमिट से जाँच रहे हैं।
चचेरे भाई

1
@webmat: मैंने जवाब में ग्लोबिंग के बारे में आपकी जानकारी जोड़ने की स्वतंत्रता ली है। इसका उल्लेख करने के लिए धन्यवाद!
साल्स्के

65

git ls-tree मदद कर सकता है। सभी मौजूदा शाखाओं में खोज करने के लिए:

for branch in `git for-each-ref --format="%(refname)" refs/heads`; do
  echo $branch :; git ls-tree -r --name-only $branch | grep '<foo>'
done

इसका लाभ यह है कि आप फ़ाइल नाम के लिए नियमित अभिव्यक्तियों के साथ भी खोज कर सकते हैं।


3
कुछ उम्मीद के मुताबिक उपयोगी टिप्पणियां: (ए) आप शायद "-आर" को "गिट्स-ट्री" में जोड़ना चाहते हैं ताकि यह एक उपनिर्देशिका में होने पर भी फ़ाइल ढूंढ ले। (बी) पहली पंक्ति का एक वैकल्पिक विकल्प "git for-प्रत्येक रेफरी" का उपयोग करना होगा, उदाहरण के लिए "इन ब्रांच के लिए git for-each-ref --format="%(refname)" refs/heads? do" (c) "git ls-tree --name-only" से आउटपुट टियरियर बनेगा (डी) यह आपके जवाब में इंगित करने के लायक हो सकता है कि डस्टिन के समाधान पर इस का एक फायदा है, अर्थात् आपको फ़ाइल नाम जानने की आवश्यकता नहीं है - आप नियमित अभिव्यक्ति द्वारा खोज सकते हैं पथ के किसी भी हिस्से से मेल कर सकते हैं
मार्क लॉन्गेयर

9
मैंने इसे एक स्क्रिप्ट में लपेटा ताकि आप "gitfind.sh <regex>" चला सकें; gist is gist.github.com/62d981890eccb48a99dc
Handyman5

3
ध्यान दें कि यह केवल स्थानीय शाखाओं में खोज करेगा । दूरस्थ-ट्रैकिंग शाखाओं की खोज करने के लिए refs/remotesइसके बजाय का उपयोग करें refs/heads। सब कुछ खोजने के लिए (स्थानीय शाखाएं, रिमोट-ट्रैकिंग शाखाएं और टैग), बस उपयोग करें refs/
साल्स्के

19

हालांकि इडिडक की प्रतिक्रिया बहुत अच्छी है, और अप्रेंटिस 5 इसका उपयोग करने के लिए एक स्क्रिप्ट प्रदान करता है, मैंने पाया कि यह उस दृष्टिकोण का उपयोग करने के लिए थोड़ा प्रतिबंधित है।

कभी-कभी आपको किसी ऐसी चीज की तलाश करने की जरूरत होती है, जो समय के साथ दिखाई दे / गायब हो जाए, तो क्यों न सभी कमिट के खिलाफ खोज की जाए? इसके अलावा, कभी-कभी आपको एक क्रिया प्रतिक्रिया की आवश्यकता होती है, और अन्य समय केवल मैच करते हैं। यहां उन विकल्पों के दो संस्करण दिए गए हैं। अपने रास्ते पर इन लिपियों रखो:

Git-ढूंढें फ़ाइल

for branch in $(git rev-list --all)
do
  if (git ls-tree -r --name-only $branch | grep --quiet "$1")
  then
     echo $branch
  fi
done

Git-खोज-फ़ाइल-वर्बोज़

for branch in $(git rev-list --all)
do
  git ls-tree -r --name-only $branch | grep "$1" | sed 's/^/'$branch': /'
done

अब आप कर सकते हैं

$ git find-file <regex>
sha1
sha2

$ git find-file-verbose <regex>
sha1: path/to/<regex>/searched
sha1: path/to/another/<regex>/in/same/sha
sha2: path/to/other/<regex>/in/other/sha

यह देखें कि गेटअप का उपयोग करके आप उस स्क्रिप्ट को सभी कमिट्स, रेफ्स, रेफ्स / हेड्स, वर्बोज़, इत्यादि की खोज के लिए बदल सकते हैं।

$ git find-file <regex>
$ git find-file --verbose <regex>
$ git find-file --verbose --decorated --color <regex>

संभावित क्रियान्वयन के लिए चेकआउट https://github.com/albfan/git-find-file


क्या आपका मतलब था "अब आप git-find-file <regex>" कर सकते हैं? मुझे यह काम कर गया, धन्यवाद!
एलिय्याह लिन

1
मुझे व्यक्तिगत रूप से $ (git Branch-cut -c 3-) का उपयोग करने के बजाय $ (git rev-list --all) का उपयोग करना अधिक उपयोगी लगता है। मुझे कमिट्स का एक गुच्छा खोजने की परवाह नहीं है, मैं नामित शाखाओं के बारे में परवाह करता हूं।
कैम्पाड्रेनलिन

मैंने भी लिपियों का उपयोग $ (git ब्रांच | कट -c 3-) का उपयोग करने के लिए किया था क्योंकि सभी कमिटों पर लूप बहुत अधिक धीमा था।
I4h

सभी उपद्रव देखा मैं इसके लिए एक रेपो बनाने के लायक है। github.com/albfan/git-find-file । मेरे पास कुछ मुद्दे हैं, बेझिझक और अधिक प्रस्ताव करें या इसके लिए पीआर भेजें।
एल्बफैन

1
पथ पर स्क्रिप्ट स्थापित करने में @lumbric बॉक्स से बाहर काम करता है, इसकी एक विशेषता है
एल्बफैन

10

आप उपयोग कर सकते हैं gitk --allऔर "टचिंग पाथ्स" के लिए खोज कर सकते हैं और जिस पाथनेम में आपकी रुचि है, वह है।


3
जैसा कि कहा गया है, gitk --all का उपयोग करें, फिर देखें में | नया दृश्य, सभी शाखाओं को सक्षम करें। फिर अपने खोज मापदंड सेट करें: फ़ाइल नाम (वाइल्ड कार्ड के साथ) अंत में: ठीक है।
माइक डब्ल्यूडब्ल्यू

8

उपयोग करने के लिए इसे कॉपी और पेस्ट करें git find-file SEARCHPATTERN

सभी खोजी गई शाखाओं की छपाई:

git config --global alias.find-file '!for branch in `git for-each-ref --format="%(refname)" refs/heads`; do echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; done; :'

परिणामों के साथ केवल शाखाएँ प्रिंट करें:

git config --global alias.find-file '!for branch in $(git for-each-ref --format="%(refname)" refs/heads); do if git ls-tree -r --name-only $branch | grep "$1" > /dev/null; then  echo "${branch}:"; git ls-tree -r --name-only $branch | nl -bn -w3 | grep "$1"; fi; done; :'

ये आदेश कुछ न्यूनतम शेल स्क्रिप्ट को सीधे आपके वैश्विक~/.gitconfig रूप से उपनाम के रूप में जोड़ देंगे ।


यह केवल मास्टर शाखा में खोज रहा है
नसिफ इम्तियाज ओही

यह सभी स्थानीय शाखाओं में खोज करता है
लियोनार्डो हरेरा

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.