ls-remote: the --exit-code option reports "no matching refs"

The "git ls-remote" uses its exit status to indicate if it successfully talked with the remote repository. A new option "--exit-code" makes the command exit with status "2" when there is no refs to be listed, even when the command successfully talked with the remote repository. This way, the caller can tell if we failed to contact the remote, or the remote did not have what we wanted to see. Of course, you can inspect the output from the command, which has been and will continue to be a valid way to check the same thing. Signed-off-by: Michael Schubert <mschub@elegosoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Schubert committed May 18, 2011 at 22:06 UTC a87247731e46255567ec58df940adb697e5b95a8
3 files changed +40 -3
Documentation/git-ls-remote.txt
+7 -1
@@ -10,7 +10,7 @@ SYNOPSIS
10 --------
11 [verse]
12 'git ls-remote' [--heads] [--tags] [-u <exec> | --upload-pack <exec>]
13 - <repository> [<refs>...]
13 + [--exit-code] <repository> [<refs>...]
14
15 DESCRIPTION
16 -----------
@@ -36,6 +36,12 @@ OPTIONS
36 SSH and where the SSH daemon does not use the PATH configured by the
37 user.
38
39 +--exit-code::
40 + Exit with status "2" when no matching refs are found in the remote
41 + repository. Usually the command exits with status "0" to indicate
42 + it successfully talked with the remote repository, whether it
43 + found any matching refs.
44 +
45 <repository>::
46 Location of the repository. The shorthand defined in
47 $GIT_DIR/branches/ can be used. Use "." (dot) to list references in
builtin/ls-remote.c
+9 -2
@@ -5,7 +5,7 @@
5
6 static const char ls_remote_usage[] =
7 "git ls-remote [--heads] [--tags] [-u <exec> | --upload-pack <exec>]\n"
8 -" [-q|--quiet] [<repository> [<refs>...]]";
8 +" [-q|--quiet] [--exit-code] [<repository> [<refs>...]]";
9
10 /*
11 * Is there one among the list of patterns that match the tail part
@@ -35,6 +35,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
35 unsigned flags = 0;
36 int get_url = 0;
37 int quiet = 0;
38 + int status = 0;
39 const char *uploadpack = NULL;
40 const char **pattern = NULL;
41
@@ -74,6 +75,11 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
75 get_url = 1;
76 continue;
77 }
78 + if (!strcmp("--exit-code", arg)) {
79 + /* return this code if no refs are reported */
80 + status = 2;
81 + continue;
82 + }
83 usage(ls_remote_usage);
84 }
85 dest = arg;
@@ -121,6 +127,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
127 if (!tail_match(pattern, ref->name))
128 continue;
129 printf("%s %s\n", sha1_to_hex(ref->old_sha1), ref->name);
130 + status = 0; /* we found something */
131 }
125 - return 0;
132 + return status;
133 }
t/t5512-ls-remote.sh
+24
@@ -123,4 +123,28 @@ test_expect_success 'confuses pattern as remote when no remote specified' '
123
124 '
125
126 +test_expect_success 'die with non-2 for wrong repository even with --exit-code' '
127 + git ls-remote --exit-code ./no-such-repository ;# not &&
128 + status=$? &&
129 + test $status != 2 && test $status != 0
130 +'
131 +
132 +test_expect_success 'Report success even when nothing matches' '
133 + git ls-remote other.git "refs/nsn/*" >actual &&
134 + >expect &&
135 + test_cmp expect actual
136 +'
137 +
138 +test_expect_success 'Report no-match with --exit-code' '
139 + test_expect_code 2 git ls-remote --exit-code other.git "refs/nsn/*" >actual &&
140 + >expect &&
141 + test_cmp expect actual
142 +'
143 +
144 +test_expect_success 'Report match with --exit-code' '
145 + git ls-remote --exit-code other.git "refs/tags/*" >actual &&
146 + git ls-remote . tags/mark >expect &&
147 + test_cmp expect actual
148 +'
149 +
150 test_done