Skip to content

Commit

Permalink
git-archive: convert archive entries like checkouts do
Browse files Browse the repository at this point in the history
As noted by Johan Herland, git-archive is a kind of checkout and needs
to apply any checkout filters that might be configured.

This patch adds the convenience function convert_sha1_file which returns
a buffer containing the object's contents, after converting, if necessary
(i.e. it's a combination of read_sha1_file and convert_to_working_tree).
Direct calls to read_sha1_file in git-archive are then replaced by calls
to convert_sha1_file.

Since convert_sha1_file expects its path argument to be NUL-terminated --
a convention it inherits from convert_to_working_tree -- the patch also
changes the path handling in archive-tar.c to always NUL-terminate the
string.  It used to solely rely on the len field of struct strbuf before.

archive-zip.c already NUL-terminates the path and thus needs no such
change.

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
René Scharfe authored and Junio C Hamano committed May 18, 2007
1 parent 4229aa5 commit 5e6cfc8
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 8 deletions.
16 changes: 9 additions & 7 deletions archive-tar.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,13 @@ 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;
if (total + 1 > sb->alloc) {
sb->buf = xrealloc(sb->buf, total + 1);
sb->alloc = total + 1;
}
memcpy(sb->buf + sb->len, s, slen);
sb->len = total;
sb->buf[total] = '\0';
}

/*
Expand Down Expand Up @@ -270,20 +271,21 @@ static int write_tar_entry(const unsigned char *sha1,
path.alloc = PATH_MAX;
path.len = path.eof = 0;
}
if (path.alloc < baselen + filenamelen) {
if (path.alloc < baselen + filenamelen + 1) {
free(path.buf);
path.buf = xmalloc(baselen + filenamelen);
path.alloc = baselen + filenamelen;
path.buf = xmalloc(baselen + filenamelen + 1);
path.alloc = baselen + filenamelen + 1;
}
memcpy(path.buf, base, baselen);
memcpy(path.buf + baselen, filename, filenamelen);
path.len = baselen + filenamelen;
path.buf[path.len] = '\0';
if (S_ISDIR(mode) || S_ISDIRLNK(mode)) {
strbuf_append_string(&path, "/");
buffer = NULL;
size = 0;
} else {
buffer = read_sha1_file(sha1, &type, &size);
buffer = convert_sha1_file(path.buf, sha1, mode, &type, &size);
if (!buffer)
die("cannot read %s", sha1_to_hex(sha1));
}
Expand Down
2 changes: 1 addition & 1 deletion archive-zip.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ static int write_zip_entry(const unsigned char *sha1,
if (S_ISREG(mode) && zlib_compression_level != 0)
method = 8;
result = 0;
buffer = read_sha1_file(sha1, &type, &size);
buffer = convert_sha1_file(path, sha1, mode, &type, &size);
if (!buffer)
die("cannot read %s", sha1_to_hex(sha1));
crc = crc32(crc, buffer, size);
Expand Down
1 change: 1 addition & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ extern void trace_argv_printf(const char **argv, int count, const char *format,
/* convert.c */
extern char *convert_to_git(const char *path, const char *src, unsigned long *sizep);
extern char *convert_to_working_tree(const char *path, const char *src, unsigned long *sizep);
extern void *convert_sha1_file(const char *path, const unsigned char *sha1, unsigned int mode, enum object_type *type, unsigned long *size);

/* match-trees.c */
void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int);
Expand Down
15 changes: 15 additions & 0 deletions convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -652,3 +652,18 @@ char *convert_to_working_tree(const char *path, const char *src, unsigned long *

return buf;
}

void *convert_sha1_file(const char *path, const unsigned char *sha1,
unsigned int mode, enum object_type *type,
unsigned long *size)
{
void *buffer = read_sha1_file(sha1, type, size);
if (S_ISREG(mode) && buffer) {
void *converted = convert_to_working_tree(path, buffer, size);
if (converted) {
free(buffer);
buffer = converted;
}
}
return buffer;
}

0 comments on commit 5e6cfc8

Please sign in to comment.