Hoe kan ik in Git-takken zoeken naar een bestand of map?

Hoe kan ik in Git naar een bestand of map zoeken op pad over een aantal branches?

Ik heb iets in een branch geschreven, maar ik weet niet meer welke. Nu moet ik het vinden.

Verduidelijking: ik ben op zoek naar een bestand dat ik op een van mijn branches heb gemaakt. Ik zou het willen vinden op pad, en niet op de inhoud, omdat ik niet meer weet wat de inhoud is.


Antwoord 1, autoriteit 100%

git log+ git branchzullen het voor je vinden:

% git log --all -- somefile
commit 55d2069a092e07c56a6b4d321509ba7620664c63
Author: Dustin Sallings <[email protected]>
Date:   Tue Dec 16 14:16:22 2008 -0800
    added somefile
% git branch -a --contains 55d2069
  otherbranch

Ondersteunt ook globbing:

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

De enkele aanhalingstekens zijn nodig (tenminste als je de Bash-shell gebruikt), zodat de shell het glob-patroon doorgeeft aan git ongewijzigd, in plaats van het uit te breiden (net als bij Unix find).


Antwoord 2, autoriteit 14%

git ls-tree zou kunnen helpen. Om in alle bestaande vestigingen te zoeken:

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

Het voordeel hiervan is dat je ook met reguliere expressies naar de bestandsnaam kunt zoeken.


Antwoord 3, autoriteit 4%

Hoewel ididaks reactiebest cool is, en Handyman5een script levert om het te gebruiken, Ik vond het een beetje beperkt om die aanpak te gebruiken.

Soms moet je zoeken naar iets dat in de loop van de tijd kan verschijnen/verdwijnen, dus waarom zou je niet op alle commits zoeken? Daarnaast heb je soms een uitgebreid antwoord nodig, en soms alleen commit-overeenkomsten. Hier zijn twee versies van die opties. Zet deze scripts op je pad:

git-find-file

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-find-file-verbose

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

Nu kunt u doen

$ 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

Zie dat je met behulp van getoptdat script kunt wijzigen om afwisselend te zoeken naar alle commits, refs , refs/heads, uitgebreid geweest, enz.

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

Afrekenen https://github.com/albfan/git-find-filevoor een mogelijke implementatie.


Antwoord 4, autoriteit 2%

Je zou gitk --allkunnen gebruiken en zoeken naar commits “touching paths” en de padnaam waarin je geïnteresseerd bent.


Antwoord 5, autoriteit 2%

Kopiëren & plak dit om git find-file SEARCHPATTERN

te gebruiken

Alle gezochte vestigingen afdrukken:

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; :'

Alleen takken met resultaten afdrukken:

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; :'

Deze commando’s zullen enkele minimale shell-scripts rechtstreeks aan uw ~/.gitconfigtoevoegen als globale git-alias.


Antwoord 6

Een behoorlijk fatsoenlijke implementatie van het findcommando voor Git repositories kan hier gevonden worden:

https://github.com/mirabilos/git-find

Other episodes