Reputation: 1607
I'm writing a bash script and I need a test to see whether a given remote exists.
Suppose, for concreteness, that I want to test whether the remote faraway
exists. If I've pushed something to faraway
, I can do if [ -d .git/refs/remotes/faraway ]; then ...
. But as far as I can see, the alias faraway
can still be defined even if .git/refs/remotes/faraway
does not exist.
One other option is to parse through the output of git remote
and see if faraway
appears there. But I'm wondering whether there is an easier way of checking whether faraway
is defined, regardless of whether .git/refs/remotes/faraway/
exists.
Upvotes: 43
Views: 30624
Reputation: 11
If the remote is defined in .git/config, you can avoid pinging the remote server with git remote.
if git remote | grep -e "^faraway$" > /dev/null; then ... fi
The ^ and $ prevent matching similar names like longagoandfaraway.
Upvotes: 0
Reputation: 44244
One thought: You could test exit status on git ls-remote faraway
. This will actually force communication with the remote, instead of just looking for its presence or absence locally.
if ! git ls-remote --exit-code faraway > /dev/null 2>&1; then
....
fi
Upvotes: 50
Reputation: 52767
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 answer here: Fastest way to check if a git server is available.
Note that I do not recommend using the --exit-code
option, due to what @Jo Liss said here:
-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 thatgit ls-remote --exit-code "$REPO_URL"
will fail for an empty repo that has only just been initialized withgit init
.
Also, I most-definitely recommend using --tags
over -h
or --heads
in order to make this command as fast as possible when the git server is available. See my speed comparisons in my question here. Here they are again for your convenience. Using --tags
consistently takes 2~4 sec, whereas --heads
takes 3~10 sec.
# 4~25 sec
# 218467 lines
time git ls-remote | wc -l
# 3~18 sec
# 218076 lines
time git ls-remote --refs | wc -l
# 3~10 sec
# 43337 lines
time git ls-remote --heads | wc -l
# 2~4 sec
# 9769 lines
time git ls-remote --tags | wc -l
# 0.002 ~ 0.008 sec
# But worthless! It passes even if the remote is not available!
time git ls-remote --get-url
# 4~25 sec
# 1 line
time git ls-remote origin HEAD
See also my comment here:
@torek, for your reference, it's a massive > 100 GB GitHub Enterprise mono-repo, with 218467 objects returned by
git ls-remote
. I tested repeatedly, andgit ls-remote --tags
is very consistently a lot faster thantime git ls-remote --symref origin HEAD
. I suspect it's because there are fewer--tags
than--heads
to search through and the latter requires finding all--heads
and then linearly searching through them to find the match toHEAD
. (I'm guessing on the linear search assumption here--trying to explain observations I am seeing, not predict observations I am not).
Upvotes: 2
Reputation: 27800
Another way to check if faraway
is defined in .git/config
:
if git config remote.faraway.url > /dev/null; then
…
fi
To check if faraway
isn't defined, prefix the condition with !
:
if ! git config remote.faraway.url > /dev/null; then
…
fi
Upvotes: 48
Reputation: 5363
If the remote is defined in .git/config
, you can avoid pinging the remote server with git remote
.
if git remote | grep faraway > /dev/null; then
...
fi
Upvotes: 11