git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/2] git-tar-tree: Move code for git-archive --format=tar to archive-tar.c
@ 2006-09-24 15:31 Rene Scharfe
  2006-09-24 21:41 ` Junio C Hamano
  0 siblings, 1 reply; 3+ messages in thread
From: Rene Scharfe @ 2006-09-24 15:31 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Franck Bui-Huu, Git Mailing List

This patch doesn't change any functionality, it only moves code around.  It
makes seeing the few remaining lines of git-tar-tree code easier. ;-)

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---

 Makefile           |    2 
 archive-tar.c      |  325 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 builtin-tar-tree.c |  313 --------------------------------------------------
 3 files changed, 326 insertions(+), 314 deletions(-)

diff --git a/Makefile b/Makefile
index 739d7e3..d4f6e01 100644
--- a/Makefile
+++ b/Makefile
@@ -254,7 +254,7 @@ LIB_OBJS = \
 	fetch-clone.o revision.o pager.o tree-walk.o xdiff-interface.o \
 	write_or_die.o trace.o list-objects.o \
 	alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \
-	color.o wt-status.o archive-zip.o
+	color.o wt-status.o archive-zip.o archive-tar.o
 
 BUILTIN_OBJS = \
 	builtin-add.o \
diff --git a/archive-tar.c b/archive-tar.c
new file mode 100644
index 0000000..ff0f6e2
--- /dev/null
+++ b/archive-tar.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2005, 2006 Rene Scharfe
+ */
+#include <time.h>
+#include "cache.h"
+#include "commit.h"
+#include "strbuf.h"
+#include "tar.h"
+#include "builtin.h"
+#include "archive.h"
+
+#define RECORDSIZE	(512)
+#define BLOCKSIZE	(RECORDSIZE * 20)
+
+static char block[BLOCKSIZE];
+static unsigned long offset;
+
+static time_t archive_time;
+static int tar_umask;
+static int verbose;
+
+/* writes out the whole block, but only if it is full */
+static void write_if_needed(void)
+{
+	if (offset == BLOCKSIZE) {
+		write_or_die(1, block, BLOCKSIZE);
+		offset = 0;
+	}
+}
+
+/*
+ * queues up writes, so that all our write(2) calls write exactly one
+ * full block; pads writes to RECORDSIZE
+ */
+static void write_blocked(const void *data, unsigned long size)
+{
+	const char *buf = data;
+	unsigned long tail;
+
+	if (offset) {
+		unsigned long chunk = BLOCKSIZE - offset;
+		if (size < chunk)
+			chunk = size;
+		memcpy(block + offset, buf, chunk);
+		size -= chunk;
+		offset += chunk;
+		buf += chunk;
+		write_if_needed();
+	}
+	while (size >= BLOCKSIZE) {
+		write_or_die(1, buf, BLOCKSIZE);
+		size -= BLOCKSIZE;
+		buf += BLOCKSIZE;
+	}
+	if (size) {
+		memcpy(block + offset, buf, size);
+		offset += size;
+	}
+	tail = offset % RECORDSIZE;
+	if (tail)  {
+		memset(block + offset, 0, RECORDSIZE - tail);
+		offset += RECORDSIZE - tail;
+	}
+	write_if_needed();
+}
+
+/*
+ * The end of tar archives is marked by 2*512 nul bytes and after that
+ * follows the rest of the block (if any).
+ */
+static void write_trailer(void)
+{
+	int tail = BLOCKSIZE - offset;
+	memset(block + offset, 0, tail);
+	write_or_die(1, block, BLOCKSIZE);
+	if (tail < 2 * RECORDSIZE) {
+		memset(block, 0, offset);
+		write_or_die(1, block, BLOCKSIZE);
+	}
+}
+
+static void strbuf_append_string(struct strbuf *sb, const char *s)
+{
+	int slen = strlen(s);
+	int total = sb->len + slen;
+	if (total > sb->alloc) {
+		sb->buf = xrealloc(sb->buf, total);
+		sb->alloc = total;
+	}
+	memcpy(sb->buf + sb->len, s, slen);
+	sb->len = total;
+}
+
+/*
+ * pax extended header records have the format "%u %s=%s\n".  %u contains
+ * the size of the whole string (including the %u), the first %s is the
+ * keyword, the second one is the value.  This function constructs such a
+ * string and appends it to a struct strbuf.
+ */
+static void strbuf_append_ext_header(struct strbuf *sb, const char *keyword,
+                                     const char *value, unsigned int valuelen)
+{
+	char *p;
+	int len, total, tmp;
+
+	/* "%u %s=%s\n" */
+	len = 1 + 1 + strlen(keyword) + 1 + valuelen + 1;
+	for (tmp = len; tmp > 9; tmp /= 10)
+		len++;
+
+	total = sb->len + len;
+	if (total > sb->alloc) {
+		sb->buf = xrealloc(sb->buf, total);
+		sb->alloc = total;
+	}
+
+	p = sb->buf;
+	p += sprintf(p, "%u %s=", len, keyword);
+	memcpy(p, value, valuelen);
+	p += valuelen;
+	*p = '\n';
+	sb->len = total;
+}
+
+static unsigned int ustar_header_chksum(const struct ustar_header *header)
+{
+	char *p = (char *)header;
+	unsigned int chksum = 0;
+	while (p < header->chksum)
+		chksum += *p++;
+	chksum += sizeof(header->chksum) * ' ';
+	p += sizeof(header->chksum);
+	while (p < (char *)header + sizeof(struct ustar_header))
+		chksum += *p++;
+	return chksum;
+}
+
+static int get_path_prefix(const struct strbuf *path, int maxlen)
+{
+	int i = path->len;
+	if (i > maxlen)
+		i = maxlen;
+	do {
+		i--;
+	} while (i > 0 && path->buf[i] != '/');
+	return i;
+}
+
+static void write_entry(const unsigned char *sha1, struct strbuf *path,
+                        unsigned int mode, void *buffer, unsigned long size)
+{
+	struct ustar_header header;
+	struct strbuf ext_header;
+
+	memset(&header, 0, sizeof(header));
+	ext_header.buf = NULL;
+	ext_header.len = ext_header.alloc = 0;
+
+	if (!sha1) {
+		*header.typeflag = TYPEFLAG_GLOBAL_HEADER;
+		mode = 0100666;
+		strcpy(header.name, "pax_global_header");
+	} else if (!path) {
+		*header.typeflag = TYPEFLAG_EXT_HEADER;
+		mode = 0100666;
+		sprintf(header.name, "%s.paxheader", sha1_to_hex(sha1));
+	} else {
+		if (verbose)
+			fprintf(stderr, "%.*s\n", path->len, path->buf);
+		if (S_ISDIR(mode)) {
+			*header.typeflag = TYPEFLAG_DIR;
+			mode = (mode | 0777) & ~tar_umask;
+		} else if (S_ISLNK(mode)) {
+			*header.typeflag = TYPEFLAG_LNK;
+			mode |= 0777;
+		} else if (S_ISREG(mode)) {
+			*header.typeflag = TYPEFLAG_REG;
+			mode = (mode | ((mode & 0100) ? 0777 : 0666)) & ~tar_umask;
+		} else {
+			error("unsupported file mode: 0%o (SHA1: %s)",
+			      mode, sha1_to_hex(sha1));
+			return;
+		}
+		if (path->len > sizeof(header.name)) {
+			int plen = get_path_prefix(path, sizeof(header.prefix));
+			int rest = path->len - plen - 1;
+			if (plen > 0 && rest <= sizeof(header.name)) {
+				memcpy(header.prefix, path->buf, plen);
+				memcpy(header.name, path->buf + plen + 1, rest);
+			} else {
+				sprintf(header.name, "%s.data",
+				        sha1_to_hex(sha1));
+				strbuf_append_ext_header(&ext_header, "path",
+				                         path->buf, path->len);
+			}
+		} else
+			memcpy(header.name, path->buf, path->len);
+	}
+
+	if (S_ISLNK(mode) && buffer) {
+		if (size > sizeof(header.linkname)) {
+			sprintf(header.linkname, "see %s.paxheader",
+			        sha1_to_hex(sha1));
+			strbuf_append_ext_header(&ext_header, "linkpath",
+			                         buffer, size);
+		} else
+			memcpy(header.linkname, buffer, size);
+	}
+
+	sprintf(header.mode, "%07o", mode & 07777);
+	sprintf(header.size, "%011lo", S_ISREG(mode) ? size : 0);
+	sprintf(header.mtime, "%011lo", archive_time);
+
+	/* XXX: should we provide more meaningful info here? */
+	sprintf(header.uid, "%07o", 0);
+	sprintf(header.gid, "%07o", 0);
+	strlcpy(header.uname, "git", sizeof(header.uname));
+	strlcpy(header.gname, "git", sizeof(header.gname));
+	sprintf(header.devmajor, "%07o", 0);
+	sprintf(header.devminor, "%07o", 0);
+
+	memcpy(header.magic, "ustar", 6);
+	memcpy(header.version, "00", 2);
+
+	sprintf(header.chksum, "%07o", ustar_header_chksum(&header));
+
+	if (ext_header.len > 0) {
+		write_entry(sha1, NULL, 0, ext_header.buf, ext_header.len);
+		free(ext_header.buf);
+	}
+	write_blocked(&header, sizeof(header));
+	if (S_ISREG(mode) && buffer && size > 0)
+		write_blocked(buffer, size);
+}
+
+static void write_global_extended_header(const unsigned char *sha1)
+{
+	struct strbuf ext_header;
+	ext_header.buf = NULL;
+	ext_header.len = ext_header.alloc = 0;
+	strbuf_append_ext_header(&ext_header, "comment", sha1_to_hex(sha1), 40);
+	write_entry(NULL, NULL, 0, ext_header.buf, ext_header.len);
+	free(ext_header.buf);
+}
+
+static int git_tar_config(const char *var, const char *value)
+{
+	if (!strcmp(var, "tar.umask")) {
+		if (!strcmp(value, "user")) {
+			tar_umask = umask(0);
+			umask(tar_umask);
+		} else {
+			tar_umask = git_config_int(var, value);
+		}
+		return 0;
+	}
+	return git_default_config(var, value);
+}
+
+static int write_tar_entry(const unsigned char *sha1,
+                           const char *base, int baselen,
+                           const char *filename, unsigned mode, int stage)
+{
+	static struct strbuf path;
+	int filenamelen = strlen(filename);
+	void *buffer;
+	char type[20];
+	unsigned long size;
+
+	if (!path.alloc) {
+		path.buf = xmalloc(PATH_MAX);
+		path.alloc = PATH_MAX;
+		path.len = path.eof = 0;
+	}
+	if (path.alloc < baselen + filenamelen) {
+		free(path.buf);
+		path.buf = xmalloc(baselen + filenamelen);
+		path.alloc = baselen + filenamelen;
+	}
+	memcpy(path.buf, base, baselen);
+	memcpy(path.buf + baselen, filename, filenamelen);
+	path.len = baselen + filenamelen;
+	if (S_ISDIR(mode)) {
+		strbuf_append_string(&path, "/");
+		buffer = NULL;
+		size = 0;
+	} else {
+		buffer = read_sha1_file(sha1, type, &size);
+		if (!buffer)
+			die("cannot read %s", sha1_to_hex(sha1));
+	}
+
+	write_entry(sha1, &path, mode, buffer, size);
+	free(buffer);
+
+	return READ_TREE_RECURSIVE;
+}
+
+int write_tar_archive(struct archiver_args *args)
+{
+	int plen = args->base ? strlen(args->base) : 0;
+
+	git_config(git_tar_config);
+
+	archive_time = args->time;
+	verbose = args->verbose;
+
+	if (args->commit_sha1)
+		write_global_extended_header(args->commit_sha1);
+
+	if (args->base && plen > 0 && args->base[plen - 1] == '/') {
+		char *base = xstrdup(args->base);
+		int baselen = strlen(base);
+
+		while (baselen > 0 && base[baselen - 1] == '/')
+			base[--baselen] = '\0';
+		write_tar_entry(args->tree->object.sha1, "", 0, base, 040777, 0);
+		free(base);
+	}
+	read_tree_recursive(args->tree, args->base, plen, 0,
+			    args->pathspec, write_tar_entry);
+	write_trailer();
+
+	return 0;
+}
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index 82b4951..aa370e3 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -4,7 +4,6 @@
 #include <time.h>
 #include "cache.h"
 #include "commit.h"
-#include "strbuf.h"
 #include "tar.h"
 #include "builtin.h"
 #include "pkt-line.h"
@@ -16,251 +15,6 @@ #define BLOCKSIZE	(RECORDSIZE * 20)
 static const char tar_tree_usage[] =
 "git-tar-tree [--remote=<repo>] <tree-ish> [basedir]";
 
-static char block[BLOCKSIZE];
-static unsigned long offset;
-
-static time_t archive_time;
-static int tar_umask;
-static int verbose;
-
-/* writes out the whole block, but only if it is full */
-static void write_if_needed(void)
-{
-	if (offset == BLOCKSIZE) {
-		write_or_die(1, block, BLOCKSIZE);
-		offset = 0;
-	}
-}
-
-/*
- * queues up writes, so that all our write(2) calls write exactly one
- * full block; pads writes to RECORDSIZE
- */
-static void write_blocked(const void *data, unsigned long size)
-{
-	const char *buf = data;
-	unsigned long tail;
-
-	if (offset) {
-		unsigned long chunk = BLOCKSIZE - offset;
-		if (size < chunk)
-			chunk = size;
-		memcpy(block + offset, buf, chunk);
-		size -= chunk;
-		offset += chunk;
-		buf += chunk;
-		write_if_needed();
-	}
-	while (size >= BLOCKSIZE) {
-		write_or_die(1, buf, BLOCKSIZE);
-		size -= BLOCKSIZE;
-		buf += BLOCKSIZE;
-	}
-	if (size) {
-		memcpy(block + offset, buf, size);
-		offset += size;
-	}
-	tail = offset % RECORDSIZE;
-	if (tail)  {
-		memset(block + offset, 0, RECORDSIZE - tail);
-		offset += RECORDSIZE - tail;
-	}
-	write_if_needed();
-}
-
-/*
- * The end of tar archives is marked by 2*512 nul bytes and after that
- * follows the rest of the block (if any).
- */
-static void write_trailer(void)
-{
-	int tail = BLOCKSIZE - offset;
-	memset(block + offset, 0, tail);
-	write_or_die(1, block, BLOCKSIZE);
-	if (tail < 2 * RECORDSIZE) {
-		memset(block, 0, offset);
-		write_or_die(1, block, BLOCKSIZE);
-	}
-}
-
-static void strbuf_append_string(struct strbuf *sb, const char *s)
-{
-	int slen = strlen(s);
-	int total = sb->len + slen;
-	if (total > sb->alloc) {
-		sb->buf = xrealloc(sb->buf, total);
-		sb->alloc = total;
-	}
-	memcpy(sb->buf + sb->len, s, slen);
-	sb->len = total;
-}
-
-/*
- * pax extended header records have the format "%u %s=%s\n".  %u contains
- * the size of the whole string (including the %u), the first %s is the
- * keyword, the second one is the value.  This function constructs such a
- * string and appends it to a struct strbuf.
- */
-static void strbuf_append_ext_header(struct strbuf *sb, const char *keyword,
-                                     const char *value, unsigned int valuelen)
-{
-	char *p;
-	int len, total, tmp;
-
-	/* "%u %s=%s\n" */
-	len = 1 + 1 + strlen(keyword) + 1 + valuelen + 1;
-	for (tmp = len; tmp > 9; tmp /= 10)
-		len++;
-
-	total = sb->len + len;
-	if (total > sb->alloc) {
-		sb->buf = xrealloc(sb->buf, total);
-		sb->alloc = total;
-	}
-
-	p = sb->buf;
-	p += sprintf(p, "%u %s=", len, keyword);
-	memcpy(p, value, valuelen);
-	p += valuelen;
-	*p = '\n';
-	sb->len = total;
-}
-
-static unsigned int ustar_header_chksum(const struct ustar_header *header)
-{
-	char *p = (char *)header;
-	unsigned int chksum = 0;
-	while (p < header->chksum)
-		chksum += *p++;
-	chksum += sizeof(header->chksum) * ' ';
-	p += sizeof(header->chksum);
-	while (p < (char *)header + sizeof(struct ustar_header))
-		chksum += *p++;
-	return chksum;
-}
-
-static int get_path_prefix(const struct strbuf *path, int maxlen)
-{
-	int i = path->len;
-	if (i > maxlen)
-		i = maxlen;
-	do {
-		i--;
-	} while (i > 0 && path->buf[i] != '/');
-	return i;
-}
-
-static void write_entry(const unsigned char *sha1, struct strbuf *path,
-                        unsigned int mode, void *buffer, unsigned long size)
-{
-	struct ustar_header header;
-	struct strbuf ext_header;
-
-	memset(&header, 0, sizeof(header));
-	ext_header.buf = NULL;
-	ext_header.len = ext_header.alloc = 0;
-
-	if (!sha1) {
-		*header.typeflag = TYPEFLAG_GLOBAL_HEADER;
-		mode = 0100666;
-		strcpy(header.name, "pax_global_header");
-	} else if (!path) {
-		*header.typeflag = TYPEFLAG_EXT_HEADER;
-		mode = 0100666;
-		sprintf(header.name, "%s.paxheader", sha1_to_hex(sha1));
-	} else {
-		if (verbose)
-			fprintf(stderr, "%.*s\n", path->len, path->buf);
-		if (S_ISDIR(mode)) {
-			*header.typeflag = TYPEFLAG_DIR;
-			mode = (mode | 0777) & ~tar_umask;
-		} else if (S_ISLNK(mode)) {
-			*header.typeflag = TYPEFLAG_LNK;
-			mode |= 0777;
-		} else if (S_ISREG(mode)) {
-			*header.typeflag = TYPEFLAG_REG;
-			mode = (mode | ((mode & 0100) ? 0777 : 0666)) & ~tar_umask;
-		} else {
-			error("unsupported file mode: 0%o (SHA1: %s)",
-			      mode, sha1_to_hex(sha1));
-			return;
-		}
-		if (path->len > sizeof(header.name)) {
-			int plen = get_path_prefix(path, sizeof(header.prefix));
-			int rest = path->len - plen - 1;
-			if (plen > 0 && rest <= sizeof(header.name)) {
-				memcpy(header.prefix, path->buf, plen);
-				memcpy(header.name, path->buf + plen + 1, rest);
-			} else {
-				sprintf(header.name, "%s.data",
-				        sha1_to_hex(sha1));
-				strbuf_append_ext_header(&ext_header, "path",
-				                         path->buf, path->len);
-			}
-		} else
-			memcpy(header.name, path->buf, path->len);
-	}
-
-	if (S_ISLNK(mode) && buffer) {
-		if (size > sizeof(header.linkname)) {
-			sprintf(header.linkname, "see %s.paxheader",
-			        sha1_to_hex(sha1));
-			strbuf_append_ext_header(&ext_header, "linkpath",
-			                         buffer, size);
-		} else
-			memcpy(header.linkname, buffer, size);
-	}
-
-	sprintf(header.mode, "%07o", mode & 07777);
-	sprintf(header.size, "%011lo", S_ISREG(mode) ? size : 0);
-	sprintf(header.mtime, "%011lo", archive_time);
-
-	/* XXX: should we provide more meaningful info here? */
-	sprintf(header.uid, "%07o", 0);
-	sprintf(header.gid, "%07o", 0);
-	strlcpy(header.uname, "git", sizeof(header.uname));
-	strlcpy(header.gname, "git", sizeof(header.gname));
-	sprintf(header.devmajor, "%07o", 0);
-	sprintf(header.devminor, "%07o", 0);
-
-	memcpy(header.magic, "ustar", 6);
-	memcpy(header.version, "00", 2);
-
-	sprintf(header.chksum, "%07o", ustar_header_chksum(&header));
-
-	if (ext_header.len > 0) {
-		write_entry(sha1, NULL, 0, ext_header.buf, ext_header.len);
-		free(ext_header.buf);
-	}
-	write_blocked(&header, sizeof(header));
-	if (S_ISREG(mode) && buffer && size > 0)
-		write_blocked(buffer, size);
-}
-
-static void write_global_extended_header(const unsigned char *sha1)
-{
-	struct strbuf ext_header;
-	ext_header.buf = NULL;
-	ext_header.len = ext_header.alloc = 0;
-	strbuf_append_ext_header(&ext_header, "comment", sha1_to_hex(sha1), 40);
-	write_entry(NULL, NULL, 0, ext_header.buf, ext_header.len);
-	free(ext_header.buf);
-}
-
-static int git_tar_config(const char *var, const char *value)
-{
-	if (!strcmp(var, "tar.umask")) {
-		if (!strcmp(value, "user")) {
-			tar_umask = umask(0);
-			umask(tar_umask);
-		} else {
-			tar_umask = git_config_int(var, value);
-		}
-		return 0;
-	}
-	return git_default_config(var, value);
-}
-
 static int generate_tar(int argc, const char **argv, const char *prefix)
 {
 	struct archiver_args args;
@@ -286,73 +40,6 @@ static int generate_tar(int argc, const 
 	return result;
 }
 
-static int write_tar_entry(const unsigned char *sha1,
-                           const char *base, int baselen,
-                           const char *filename, unsigned mode, int stage)
-{
-	static struct strbuf path;
-	int filenamelen = strlen(filename);
-	void *buffer;
-	char type[20];
-	unsigned long size;
-
-	if (!path.alloc) {
-		path.buf = xmalloc(PATH_MAX);
-		path.alloc = PATH_MAX;
-		path.len = path.eof = 0;
-	}
-	if (path.alloc < baselen + filenamelen) {
-		free(path.buf);
-		path.buf = xmalloc(baselen + filenamelen);
-		path.alloc = baselen + filenamelen;
-	}
-	memcpy(path.buf, base, baselen);
-	memcpy(path.buf + baselen, filename, filenamelen);
-	path.len = baselen + filenamelen;
-	if (S_ISDIR(mode)) {
-		strbuf_append_string(&path, "/");
-		buffer = NULL;
-		size = 0;
-	} else {
-		buffer = read_sha1_file(sha1, type, &size);
-		if (!buffer)
-			die("cannot read %s", sha1_to_hex(sha1));
-	}
-
-	write_entry(sha1, &path, mode, buffer, size);
-	free(buffer);
-
-	return READ_TREE_RECURSIVE;
-}
-
-int write_tar_archive(struct archiver_args *args)
-{
-	int plen = args->base ? strlen(args->base) : 0;
-
-	git_config(git_tar_config);
-
-	archive_time = args->time;
-	verbose = args->verbose;
-
-	if (args->commit_sha1)
-		write_global_extended_header(args->commit_sha1);
-
-	if (args->base && plen > 0 && args->base[plen - 1] == '/') {
-		char *base = xstrdup(args->base);
-		int baselen = strlen(base);
-
-		while (baselen > 0 && base[baselen - 1] == '/')
-			base[--baselen] = '\0';
-		write_tar_entry(args->tree->object.sha1, "", 0, base, 040777, 0);
-		free(base);
-	}
-	read_tree_recursive(args->tree, args->base, plen, 0,
-			    args->pathspec, write_tar_entry);
-	write_trailer();
-
-	return 0;
-}
-
 static const char *exec = "git-upload-tar";
 
 static int remote_tar(int argc, const char **argv)

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] git-tar-tree: Move code for git-archive --format=tar to archive-tar.c
  2006-09-24 15:31 [PATCH 2/2] git-tar-tree: Move code for git-archive --format=tar to archive-tar.c Rene Scharfe
@ 2006-09-24 21:41 ` Junio C Hamano
  2006-09-24 22:19   ` Rene Scharfe
  0 siblings, 1 reply; 3+ messages in thread
From: Junio C Hamano @ 2006-09-24 21:41 UTC (permalink / raw)
  To: Rene Scharfe; +Cc: git

Rene Scharfe <rene.scharfe@lsrfire.ath.cx> writes:

> This patch doesn't change any functionality, it only moves code around.  It
> makes seeing the few remaining lines of git-tar-tree code easier. ;-)
>
> Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>

Thanks.  And here is an obvious follow-up to it.

-- >8 --
[PATCH] Remove upload-tar and make git-tar-tree a thin wrapper to git-archive

---
diff --git a/.gitignore b/.gitignore
index 3ca66e4..284db5d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -122,7 +122,6 @@ git-update-ref
 git-update-server-info
 git-upload-archive
 git-upload-pack
-git-upload-tar
 git-var
 git-verify-pack
 git-verify-tag
diff --git a/Documentation/git-tar-tree.txt b/Documentation/git-tar-tree.txt
index 1e1c7fa..74a6fdd 100644
--- a/Documentation/git-tar-tree.txt
+++ b/Documentation/git-tar-tree.txt
@@ -12,6 +12,9 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
+THIS COMMAND IS DEPRECATED.  Use `git-archive` with `--format=tar`
+option instead.
+
 Creates a tar archive containing the tree structure for the named tree.
 When <base> is specified it is added as a leading path to the files in the
 generated tar archive.
diff --git a/Documentation/git-upload-tar.txt b/Documentation/git-upload-tar.txt
deleted file mode 100644
index 394af62..0000000
--- a/Documentation/git-upload-tar.txt
+++ /dev/null
@@ -1,39 +0,0 @@
-git-upload-tar(1)
-=================
-
-NAME
-----
-git-upload-tar - Send tar archive
-
-
-SYNOPSIS
---------
-'git-upload-tar' <directory>
-
-DESCRIPTION
------------
-Invoked by 'git-tar-tree --remote' and sends a generated tar archive
-to the other end over the git protocol.
-
-This command is usually not invoked directly by the end user.
-The UI for the protocol is on the 'git-tar-tree' side, and the
-program pair is meant to be used to get a tar archive from a
-remote repository.
-
-
-OPTIONS
--------
-<directory>::
-	The repository to get a tar archive from.
-
-Author
-------
-Written by Junio C Hamano <junio@kernel.org>
-
-Documentation
---------------
-Documentation by Junio C Hamano.
-
-GIT
----
-Part of the gitlink:git[7] suite
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 744c38d..1bf5ef5 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -247,10 +247,6 @@ gitlink:git-upload-pack[1]::
 	Invoked by 'git-fetch-pack' to push
 	what are asked for.
 
-gitlink:git-upload-tar[1]::
-	Invoked by 'git-tar-tree --remote' to return the tar
-	archive the other end asked for.
-
 
 High-level commands (porcelain)
 -------------------------------
diff --git a/Makefile b/Makefile
index d4f6e01..35de011 100644
--- a/Makefile
+++ b/Makefile
@@ -298,7 +298,6 @@ BUILTIN_OBJS = \
 	builtin-update-index.o \
 	builtin-update-ref.o \
 	builtin-upload-archive.o \
-	builtin-upload-tar.o \
 	builtin-verify-pack.o \
 	builtin-write-tree.o
 
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index aa370e3..5d2bec0 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -8,94 +8,66 @@ #include "tar.h"
 #include "builtin.h"
 #include "pkt-line.h"
 #include "archive.h"
-
-#define RECORDSIZE	(512)
-#define BLOCKSIZE	(RECORDSIZE * 20)
+#include "quote.h"
 
 static const char tar_tree_usage[] =
-"git-tar-tree [--remote=<repo>] <tree-ish> [basedir]";
+"git-tar-tree [--remote=<repo>] <tree-ish> [basedir]\n"
+"*** Note that this command is now deprecated; use git-archive instead.";
 
-static int generate_tar(int argc, const char **argv, const char *prefix)
+int cmd_tar_tree(int argc, const char **argv, const char *prefix)
 {
-	struct archiver_args args;
-	int result;
-	char *base = NULL;
-
-	memset(&args, 0, sizeof(args));
-	if (argc != 2 && argc != 3)
-		usage(tar_tree_usage);
-	if (argc == 3) {
-		int baselen = strlen(argv[2]);
-		base = xmalloc(baselen + 2);
-		memcpy(base, argv[2], baselen);
-		base[baselen] = '/';
-		base[baselen + 1] = '\0';
+	/*
+	 * git-tar-tree is now a wrapper around git-archive --format=tar
+	 *
+	 * $0 --remote=<repo> arg... ==>
+	 *	git-archive --format=tar --remote=<repo> arg...
+	 * $0 tree-ish ==>
+	 *	git-archive --format=tar tree-ish
+	 * $0 tree-ish basedir ==>
+	 * 	git-archive --format-tar --prefix=basedir tree-ish
+	 */ 
+	int i;
+	const char **nargv = xcalloc(sizeof(*nargv), argc + 2);
+	char *basedir_arg;
+	int nargc = 0;
+
+	nargv[nargc++] = "git-archive";
+	nargv[nargc++] = "--format=tar";
+
+	if (2 <= argc && !strncmp("--remote=", argv[1], 9)) {
+		nargv[nargc++] = argv[1];
+		argv++;
+		argc--;
 	}
-	args.base = base;
-	parse_treeish_arg(argv + 1, &args, NULL);
-
-	result = write_tar_archive(&args);
-	free(base);
-
-	return result;
-}
-
-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)
+	switch (argc) {
+	default:
 		usage(tar_tree_usage);
-
-	/* --remote=<repo> */
-	url = xstrdup(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");
+		break;
+	case 3:
+		/* base-path */ 
+		basedir_arg = xmalloc(strlen(argv[2]) + 10);
+		sprintf(basedir_arg, "--prefix=%s", argv[2]);
+		nargv[nargc++] = basedir_arg;
+		/* fallthru */
+	case 2:
+		/* tree-ish */
+		nargv[nargc++] = argv[1];
 	}
-	/* 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, const char *prefix)
-{
-	if (argc < 2)
-		usage(tar_tree_usage);
-	if (!strncmp("--remote=", argv[1], 9))
-		return remote_tar(argc, argv);
-	return generate_tar(argc, argv, prefix);
+	nargv[nargc] = NULL;
+	
+	fprintf(stderr,
+		"*** git-tar-tree is now deprecated.\n"
+		"*** Running git-archive instead.\n***");
+	for (i = 0; i < nargc; i++) {
+		fputc(' ', stderr);
+		sq_quote_print(stderr, nargv[i]);
+	}
+	fputc('\n', stderr);
+	return cmd_archive(nargc, nargv, prefix);
 }
 
 /* ustar header + extended global header content */
+#define RECORDSIZE	(512)
 #define HEADERSIZE (2 * RECORDSIZE)
 
 int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
diff --git a/builtin-upload-tar.c b/builtin-upload-tar.c
deleted file mode 100644
index 06a945a..0000000
--- a/builtin-upload-tar.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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, const char *prefix)
-{
-	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 = xstrdup(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;
-}
diff --git a/git.c b/git.c
index 1686220..ae80e78 100644
--- a/git.c
+++ b/git.c
@@ -263,7 +263,6 @@ static void handle_internal_command(int 
 		{ "update-index", cmd_update_index, RUN_SETUP },
 		{ "update-ref", cmd_update_ref, RUN_SETUP },
 		{ "upload-archive", cmd_upload_archive },
-		{ "upload-tar", cmd_upload_tar },
 		{ "version", cmd_version },
 		{ "whatchanged", cmd_whatchanged, RUN_SETUP | USE_PAGER },
 		{ "write-tree", cmd_write_tree, RUN_SETUP },

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] git-tar-tree: Move code for git-archive --format=tar to archive-tar.c
  2006-09-24 21:41 ` Junio C Hamano
