Browse Source

built-in tar-tree and remote tar-tree

This makes tar-tree a built-in.  As an added bonus, you can now
say:

	git tar-tree --remote=remote-repository <ent> [<base>]

This does not work with git-daemon yet, but should work with
localhost and git over ssh transports.

Signed-off-by: Junio C Hamano <junkio@cox.net>
maint
Junio C Hamano 19 years ago
parent
commit
217542640e
  1. 6
      Makefile
  2. 62
      builtin-tar-tree.c
  3. 74
      builtin-upload-tar.c
  4. 2
      builtin.h
  5. 4
      git.c

6
Makefile

@ -161,7 +161,7 @@ PROGRAMS = \ @@ -161,7 +161,7 @@ PROGRAMS = \
git-receive-pack$X git-rev-parse$X \
git-send-pack$X git-show-branch$X git-shell$X \
git-show-index$X git-ssh-fetch$X \
git-ssh-upload$X git-tar-tree$X git-unpack-file$X \
git-ssh-upload$X git-unpack-file$X \
git-unpack-objects$X git-update-index$X git-update-server-info$X \
git-upload-pack$X git-verify-pack$X git-write-tree$X \
git-update-ref$X git-symbolic-ref$X \
@ -171,7 +171,7 @@ PROGRAMS = \ @@ -171,7 +171,7 @@ PROGRAMS = \
BUILT_INS = git-log$X git-whatchanged$X git-show$X \
git-count-objects$X git-diff$X git-push$X \
git-grep$X git-rev-list$X git-check-ref-format$X \
git-init-db$X
git-init-db$X git-tar-tree$X git-upload-tar$X

# what 'all' will build and 'install' will install, in gitexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@ -220,7 +220,7 @@ LIB_OBJS = \ @@ -220,7 +220,7 @@ LIB_OBJS = \
BUILTIN_OBJS = \
builtin-log.o builtin-help.o builtin-count.o builtin-diff.o builtin-push.o \
builtin-grep.o builtin-rev-list.o builtin-check-ref-format.o \
builtin-init-db.o
builtin-init-db.o builtin-tar-tree.o builtin-upload-tar.o

GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz

62
tar-tree.c → builtin-tar-tree.c

@ -7,11 +7,14 @@ @@ -7,11 +7,14 @@
#include "commit.h"
#include "strbuf.h"
#include "tar.h"
#include "builtin.h"
#include "pkt-line.h"

#define RECORDSIZE (512)
#define BLOCKSIZE (RECORDSIZE * 20)

static const char tar_tree_usage[] = "git-tar-tree <key> [basedir]";
static const char tar_tree_usage[] =
"git-tar-tree [--remote=<repo>] <ent> [basedir]";

static char block[BLOCKSIZE];
static unsigned long offset;
@ -301,7 +304,7 @@ static void traverse_tree(struct tree_desc *tree, struct strbuf *path) @@ -301,7 +304,7 @@ static void traverse_tree(struct tree_desc *tree, struct strbuf *path)
}
}

int main(int argc, char **argv)
int generate_tar(int argc, const char **argv)
{
unsigned char sha1[20], tree_sha1[20];
struct commit *commit;
@ -348,3 +351,58 @@ int main(int argc, char **argv) @@ -348,3 +351,58 @@ int main(int argc, char **argv)
free(current_path.buf);
return 0;
}

static const char *exec = "git-upload-tar";

static int remote_tar(int argc, const char **argv)
{
int fd[2], ret, len;
pid_t pid;
char buf[1024];
char *url;

if (argc < 3 || 4 < argc)
usage(tar_tree_usage);

/* --remote=<repo> */
url = strdup(argv[1]+9);
pid = git_connect(fd, url, exec);
if (pid < 0)
return 1;

packet_write(fd[1], "want %s\n", argv[2]);
if (argv[3])
packet_write(fd[1], "base %s\n", argv[3]);
packet_flush(fd[1]);

len = packet_read_line(fd[0], buf, sizeof(buf));
if (!len)
die("git-tar-tree: expected ACK/NAK, got EOF");
if (buf[len-1] == '\n')
buf[--len] = 0;
if (strcmp(buf, "ACK")) {
if (5 < len && !strncmp(buf, "NACK ", 5))
die("git-tar-tree: NACK %s", buf + 5);
die("git-tar-tree: protocol error");
}
/* expect a flush */
len = packet_read_line(fd[0], buf, sizeof(buf));
if (len)
die("git-tar-tree: expected a flush");

/* Now, start reading from fd[0] and spit it out to stdout */
ret = copy_fd(fd[0], 1);
close(fd[0]);

ret |= finish_connect(pid);
return !!ret;
}

