You need git ls-remote :
NAME
git-ls-remote - List of links in the remote repository
SYNTAX
git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>] [-q | --quiet] [--exit-code] [--get-url] [--symref] [<repository> [<refs>...]]
DESCRIPTION
Displays links available in the remote repository along with associated commit identifiers.
So it works like:
% git ls-remote origin af51dfb080728117d898e1d0a10e3fe01ed67063 HEAD 6a60cc68a2953f1a62b0dca641eb29509b5b6e8c refs/heads/expdate-fix af51dfb080728117d898e1d0a10e3fe01ed67063 refs/heads/master 4c42e43b4ccfd37074d115f6e9a694ddb8b70d55 refs/heads/redux fd18a67bbc5cbf8aa6cda136afa4e5c20ed2d522 refs/heads/rest 7ad17cdf8b0dcd1a29a1795a363279fb3c76ac66 refs/tags/test.key be0b2d6881902600fb3d6686c10d0a47f1e6751a refs/tags/test.pub
To get only branches (heads), you need to narrow the refspec:
% git ls-remote origin 'refs/heads/*' 6a60cc68a2953f1a62b0dca641eb29509b5b6e8c refs/heads/expdate-fix af51dfb080728117d898e1d0a10e3fe01ed67063 refs/heads/master 4c42e43b4ccfd37074d115f6e9a694ddb8b70d55 refs/heads/redux fd18a67bbc5cbf8aa6cda136afa4e5c20ed2d522 refs/heads/rest
Now you can script around this output, for example
git ls-remote origin 'refs/heads/*' | while read sha ref; do # test if $sha is merged done
To remove a branch, you need to "click on it", for example, in
git push origin :refs/heads/feature-x
(pay attention to the empty line to the left of ":", which determines what to click on what is on the right).
So we get something like
#!/bin/sh set -e -u git ls-remote origin 'refs/heads/*' | while read sha ref; do
Note that we use the built-in printf shell to distinguish between the names of the links we return with a NULL ASCII character, and then pass -0 to xargs to wait for null terminated input. So we are working on funky link names (containing spaces, etc.).
Some explanations:
If git cat-file -t <object_sha1_name> cannot find the object with the specified name SHA1 in the local repository, it exits with a non-zero exit code and prints
fatal: git cat-file: could not get object information
to his stderr.
So, to check if the history pointed to by the remote reflector exists, in the local one we run git cat-file -t in the name SHA1 of the object that it points to, grab the combined output of this command, and then check whether it comes out with a non-zero exit code ( $? -ne 0 ) and whether the missing object displays an error message ( ${VAR#PATTERN} removes the prefix corresponding to PATTERN from the contents of the VAR variable and returns the resulting value).
If a story in which the remote reflex does not exist does not exist in the local repository, it cannot be combined with any of the local links by definition, so if we find such a reflex, we will skip further testing with git branch --merged .