@ 2006-09-24 22:19   ` Rene Scharfe
  0 siblings, 0 replies; 3+ messages in thread
From: Rene Scharfe @ 2006-09-24 22:19 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Junio C Hamano schrieb:
> Rene Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
> 
>> This patch doesn't change any functionality, it only moves code around.  It
>> makes seeing the few remaining lines of git-tar-tree code easier. ;-)
>>
>> Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
> 
> Thanks.  And here is an obvious follow-up to it.
> 
> -- >8 --
> [PATCH] Remove upload-tar and make git-tar-tree a thin wrapper to git-archive

OK.

> diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
> index aa370e3..5d2bec0 100644
> --- a/builtin-tar-tree.c
> +++ b/builtin-tar-tree.c
> @@ -8,94 +8,66 @@ #include "tar.h"
>  #include "builtin.h"
>  #include "pkt-line.h"
>  #include "archive.h"

At least the last two header references aren't needed any more.

> -	if (argc == 3) {
> -		int baselen = strlen(argv[2]);
> -		base = xmalloc(baselen + 2);
> -		memcpy(base, argv[2], baselen);
> -		base[baselen] = '/';
> -		base[baselen + 1] = '\0';
[...]
> +	case 3:
> +		/* base-path */ 
> +		basedir_arg = xmalloc(strlen(argv[2]) + 10);
> +		sprintf(basedir_arg, "--prefix=%s", argv[2]);
> +		nargv[nargc++] = basedir_arg;

Traditionally we always added a slash to the git-tar-tree base
parameter, forcing it to always be a base _directory_.  git-archive
in contrast to that simply adds the prefix to the paths; users have
to provide their own slash.  This is consistent with how we handle
--prefix parameters elsewhere.  It also means that the sprintf
format string here should be "--prefix=%s/" (and allocate one more
byte the line before).

> +	fprintf(stderr,
> +		"*** git-tar-tree is now deprecated.\n"
> +		"*** Running git-archive instead.\n***");
> +	for (i = 0; i < nargc; i++) {
> +		fputc(' ', stderr);
> +		sq_quote_print(stderr, nargv[i]);
> +	}
> +	fputc('\n', stderr);

Hey, scary message. ;-)  It certainly will aid the re-education of
our users, so I think it's OK.

Thanks,
René

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2006-09-24 22:20 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-09-24 15:31 [PATCH 2/2] git-tar-tree: Move code for git-archive --format=tar to archive-tar.c Rene Scharfe
2006-09-24 21:41 ` Junio C Hamano
2006-09-24 22:19   ` Rene Scharfe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).