Skip to content

Commit

Permalink
git-archive: wire up TAR format.
Browse files Browse the repository at this point in the history
This is based on Rene Scharfe's earlier patch, but uses the
archiver support introduced by the previous patch.

Signed-off-by: Franck Bui-Huu <[email protected]>
Acked-by: Rene Scharfe <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
Franck Bui-Huu authored and Junio C Hamano committed Sep 9, 2006
1 parent 4df096a commit efd8696
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
4 changes: 4 additions & 0 deletions archive.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,9 @@ extern void parse_treeish_arg(const char **treeish,

extern void parse_pathspec_arg(const char **pathspec,
struct archiver_args *args);
/*
* Archive-format specific backends.
*/
extern int write_tar_archive(struct archiver_args *);

#endif /* ARCHIVE_H */
2 changes: 1 addition & 1 deletion builtin-archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ static const char archive_usage[] = \
"git-archive --format=<fmt> [--prefix=<prefix>/] [<extra>] <tree-ish> [path...]";

struct archiver archivers[] = {
{ "" /* dummy */ },
{ .name = "tar", .write_archive = write_tar_archive },
};

static int run_remote_archiver(struct archiver *ar, int argc,
Expand Down
67 changes: 67 additions & 0 deletions builtin-tar-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "tar.h"
#include "builtin.h"
#include "pkt-line.h"
#include "archive.h"

#define RECORDSIZE (512)
#define BLOCKSIZE (RECORDSIZE * 20)
Expand Down Expand Up @@ -338,6 +339,72 @@ static int generate_tar(int argc, const char **argv, const char *prefix)
return 0;
}

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 = strlen(args->base);

git_config(git_tar_config);

archive_time = args->time;

if (args->commit_sha1)
write_global_extended_header(args->commit_sha1);

if (args->base && plen > 0 && args->base[plen - 1] == '/') {
char *base = strdup(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)
Expand Down

0 comments on commit efd8696

Please sign in to comment.