Instead of messing around with bash
and tr
and cut
and xargs
and all the whitespace and word-splitting and glob issues that bash brings, you could use a language more suited to the job...and one that includes a library module for interacting with git repos. For example, perl with the Git::Raw module.
Here's a very simple one-liner example (although it's worth noting that Git::Raw
is capable of much more than this and you'd probably be better off writing a stand-alone perl script that uses the module):
I've added newlines and indentation for readability. It works as-is, or all squished up on one line.
$ perl -MGit::Raw -l -e '
foreach my $d (@ARGV) {
$d =~ s/\.git$//;
next unless -d "$d/.git";
my $repo = Git::Raw::Repository->open($d);
print $d;
foreach my $r ($repo->remotes()) {
print $r->url
};
print "";
}' */.git
In English, that's:
- Open each repo listed on the command line, ignoring directories that aren't actually git repos,
- iterate over the repo's remotes and print their URLs.
Sample output. I ran the one-liner above in a directory that I sometimes use to clone various repos from github. I wrote the one-liner to print the directory name before the list of remotes belonging to that repo, and a blank line after each directory processed.
mgetty
https://github.com/Distrotech/mgetty.git
roxterm
https://github.com/realh/roxterm.git
zpool-iostat-viz
https://github.com/chadmiller/zpool-iostat-viz.git
Note: Git::Raw
is not included with perl, it needs to be installed with cpan
or via a distro package (e.g. on Debian etc, apt-get install libgit-raw-perl
. Other distros probably have it too). The module is a perl wrapper around libgit2 so installing it manually with CPAN will require gcc
and the libgit2 development library & headers installed.
Also worth noting: even without Git::Raw
parsing the output of git
with perl (or almost any other language) is going to be a lot easier and a lot less error-prone than doing it in bash. Perl in particular is designed for string matching and manipulation, so doing what you're trying to do in bash is trivial in perl.
BTW, if you prefer python
, you may want to look at GitPython instead. On Debian etc, you can install it with apt-get install python3-git
, and it's probably packaged for other distros too. This one doesn't use libgit2
, it's a wrapper around the git
command, similar to what you're trying to do in bash.
I somehow missed this yesterday, but the libgit2
web site says that pygit2 does for python what Git::Raw
does for perl (i.e. it uses the C libgit2 library - so will be faster than forking git
whenever needed, and avoids the risk of output-parsing problems). Debian package is python3-pygit2
, and it's probably packaged for other distros too.
ls
intoxargs
is very dangerous, and the output ofls
shouldn't be used for anything except displaying file/directory listings for a human to read. See Why not parsels
(and what to do instead)? – cas Aug 22 '23 at 12:09