blob: 6ef519514bd1a4dfc39b149967ee60dcf14dfbaa [file] [log] [blame]
Daniel Barkalow18f7c512007-10-29 21:05:43 -04001#include "builtin.h"
2#include "cache.h"
3#include "transport.h"
Harald Nordgren1fb20df2018-04-09 03:42:26 +02004#include "ref-filter.h"
Daniel Barkalow18f7c512007-10-29 21:05:43 -04005#include "remote.h"
Brandon Williamsb4be7412018-03-15 10:31:24 -07006#include "refs.h"
Daniel Barkalow18f7c512007-10-29 21:05:43 -04007
Thomas Gummererba5f28b2016-01-19 00:20:49 +01008static const char * const ls_remote_usage[] = {
9 N_("git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
Thomas Gummerer99c08d42016-01-19 00:20:50 +010010 " [-q | --quiet] [--exit-code] [--get-url]\n"
11 " [--symref] [<repository> [<refs>...]]"),
Thomas Gummererba5f28b2016-01-19 00:20:49 +010012 NULL
13};
Daniel Barkalow18f7c512007-10-29 21:05:43 -040014
Junio C Hamano2ea7fe02007-12-08 22:52:59 -080015/*
Junio C Hamano3d3c4f52007-12-09 12:16:55 -080016 * Is there one among the list of patterns that match the tail part
17 * of the path?
Junio C Hamano2ea7fe02007-12-08 22:52:59 -080018 */
Junio C Hamano2ea7fe02007-12-08 22:52:59 -080019static int tail_match(const char **pattern, const char *path)
20{
Junio C Hamano2ea7fe02007-12-08 22:52:59 -080021 const char *p;
Jeff King7f897b62017-03-28 15:46:30 -040022 char *pathbuf;
Junio C Hamano2ea7fe02007-12-08 22:52:59 -080023
Junio C Hamano3d3c4f52007-12-09 12:16:55 -080024 if (!pattern)
Junio C Hamano2ea7fe02007-12-08 22:52:59 -080025 return 1; /* no restriction */
26
Jeff King7f897b62017-03-28 15:46:30 -040027 pathbuf = xstrfmt("/%s", path);
Junio C Hamano3d3c4f52007-12-09 12:16:55 -080028 while ((p = *(pattern++)) != NULL) {
Ævar Arnfjörð Bjarmason55d34262017-06-22 21:38:08 +000029 if (!wildmatch(p, pathbuf, 0)) {
Jeff King7f897b62017-03-28 15:46:30 -040030 free(pathbuf);
Junio C Hamano3d3c4f52007-12-09 12:16:55 -080031 return 1;
Jeff King7f897b62017-03-28 15:46:30 -040032 }
Junio C Hamano2ea7fe02007-12-08 22:52:59 -080033 }
Jeff King7f897b62017-03-28 15:46:30 -040034 free(pathbuf);
Junio C Hamano2ea7fe02007-12-08 22:52:59 -080035 return 0;
36}
37
Daniel Barkalow8951d7c2007-11-04 15:51:17 -050038int cmd_ls_remote(int argc, const char **argv, const char *prefix)
Daniel Barkalow18f7c512007-10-29 21:05:43 -040039{
Daniel Barkalow18f7c512007-10-29 21:05:43 -040040 const char *dest = NULL;
Daniel Barkalow18f7c512007-10-29 21:05:43 -040041 unsigned flags = 0;
Uwe Kleine-König45781ad2011-03-01 10:21:36 +010042 int get_url = 0;
Tay Ray Chuancefb2a52010-05-12 01:20:23 +080043 int quiet = 0;
Michael Schuberta8724772011-05-18 22:06:00 +020044 int status = 0;
Thomas Gummerer99c08d42016-01-19 00:20:50 +010045 int show_symref_target = 0;
Daniel Barkalow18f7c512007-10-29 21:05:43 -040046 const char *uploadpack = NULL;
Junio C Hamano2ea7fe02007-12-08 22:52:59 -080047 const char **pattern = NULL;
Brandon Williamsb4be7412018-03-15 10:31:24 -070048 struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
Harald Nordgren1fb20df2018-04-09 03:42:26 +020049 int i;
Brandon Williamsff473222018-04-23 15:46:23 -070050 struct string_list server_options = STRING_LIST_INIT_DUP;
Daniel Barkalow18f7c512007-10-29 21:05:43 -040051
Shawn O. Pearce7c2c6ee2007-11-06 20:29:20 -050052 struct remote *remote;
Daniel Barkalow18f7c512007-10-29 21:05:43 -040053 struct transport *transport;
54 const struct ref *ref;
Harald Nordgren1fb20df2018-04-09 03:42:26 +020055 struct ref_array ref_array;
56 static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
Daniel Barkalow18f7c512007-10-29 21:05:43 -040057
Thomas Gummererba5f28b2016-01-19 00:20:49 +010058 struct option options[] = {
59 OPT__QUIET(&quiet, N_("do not print remote URL")),
60 OPT_STRING(0, "upload-pack", &uploadpack, N_("exec"),
61 N_("path of git-upload-pack on the remote host")),
62 { OPTION_STRING, 0, "exec", &uploadpack, N_("exec"),
63 N_("path of git-upload-pack on the remote host"),
64 PARSE_OPT_HIDDEN },
65 OPT_BIT('t', "tags", &flags, N_("limit to tags"), REF_TAGS),
66 OPT_BIT('h', "heads", &flags, N_("limit to heads"), REF_HEADS),
67 OPT_BIT(0, "refs", &flags, N_("do not show peeled tags"), REF_NORMAL),
68 OPT_BOOL(0, "get-url", &get_url,
69 N_("take url.<base>.insteadOf into account")),
Jeff King95be7172019-03-20 16:22:15 -040070 OPT_REF_SORT(sorting_tail),
Nguyễn Thái Ngọc Duycdc71c12018-02-09 18:02:03 +070071 OPT_SET_INT_F(0, "exit-code", &status,
72 N_("exit with exit code 2 if no matching refs are found"),
73 2, PARSE_OPT_NOCOMPLETE),
Thomas Gummerer99c08d42016-01-19 00:20:50 +010074 OPT_BOOL(0, "symref", &show_symref_target,
75 N_("show underlying ref in addition to the object pointed by it")),
Brandon Williamsff473222018-04-23 15:46:23 -070076 OPT_STRING_LIST('o', "server-option", &server_options, N_("server-specific"), N_("option to transmit")),
Thomas Gummererba5f28b2016-01-19 00:20:49 +010077 OPT_END()
78 };
Junio C Hamano91a640f2011-09-16 11:14:27 -070079
Harald Nordgren1fb20df2018-04-09 03:42:26 +020080 memset(&ref_array, 0, sizeof(ref_array));
81
Thomas Gummererba5f28b2016-01-19 00:20:49 +010082 argc = parse_options(argc, argv, prefix, options, ls_remote_usage,
83 PARSE_OPT_STOP_AT_NON_OPTION);
84 dest = argv[0];
Daniel Barkalow18f7c512007-10-29 21:05:43 -040085
Thomas Gummererba5f28b2016-01-19 00:20:49 +010086 if (argc > 1) {
87 int i;
88 pattern = xcalloc(argc, sizeof(const char *));
Brandon Williamsb4be7412018-03-15 10:31:24 -070089 for (i = 1; i < argc; i++) {
Thomas Gummererba5f28b2016-01-19 00:20:49 +010090 pattern[i - 1] = xstrfmt("*/%s", argv[i]);
Brandon Williamsb4be7412018-03-15 10:31:24 -070091 }
Daniel Barkalow18f7c512007-10-29 21:05:43 -040092 }
93
Jeff King6a139cd2018-10-31 00:24:42 -040094 if (flags & REF_TAGS)
95 argv_array_push(&ref_prefixes, "refs/tags/");
96 if (flags & REF_HEADS)
97 argv_array_push(&ref_prefixes, "refs/heads/");
98
Daniel Barkalowc1d45cf2009-11-03 21:38:51 -050099 remote = remote_get(dest);
Tay Ray Chuan9c00de52010-04-09 01:21:13 +0800100 if (!remote) {
101 if (dest)
102 die("bad repository '%s'", dest);
103 die("No remote configured to list refs from.");
104 }
Daniel Barkalowc1d45cf2009-11-03 21:38:51 -0500105 if (!remote->url_nr)
Shawn O. Pearce7c2c6ee2007-11-06 20:29:20 -0500106 die("remote %s has no configured URL", dest);
Uwe Kleine-König45781ad2011-03-01 10:21:36 +0100107
108 if (get_url) {
109 printf("%s\n", *remote->url);
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200110 UNLEAK(sorting);
Uwe Kleine-König45781ad2011-03-01 10:21:36 +0100111 return 0;
112 }
113
Daniel Barkalowfb0cc872009-11-18 02:42:22 +0100114 transport = transport_get(remote, NULL);
Daniel Barkalow18f7c512007-10-29 21:05:43 -0400115 if (uploadpack != NULL)
116 transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
Brandon Williamsff473222018-04-23 15:46:23 -0700117 if (server_options.nr)
118 transport->server_options = &server_options;
Daniel Barkalow18f7c512007-10-29 21:05:43 -0400119
Brandon Williamsb4be7412018-03-15 10:31:24 -0700120 ref = transport_get_remote_refs(transport, &ref_prefixes);
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200121 if (transport_disconnect(transport)) {
122 UNLEAK(sorting);
Daniel Barkalow18f7c512007-10-29 21:05:43 -0400123 return 1;
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200124 }
Tay Ray Chuancefb2a52010-05-12 01:20:23 +0800125
126 if (!dest && !quiet)
127 fprintf(stderr, "From %s\n", *remote->url);
Junio C Hamano2ea7fe02007-12-08 22:52:59 -0800128 for ( ; ref; ref = ref->next) {
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200129 struct ref_array_item *item;
Junio C Hamano2ea7fe02007-12-08 22:52:59 -0800130 if (!check_ref_type(ref, flags))
131 continue;
132 if (!tail_match(pattern, ref->name))
133 continue;
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200134 item = ref_array_push(&ref_array, ref->name, &ref->old_oid);
135 item->symref = xstrdup_or_null(ref->symref);
136 }
137
138 if (sorting)
139 ref_array_sort(sorting, &ref_array);
140
141 for (i = 0; i < ref_array.nr; i++) {
142 const struct ref_array_item *ref = ref_array.items[i];
Thomas Gummerer99c08d42016-01-19 00:20:50 +0100143 if (show_symref_target && ref->symref)
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200144 printf("ref: %s\t%s\n", ref->symref, ref->refname);
145 printf("%s\t%s\n", oid_to_hex(&ref->objectname), ref->refname);
Michael Schuberta8724772011-05-18 22:06:00 +0200146 status = 0; /* we found something */
Daniel Barkalow18f7c512007-10-29 21:05:43 -0400147 }
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200148
149 UNLEAK(sorting);
Olga Telezhnayadeec6b82018-10-18 07:28:54 +0000150 ref_array_clear(&ref_array);
Michael Schuberta8724772011-05-18 22:06:00 +0200151 return status;
Daniel Barkalow18f7c512007-10-29 21:05:43 -0400152}