Is there a way in which I can see all the git repositories that exist on my machine? Any command for that?
If you are in Linux find / -name ".git"
, otherwise there is no way, they are standard directories, just use your OS file/folder find program to find .git
named folders.
for d in `find / -name ".git"`; do cd $d/..; echo `pwd`:; git status; echo; done
–
Filibeg -name ".git"
doesn't work for me, it has to be -name "*.git"
to get a wildcard match (quoted to avoid it being expanded by the shell). I'd update the above command to: find / -type d -name "*.git' -print -prune
–
Zamindar /Users/USER/somedir
and then again at the "absolute" /System/Volumes/Data/Users/USER/somedir
–
Inconsistent Git Bash
, which you might have installed. –
Outpatient ORIGINAL ANSWER: This works pretty well from Windows Powershell:
Get-ChildItem . -Attributes Directory+Hidden -ErrorAction SilentlyContinue -Include ".git" -Recurse
EDIT #1: -Filter is twice as fast as -Include. Here is that solution:
Get-ChildItem . -Attributes Directory+Hidden -ErrorAction SilentlyContinue -Filter ".git" -Recurse
EDIT #2: Keith E. Truesdell mentioned sending the output to a file. See his comment for that solution. I prefer console output. But his comment got me thinking that I prefer just the full path, not the whole mess that is returned by default. If you want that just the full path, use the following:
Get-ChildItem . -Attributes Directory+Hidden -ErrorAction SilentlyContinue -Filter ".git" -Recurse | % { Write-Host $_.FullName }
FINAL NOTE: The above solutions only return Git repositories under the current directory. If you want ALL repositories on a drive, you should run the command once from the root of each drive.
Get-ChildItem . -Attributes Directory,Directory+Hidden -ErrorAction SilentlyContinue -Include ".git" -Recurse | Out-File -FilePath C:\Dev\GitRepoList.txt
–
Progeny -Force
shows hidden files, so you can use Get-ChildItem . -Name '.git' -Force -Recurse
Note that using -Name
causes it to return a string instead of objects. You can get around this by using where
like gci . -Force -Recurse | where { $_.Name -eq ".git" }
–
Streeter On *nix, this will also find any --bare
repositories.
find / -name "*.git" -type d
name.git
thats just a convention, that I for example, don't follow. –
Hertha find
those repos? –
Hebephrenia git rev-parse --git-dir
succeeds. –
Pythoness Git repositories all have HEAD
, refs
and objects
entries.
on GNU/anything,
find -name HEAD -execdir test -e refs -a -e objects \; -printf %h\\n
Just checking for .git
will miss many bare repos and submodules.
To go full-paranoid on the checking you can ask git to do all its own checks before printing,
find -name HEAD -execdir test -e refs -a -e objects \; \
-execdir sh -ec 'GIT_DIR=$PWD git rev-parse --absolute-git-dir 2>&-' \;
(edit: I thought the .git/config
file was necessary, turns out it's not, so the absolute minimum git init newrepo
is
mkdir -p newrepo/.git/{objects,refs}
echo ref: refs/heads/master >newrepo/.git/HEAD
)
On Linux and OS X the following command is possibly the fastest (ignoring repositories without .git
) when the root directory of find
is /
:
find / -name .git -exec dirname {} \; -prune
But for roots that have mostly repositories underneath, the following is probably the fastest (you may want to replace /
with .
or another root):
find / -type d -exec test -d {}/.git \; -prune -print
Quick explanation of the primaries of find
used (since no operators are present here, -and
is implicit, i.e., for each visited node primaries are evaluated left to right until one of them evaluates to false
):
-name
istrue
if the name matches (often, but not here, with wildcards)-exec
executes a command terminated by;
(which is escaped by\
to avoid interpretation by the shell), and istrue
if the return status is0
(i.e., OK). The current node is available as{}
(which needs no escaping)-prune
is alwaystrue
, and causes all child nodes to be skipped-type d
istrue
for directories-print
is needed here because if-exec
is present it is not implicitly appended
find
on a big tree, and yours was faster by 3.6% (46.6 seconds vs 48.4), so, yes, faster, but not “much faster” (on a MacBook Pro 2018 with Big Sur) –
Siftings find / -name .git -exec dirname {} + -prune
–
Rivi \;
with +
so that a dirname
process isn't started for every repository. You are right that in this case, I was wrong saying it's much faster. I tend to have a horror reflex everytime I see a find command not taking advantage of commands that accept file lists as arguments. –
Rivi On Linux, a faster way would be:
locate -r "\.git$"
assuming you keep locate's database updated with sudo updatedb
A simple PowerShell version:
Get-ChildItem . -Recurse -Hidden .git
C:\users\<username>\PrintHood
Also, I found it useful to add an output to a file and since I only cared about the path (as this script gets a bunch of info) to also filter only for the path/directory info. Get-ChildItem . -Recurse -Hidden .git | Out-file -FilePath C:\Dev\GitRepoList.txt
–
Progeny On Linux, try this command with root permission:
find / | grep \\.git$
this just searchs every files that end with .git ... you can do it with searching tools in Windows, Linux etc...
find
output everything then filtering with grep
. I would rather use --name "*.git"
–
Estrange /
tree for the second to grep, when the first one can do everything and avoid the huge useless IO use. Not a real difference for the user normally, but for big filesystems it might make a difference. –
Hertha Small variation from Eric Burcham's answer. That answer adds \.git to end, this one doesn't.
Get-ChildItem . -Attributes Directory+Hidden -ErrorAction SilentlyContinue -Filter ".git" -Recurse | % { Write-Host $_.Parent.FullName }
I use this command at the beginning of the day. It simply adds a few git commands to the above. For some reason, our git repository works best if one runs a fetch then pull, don't know why. And we have a lot of submodules for some reason. Anyway, put what you need in between the {}'s.
push-location; Get-ChildItem . -Attributes Directory+Hidden -ErrorAction SilentlyContinue -Filter ".git" -Recurse | % { cd $_.parent.fullname; write-host '*************'; $(get-location).path; git fetch; git pull; git checkout .; git clean -f; git submodule update; git status; write-host '*************'; write-host ' '; }; pop-location
For Linux:
dir="/home/${USER}"
dir_not="${dir}/miniconda3"
find /home/aeug -type d -iname ".git" -o -path "${dir_not}" -prune | xargs -0 echo
I wanted the answer to this and for it to be as fast as possible. In particular I want to search a home directory for workspaces with the following constraints:
- home directories may have VMWare shared mounts in them. No need to search outside of the current filesystem
- some directories are inaccessible to the user. These can be skipped
- directory names starting with
.
can be skipped - nested git workspaces can be skipped
With this in mind, I am using this GNU find
command:
find . \
-mount \
! -type d -prune -o \
! -executable -prune -o \
-name '.?*' -prune -o \
-execdir test -f '{}/.git/HEAD' \; -print -prune
This takes care to prune directories from the search as early as possible. Also, once a directory is positively confirmed as a git workspace, then it too is pruned. This returns the list of workspaces almost immediately (34ms on my home directory).
If you're using BSD find
(e.g. MacOS), this does the same thing:
find . \
-mount \
! -type d -prune -o \
! -perm -g+x -prune -o \
-name '.?*' -prune -o \
-execdir test -f '{}/.git/HEAD' \; -print -prune
The simplest way was not yet listed: git config --get-all safe.directory
Ubuntu
find catalogue/archaeology/ -path '*/objects' -execdir git -C '{}' rev-parse --git-dir \; 2>&-
© 2022 - 2024 — McMap. All rights reserved.