Browse Source

Do ref matching on the sender side rather than on receiver

This makes the receiver always send a full list of valid refs, which
will allow us to do better packs, as well as handle creation of new
refs.  Eventually.  Right now we just moved the matching and enabled it.

So now you can do

	git-send-pack host:path branch1 branch2

to only send branches "branch1" and "branch2".
maint
Linus Torvalds 20 years ago
parent
commit
d0efc8a71d
  1. 43
      receive-pack.c
  2. 28
      send-pack.c

43
receive-pack.c

@ -2,31 +2,10 @@ @@ -2,31 +2,10 @@
#include "pkt-line.h"
#include <sys/wait.h>

static const char receive_pack_usage[] = "git-receive-pack [--unpack=executable] <git-dir> [heads]";
static const char receive_pack_usage[] = "git-receive-pack <git-dir>";

static const char *unpacker = "git-unpack-objects";

static int path_match(const char *path, int nr, char **match)
{
int i;
int pathlen = strlen(path);

for (i = 0; i < nr; i++) {
char *s = match[i];
int len = strlen(s);

if (!len || len > pathlen)
continue;
if (memcmp(path + pathlen - len, s, len))
continue;
if (pathlen > len && path[pathlen - len - 1] != '/')
continue;
*s = 0;
return 1;
}
return 0;
}

static void show_ref(const char *path, unsigned char *sha1)
{
packet_write(1, "%s %s\n", sha1_to_hex(sha1), path);
@ -46,7 +25,7 @@ static int read_ref(const char *path, unsigned char *sha1) @@ -46,7 +25,7 @@ static int read_ref(const char *path, unsigned char *sha1)
return ret;
}

static void write_head_info(const char *base, int nr, char **match)
static void write_head_info(const char *base)
{
DIR *dir = opendir(base);

@ -72,15 +51,13 @@ static void write_head_info(const char *base, int nr, char **match) @@ -72,15 +51,13 @@ static void write_head_info(const char *base, int nr, char **match)
if (S_ISDIR(st.st_mode)) {
path[baselen + namelen] = '/';
path[baselen + namelen + 1] = 0;
write_head_info(path, nr, match);
write_head_info(path);
continue;
}
if (read_ref(path, sha1) < 0)
continue;
if (!has_sha1_file(sha1))
continue;
if (nr && !path_match(path, nr, match))
continue;
show_ref(path, sha1);
}
free(path);
@ -247,26 +224,20 @@ static void unpack(void) @@ -247,26 +224,20 @@ static void unpack(void)

int main(int argc, char **argv)
{
int i, nr_heads = 0;
int i;
const char *dir = NULL;
char **heads = NULL;

argv++;
for (i = 1; i < argc; i++) {
const char *arg = *argv++;

if (*arg == '-') {
if (!strncmp(arg, "--unpack=", 9)) {
unpacker = arg+9;
continue;
}
/* Do flag handling here */
usage(receive_pack_usage);
}
if (dir)
usage(receive_pack_usage);
dir = arg;
heads = argv;
nr_heads = argc - i - 1;
break;
}
if (!dir)
usage(receive_pack_usage);
@ -285,7 +256,7 @@ int main(int argc, char **argv) @@ -285,7 +256,7 @@ int main(int argc, char **argv)

if (access("objects", X_OK) < 0 || access("refs/heads", X_OK) < 0)
die("%s doesn't appear to be a git directory", dir);
write_head_info("refs/", nr_heads, heads);
write_head_info("refs/");

/* EOF */
packet_flush(1);

28
send-pack.c

@ -3,9 +3,29 @@ @@ -3,9 +3,29 @@
#include <sys/wait.h>

static const char send_pack_usage[] = "git-send-pack [--exec=other] destination [heads]*";

static const char *exec = "git-receive-pack";

static int path_match(const char *path, int nr, char **match)
{
int i;
int pathlen = strlen(path);

for (i = 0; i < nr; i++) {
char *s = match[i];
int len = strlen(s);

if (!len || len > pathlen)
continue;
if (memcmp(path + pathlen - len, s, len))
continue;
if (pathlen > len && path[pathlen - len - 1] != '/')
continue;
*s = 0;
return 1;
}
return 0;
}

struct ref {
struct ref *next;
unsigned char old_sha1[20];
@ -108,7 +128,7 @@ static int read_ref(const char *ref, unsigned char *sha1) @@ -108,7 +128,7 @@ static int read_ref(const char *ref, unsigned char *sha1)
return ret;
}

static int send_pack(int in, int out)
static int send_pack(int in, int out, int nr_match, char **match)
{
struct ref *ref_list = NULL, **last_ref = &ref_list;
struct ref *ref;
@ -129,6 +149,8 @@ static int send_pack(int in, int out) @@ -129,6 +149,8 @@ static int send_pack(int in, int out)
if (len < 42 || get_sha1_hex(buffer, old_sha1) || buffer[40] != ' ')
die("protocol error: expected sha/ref, got '%s'", buffer);
name = buffer + 41;
if (nr_match && !path_match(name, nr_match, match))
continue;
if (read_ref(name, new_sha1) < 0)
return error("no such local reference '%s'", name);
if (!has_sha1_file(old_sha1))
@ -260,7 +282,7 @@ int main(int argc, char **argv) @@ -260,7 +282,7 @@ int main(int argc, char **argv)
pid = setup_connection(fd, dest, heads);
if (pid < 0)
return 1;
ret = send_pack(fd[0], fd[1]);
ret = send_pack(fd[0], fd[1], nr_heads, heads);
close(fd[0]);
close(fd[1]);
waitpid(pid, NULL, 0);

Loading…
Cancel
Save