git-archive: convert archive entries like checkouts do
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>
This commit is contained in:
parent
4229aa5141
commit
5e6cfc80e2
@ -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';
|
||||
}
|
||||
|
||||
/*
|
||||
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
1
cache.h
1
cache.h
@ -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);
|
||||
|
15
convert.c
15
convert.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user