git "ping": check if remote repository exists

77

14

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

Posted 2010-12-31T00:34:11.600

Reputation: 2 450

The answer should be: No, there is no better way. – Timo – 2018-08-18T07:09:44.950

4It seems like a fine choice. The overhead of the “extra work” of fetching and formatting the list of refs (which is then sent to /dev/null) should be fairly small. – Chris Johnsen – 2010-12-31T00:57:22.937

Answers

73

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

Peter Eisentraut

Posted 2010-12-31T00:34:11.600

Reputation: 6 330

yep, this seems to work, but can you, please, provide some explanation and tell if this 100% that I can clone that repo – vladkras – 2016-10-24T09:32:02.603

16

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"

Oleksiy Chystoprudov

Posted 2010-12-31T00:34:11.600

Reputation: 261

-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 – 2015-05-16T22:20:22.253

3

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

ony

Posted 2010-12-31T00:34:11.600

Reputation: 181

It hangs forever. – Timo – 2018-07-18T12:19:07.607

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 – 2018-08-17T05:29:45.627

0

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 is probably nonexistent, as git will still exit with error-level 0 on non-matching 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 ref checked 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

Posted 2010-12-31T00:34:11.600

Reputation: 372