Suppose, not hypothetically , that you have a situation where there's a number of distinct hosts backing some Git repository, such as all of the IP addresses of https.git.savannah.gnu.org, and one or more of them seem to be outdated or not working right. As far as I know, Git itself provides very few tools to examine or control which host the fetching process uses; the best option ' git fetch ' has is to select only IPv4 or IPv6 hosts (well, IP addresses).
(Quite reasonably,
git fetch
's verbosity settings are focused on the Git side of things, not on the network side of things. The network is supposed to just work, or at least fail in an obvious way.)
Fortunately we can take advantage of the simple Git HTTP protocol to directly query every server to see the state of their repository (assuming that they respond). Specifically, we want to use dumb client reference discovery to see the commit ID of one or more references (most often branch heads) on each server. To do this we'll need some way of forcing a HTTPS server name to resolve to a specific IP address, but curl has this feature in the form of its '
--resolve
' command line option.
(Curl has two ways to remap a HTTP server name; for using a specific IP address, --resolve is easier or at least more obvious than --connect-to .)
So what we want is something like this (assuming we care about the state of the main branch; you can pick another one):
host=https.git.savannah.gnu.org
url=https://$host/git/emacs.git/info/refs
ipv4=$(dig +short a $host.)
# Curl requires IPv6 addresses as
# '[...]'.
ipv6=$(dig +short aaaa $host. |
sed -e 's/^/[/' -e 's/$/]/')
for i in $ipv4 $ipv6; do
echo $i:
curl -sS -L --resolve $host:443:$i $url |
grep refs/heads/master
done
(I'm using '
dig +short
' in this example as the most convenient general way to get the IPv4 and IPv6 addresses of the host, without anything else.)
At the moment, this says that all of the IP addresses are actually responding to Curl and one IPv6 address is outdated (ie, it has a different commit ID for refs/heads/master, and that commit ID is an old one). I will leave a nicer output format as an exercise to the reader; this is a quick hack that I'm writing down in case I ever need it again (and I hope not to).
(One improvement would be a script that you ran in a repository so it could look up the current head commit and only show you mirror hosts that had a different commit ID for their head.)
Actually doing anything with this information is also left as an exercise to the reader. As far as I know, Git doesn't let you not connect to one specific IP address, so you're left with more system level things like blocking connections to the errant mirror host. Right now, I'm just going to remember to use '
git fetch -4 savannah
' when fetching from the official GNU Emacs repository (and hope that no IPv4 mirror host goes bad).
(If you're operating mirror hosts you can use this approach to monitor whether all of the hosts are sufficiently up to date and check for persistently out of date hosts. Or you may have a better monitoring method, for example based on internal mirroring data.)