blob: 44448fa61d168d7b846f5e241b58e0e6cce9e128 [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"
Ævar Arnfjörð Bjarmason5d701982021-09-13 02:13:19 +020010 " [-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;
Jonathan Tan39835402021-02-05 12:48:48 -080048 struct transport_ls_refs_options transport_options =
49 TRANSPORT_LS_REFS_OPTIONS_INIT;
Harald Nordgren1fb20df2018-04-09 03:42:26 +020050 int i;
Brandon Williamsff473222018-04-23 15:46:23 -070051 struct string_list server_options = STRING_LIST_INIT_DUP;
Daniel Barkalow18f7c512007-10-29 21:05:43 -040052
Shawn O. Pearce7c2c6ee2007-11-06 20:29:20 -050053 struct remote *remote;
Daniel Barkalow18f7c512007-10-29 21:05:43 -040054 struct transport *transport;
55 const struct ref *ref;
Harald Nordgren1fb20df2018-04-09 03:42:26 +020056 struct ref_array ref_array;
Junio C Hamano98e7ab62021-10-20 12:23:53 -070057 struct string_list sorting_options = STRING_LIST_INIT_DUP;
Daniel Barkalow18f7c512007-10-29 21:05:43 -040058
Thomas Gummererba5f28b2016-01-19 00:20:49 +010059 struct option options[] = {
60 OPT__QUIET(&quiet, N_("do not print remote URL")),
61 OPT_STRING(0, "upload-pack", &uploadpack, N_("exec"),
62 N_("path of git-upload-pack on the remote host")),
63 { OPTION_STRING, 0, "exec", &uploadpack, N_("exec"),
64 N_("path of git-upload-pack on the remote host"),
65 PARSE_OPT_HIDDEN },
66 OPT_BIT('t', "tags", &flags, N_("limit to tags"), REF_TAGS),
67 OPT_BIT('h', "heads", &flags, N_("limit to heads"), REF_HEADS),
68 OPT_BIT(0, "refs", &flags, N_("do not show peeled tags"), REF_NORMAL),
69 OPT_BOOL(0, "get-url", &get_url,
70 N_("take url.<base>.insteadOf into account")),
Junio C Hamano98e7ab62021-10-20 12:23:53 -070071 OPT_REF_SORT(&sorting_options),
Nguyễn Thái Ngọc Duycdc71c12018-02-09 18:02:03 +070072 OPT_SET_INT_F(0, "exit-code", &status,
73 N_("exit with exit code 2 if no matching refs are found"),
74 2, PARSE_OPT_NOCOMPLETE),
Thomas Gummerer99c08d42016-01-19 00:20:50 +010075 OPT_BOOL(0, "symref", &show_symref_target,
76 N_("show underlying ref in addition to the object pointed by it")),
Brandon Williamsff473222018-04-23 15:46:23 -070077 OPT_STRING_LIST('o', "server-option", &server_options, N_("server-specific"), N_("option to transmit")),
Thomas Gummererba5f28b2016-01-19 00:20:49 +010078 OPT_END()
79 };
Junio C Hamano91a640f2011-09-16 11:14:27 -070080
Harald Nordgren1fb20df2018-04-09 03:42:26 +020081 memset(&ref_array, 0, sizeof(ref_array));
82
Thomas Gummererba5f28b2016-01-19 00:20:49 +010083 argc = parse_options(argc, argv, prefix, options, ls_remote_usage,
84 PARSE_OPT_STOP_AT_NON_OPTION);
85 dest = argv[0];
Daniel Barkalow18f7c512007-10-29 21:05:43 -040086
Ævar Arnfjörð Bjarmasonf58c7462021-08-23 15:17:49 +020087 packet_trace_identity("ls-remote");
88
Thomas Gummererba5f28b2016-01-19 00:20:49 +010089 if (argc > 1) {
90 int i;
René Scharfeca56dad2021-03-13 17:17:22 +010091 CALLOC_ARRAY(pattern, argc);
Brandon Williamsb4be7412018-03-15 10:31:24 -070092 for (i = 1; i < argc; i++) {
Thomas Gummererba5f28b2016-01-19 00:20:49 +010093 pattern[i - 1] = xstrfmt("*/%s", argv[i]);
Brandon Williamsb4be7412018-03-15 10:31:24 -070094 }
Daniel Barkalow18f7c512007-10-29 21:05:43 -040095 }
96
Jeff King6a139cd2018-10-31 00:24:42 -040097 if (flags & REF_TAGS)
Jonathan Tan39835402021-02-05 12:48:48 -080098 strvec_push(&transport_options.ref_prefixes, "refs/tags/");
Jeff King6a139cd2018-10-31 00:24:42 -040099 if (flags & REF_HEADS)
Jonathan Tan39835402021-02-05 12:48:48 -0800100 strvec_push(&transport_options.ref_prefixes, "refs/heads/");
Jeff King6a139cd2018-10-31 00:24:42 -0400101
Daniel Barkalowc1d45cf2009-11-03 21:38:51 -0500102 remote = remote_get(dest);
Tay Ray Chuan9c00de52010-04-09 01:21:13 +0800103 if (!remote) {
104 if (dest)
105 die("bad repository '%s'", dest);
106 die("No remote configured to list refs from.");
107 }
Daniel Barkalowc1d45cf2009-11-03 21:38:51 -0500108 if (!remote->url_nr)
Shawn O. Pearce7c2c6ee2007-11-06 20:29:20 -0500109 die("remote %s has no configured URL", dest);
Uwe Kleine-König45781ad2011-03-01 10:21:36 +0100110
111 if (get_url) {
112 printf("%s\n", *remote->url);
113 return 0;
114 }
115
Daniel Barkalowfb0cc872009-11-18 02:42:22 +0100116 transport = transport_get(remote, NULL);
Daniel Barkalow18f7c512007-10-29 21:05:43 -0400117 if (uploadpack != NULL)
118 transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
Brandon Williamsff473222018-04-23 15:46:23 -0700119 if (server_options.nr)
120 transport->server_options = &server_options;
Daniel Barkalow18f7c512007-10-29 21:05:43 -0400121
Jonathan Tan39835402021-02-05 12:48:48 -0800122 ref = transport_get_remote_refs(transport, &transport_options);
brian m. carlsond96dab82020-05-25 19:59:19 +0000123 if (ref) {
124 int hash_algo = hash_algo_by_ptr(transport_get_hash_algo(transport));
125 repo_set_hash_algo(the_repository, hash_algo);
126 }
Tay Ray Chuancefb2a52010-05-12 01:20:23 +0800127
128 if (!dest && !quiet)
129 fprintf(stderr, "From %s\n", *remote->url);
Junio C Hamano2ea7fe02007-12-08 22:52:59 -0800130 for ( ; ref; ref = ref->next) {
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200131 struct ref_array_item *item;
Junio C Hamano2ea7fe02007-12-08 22:52:59 -0800132 if (!check_ref_type(ref, flags))
133 continue;
134 if (!tail_match(pattern, ref->name))
135 continue;
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200136 item = ref_array_push(&ref_array, ref->name, &ref->old_oid);
137 item->symref = xstrdup_or_null(ref->symref);
138 }
139
Junio C Hamano98e7ab62021-10-20 12:23:53 -0700140 if (sorting_options.nr) {
141 struct ref_sorting *sorting;
142
143 sorting = ref_sorting_options(&sorting_options);
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200144 ref_array_sort(sorting, &ref_array);
Junio C Hamano98e7ab62021-10-20 12:23:53 -0700145 ref_sorting_release(sorting);
146 }
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200147
148 for (i = 0; i < ref_array.nr; i++) {
149 const struct ref_array_item *ref = ref_array.items[i];
Thomas Gummerer99c08d42016-01-19 00:20:50 +0100150 if (show_symref_target && ref->symref)
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200151 printf("ref: %s\t%s\n", ref->symref, ref->refname);
152 printf("%s\t%s\n", oid_to_hex(&ref->objectname), ref->refname);
Michael Schuberta8724772011-05-18 22:06:00 +0200153 status = 0; /* we found something */
Daniel Barkalow18f7c512007-10-29 21:05:43 -0400154 }
Harald Nordgren1fb20df2018-04-09 03:42:26 +0200155
Olga Telezhnayadeec6b82018-10-18 07:28:54 +0000156 ref_array_clear(&ref_array);
Andrzej Hunt68ffe092021-03-21 16:58:37 +0000157 if (transport_disconnect(transport))
158 return 1;
Michael Schuberta8724772011-05-18 22:06:00 +0200159 return status;
Daniel Barkalow18f7c512007-10-29 21:05:43 -0400160}