mirror of
https://github.com/git/git.git
synced 2024-12-04 07:24:41 +08:00
ba227857d2
This shares the connection between getting the remote ref list and getting objects in the first batch. (A second connection is still used to follow tags). When we do not fetch objects (i.e. either ls-remote disconnects after getting list of refs, or we decide we are already up-to-date), we clean up the connection properly; otherwise the connection is left open in need of cleaning up to avoid getting an error message from the remote end when ssh is used. Signed-off-by: Daniel Barkalow <barkalow@iabervon.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
111 lines
2.4 KiB
C
111 lines
2.4 KiB
C
#include "builtin.h"
|
|
#include "cache.h"
|
|
#include "transport.h"
|
|
#include "remote.h"
|
|
|
|
static const char ls_remote_usage[] =
|
|
"git-ls-remote [--upload-pack=<git-upload-pack>] [<host>:]<directory>";
|
|
|
|
/*
|
|
* Is there one among the list of patterns that match the tail part
|
|
* of the path?
|
|
*/
|
|
static int tail_match(const char **pattern, const char *path)
|
|
{
|
|
const char *p;
|
|
char pathbuf[PATH_MAX];
|
|
|
|
if (!pattern)
|
|
return 1; /* no restriction */
|
|
|
|
if (snprintf(pathbuf, sizeof(pathbuf), "/%s", path) > sizeof(pathbuf))
|
|
return error("insanely long ref %.*s...", 20, path);
|
|
while ((p = *(pattern++)) != NULL) {
|
|
if (!fnmatch(p, pathbuf, 0))
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int cmd_ls_remote(int argc, const char **argv, const char *prefix)
|
|
{
|
|
int i;
|
|
const char *dest = NULL;
|
|
int nongit = 0;
|
|
unsigned flags = 0;
|
|
const char *uploadpack = NULL;
|
|
const char **pattern = NULL;
|
|
|
|
struct remote *remote;
|
|
struct transport *transport;
|
|
const struct ref *ref;
|
|
|
|
setup_git_directory_gently(&nongit);
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
const char *arg = argv[i];
|
|
|
|
if (*arg == '-') {
|
|
if (!prefixcmp(arg, "--upload-pack=")) {
|
|
uploadpack = arg + 14;
|
|
continue;
|
|
}
|
|
if (!prefixcmp(arg, "--exec=")) {
|
|
uploadpack = arg + 7;
|
|
continue;
|
|
}
|
|
if (!strcmp("--tags", arg) || !strcmp("-t", arg)) {
|
|
flags |= REF_TAGS;
|
|
continue;
|
|
}
|
|
if (!strcmp("--heads", arg) || !strcmp("-h", arg)) {
|
|
flags |= REF_HEADS;
|
|
continue;
|
|
}
|
|
if (!strcmp("--refs", arg)) {
|
|
flags |= REF_NORMAL;
|
|
continue;
|
|
}
|
|
usage(ls_remote_usage);
|
|
}
|
|
dest = arg;
|
|
i++;
|
|
break;
|
|
}
|
|
|
|
if (!dest)
|
|
usage(ls_remote_usage);
|
|
|
|
if (argv[i]) {
|
|
int j;
|
|
pattern = xcalloc(sizeof(const char *), argc - i + 1);
|
|
for (j = i; j < argc; j++) {
|
|
int len = strlen(argv[j]);
|
|
char *p = xmalloc(len + 3);
|
|
sprintf(p, "*/%s", argv[j]);
|
|
pattern[j - i] = p;
|
|
}
|
|
}
|
|
remote = nongit ? NULL : remote_get(dest);
|
|
if (remote && !remote->url_nr)
|
|
die("remote %s has no configured URL", dest);
|
|
transport = transport_get(remote, remote ? remote->url[0] : dest);
|
|
if (uploadpack != NULL)
|
|
transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
|
|
|
|
ref = transport_get_remote_refs(transport);
|
|
transport_disconnect(transport);
|
|
|
|
if (!ref)
|
|
return 1;
|
|
|
|
for ( ; ref; ref = ref->next) {
|
|
if (!check_ref_type(ref, flags))
|
|
continue;
|
|
if (!tail_match(pattern, ref->name))
|
|
continue;
|
|
printf("%s %s\n", sha1_to_hex(ref->old_sha1), ref->name);
|
|
}
|
|
return 0;
|
|
}
|