int cmd_tar_tree(int argc, const char **argv, char **envp)
{
if (argc < 2)
usage(tar_tree_usage);
if (!strncmp("--remote=", argv[1], 9))
return remote_tar(argc, argv);
return generate_tar(argc, argv);
}

74
builtin-upload-tar.c

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
/*
* Copyright (c) 2006 Junio C Hamano
*/
#include "cache.h"
#include "pkt-line.h"
#include "exec_cmd.h"
#include "builtin.h"

static const char upload_tar_usage[] = "git-upload-tar <repo>";

static int nak(const char *reason)
{
packet_write(1, "NACK %s\n", reason);
packet_flush(1);
return 1;
}

int cmd_upload_tar(int argc, const char **argv, char **envp)
{
int len;
const char *dir = argv[1];
char buf[8192];
unsigned char sha1[20];
char *base = NULL;
char hex[41];
int ac;
const char *av[4];

if (argc != 2)
usage(upload_tar_usage);
if (strlen(dir) < sizeof(buf)-1)
strcpy(buf, dir); /* enter-repo smudges its argument */
else
packet_write(1, "NACK insanely long repository name %s\n", dir);
if (!enter_repo(buf, 0)) {
packet_write(1, "NACK not a git archive %s\n", dir);
packet_flush(1);
return 1;
}

len = packet_read_line(0, buf, sizeof(buf));
if (len < 5 || strncmp("want ", buf, 5))
return nak("expected want");
if (buf[len-1] == '\n')
buf[--len] = 0;
if (get_sha1(buf + 5, sha1))
return nak("expected sha1");
strcpy(hex, sha1_to_hex(sha1));

len = packet_read_line(0, buf, sizeof(buf));
if (len) {
if (len < 5 || strncmp("base ", buf, 5))
return nak("expected (optional) base");
if (buf[len-1] == '\n')
buf[--len] = 0;
base = strdup(buf + 5);
len = packet_read_line(0, buf, sizeof(buf));
}
if (len)
return nak("expected flush");

packet_write(1, "ACK\n");
packet_flush(1);

ac = 0;
av[ac++] = "tar-tree";
av[ac++] = hex;
if (base)
av[ac++] = base;
av[ac++] = NULL;
execv_git_cmd(av);
/* should it return that is an error */
return 1;
}

2
builtin.h

@ -27,5 +27,7 @@ extern int cmd_grep(int argc, const char **argv, char **envp); @@ -27,5 +27,7 @@ extern int cmd_grep(int argc, const char **argv, char **envp);
extern int cmd_rev_list(int argc, const char **argv, char **envp);
extern int cmd_check_ref_format(int argc, const char **argv, char **envp);
extern int cmd_init_db(int argc, const char **argv, char **envp);
extern int cmd_tar_tree(int argc, const char **argv, char **envp);
extern int cmd_upload_tar(int argc, const char **argv, char **envp);

#endif

4
git.c

@ -50,8 +50,10 @@ static void handle_internal_command(int argc, const char **argv, char **envp) @@ -50,8 +50,10 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "count-objects", cmd_count_objects },
{ "diff", cmd_diff },
{ "grep", cmd_grep },
{ "rev-list", cmd_rev_list },
{ "init-db", cmd_init_db },
{ "tar-tree", cmd_tar_tree },
{ "upload-tar", cmd_upload_tar },
{ "rev-list", cmd_rev_list },
{ "check-ref-format", cmd_check_ref_format }
};
int i;

Loading…
Cancel
Save