101

I'd like to know whether a remote repository exists. Here's what I came up with:

git ls-remote -h "$REPO_URL" &> /dev/null

Is there any better way?

Jo Liss
  • 4,279

6 Answers6

103

I think the git ls-remote command is pretty much made for that purpose.

Zebiano
  • 103
23

If you use --exit-code argument you can skip sending output to null. It will return something only in case of error.

Also, you can use -h argument to show only heads references.

git ls-remote --exit-code -h "$REPO_URL"
Jawa
  • 3,649
  • 3
    -h is a great idea. However, --exit-code is not the right choice here. The man page says: Exit with status "2" when no matching refs are found in the remote repository. This means that git ls-remote --exit-code "$REPO_URL" will fail for an empty repo that has only just been initialized with git init. – Jo Liss May 16 '15 at 22:20
5

TL;DR:

git ls-remote is the way, here is a shell-ready function for quick access:

  ## Returns errlvl 0 if $1 is a reachable git remote url 
  git-remote-url-reachable() {
      git ls-remote "$1" CHECK_GIT_REMOTE_URL_REACHABILITY >/dev/null 2>&1
  }

Usage:

if git-remote-url-reachable "$url"; then
   ## code
fi

What is it doing ?

This is just a convenient mash-up of all the comments/solutions previously stated with some small tweaks, a bash copy-paste ready function and usage code sample to make it crystal clear. You'll note that:

  • it limits output as the reference checked (here CHECK_GIT_REMOTE_URL_REACHABILITY) is probably nonexistent on the remote server, and git doesn't have anything to answer back. We rely on the fact that git will still exit with error-level 0 on non-existing ref. The only difference here is that there are slightly less output to transfer on the network compared to ask for HEAD (and much less than not asking for a ref or even limiting to only heads), and this is also less output to cast in /dev/null (but this last one is taking negligible time anyway)

  • the name of the ref checked that was chosen (which is CHECK_GIT_REMOTE_URL_REACHABILITY) makes it clear we are probing for existence, this could help if you want to be polite with the administrators of the server you are probing and give them a chance to understand why they receive these probes if they monitor anything.

vaab
  • 452
  • 2
    as long as you're using bash, this is syntax is a little cleaner: &>/dev/null – Chris Noe Apr 01 '20 at 12:29
  • What does CHECK_GIT_REMOTE_URL_REACHABILITY mean? What is it defined as, and where does it come from? I can't find anything about it anywhere. – Gabriel Staples Aug 09 '22 at 21:59
  • @GabrielStaples This is the arbitrary reference name mentioned in the answer, in the two point of the section "What is it doing". I tried to edit my answer to make this clearer. – vaab Aug 10 '22 at 16:45
4

You can narrow output by using something like git ls-remote "$REPO_URL" HEAD

ony
  • 211
  • 2
    It hangs forever. – Timo Jul 18 '18 at 12:19
  • 1
    @Timo, then you probably have either unresponsive server or your connection or broken git client. For example network port is filtered. Further investigations is kinda similar to what happens when your ping doesn't respond :) . For example you can try check if you get connection established via netcat or openssl s_client or tracepath. – ony Aug 17 '18 at 05:29
  • 1
    @Timo, it doesn't actually hang "forever". Rather, if the git server is up and available, it returns in 3 to 30 seconds, and if the server is down or unavailable, it returns in about 2.5 minutes. – Gabriel Staples Aug 09 '22 at 19:55
2

By disabling asking for credentials, then listing the remote head only:

export GIT_TERMINAL_PROMPT=0
git ls-remote "${repo}" HEAD &> /dev/null
0

The fastest and most-reliable way I've found in bash is this:

if timeout 30s git ls-remote --tags > /dev/null 2>&1; then
    # Note: it takes 2~4 sec to get to here.
    echo "git server IS available"
else
    # Note: it takes 30 seconds (as specified by `timeout`) to get to here.
    echo "git server is NOT available"
fi

Optionally increase the timeout 30s value to a larger number of seconds if your server is unable to respond under normal conditions within that amount of time.

For a full and detailed explanation, see my main answers here:

  1. Stack Overflow: Check if git remote exists before first push
  2. Stack Overflow: Fastest way to check if a git server is available.