Hi, Short description: To enable that I added a new option "--output" that will redirect the output to a file instead to stdout. Long description: When archiving a repository there is no way to send the result to a file without using redirection at shell level. Since there are situations where redirection is not available, for instance when running git inside a continuous integration system which is already redirecting the output, I added an option to write the archive to a file directly. In order to do that I added a new option to archiver_args, int output_fd, which holds the file descriptor where the resulting archive should be written. If no option is specified in command line that option defaults to 1 and no behavior change, however if the "--output" option is specified and the file was created that file descriptor points to the new file. I also modified the write_or_die calls to use "output_fd" instead of 1, so they write to the file descriptor. >From 10e09bf828c18f2846651262b7f647b630e09872 Mon Sep 17 00:00:00 2001 From: Carlos Manuel Duclos Vergara <carlos.duclos@xxxxxxxxxxxxx> Date: Fri, 13 Feb 2009 16:09:39 +0100 Subject: [PATCH] When archiving a repository there is no way to specify a file as output. To enable that I added a new option "--output" that will redirect the output to a file instead to stdout. Signed-off-by: Carlos Manuel Duclos Vergara <carlos.duclos@xxxxxxxxx> --- archive-tar.c | 16 ++++++++++++---- archive-zip.c | 21 ++++++++++++++------- archive.c | 20 ++++++++++++++++++++ archive.h | 1 + 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/archive-tar.c b/archive-tar.c index ba890eb..4d8fc03 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -13,11 +13,13 @@ static unsigned long offset; static int tar_umask = 002; +static int output_fd = 1; + /* 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); + write_or_die(output_fd, block, BLOCKSIZE); offset = 0; } } @@ -42,7 +44,7 @@ static void write_blocked(const void *data, unsigned long size) write_if_needed(); } while (size >= BLOCKSIZE) { - write_or_die(1, buf, BLOCKSIZE); + write_or_die(output_fd, buf, BLOCKSIZE); size -= BLOCKSIZE; buf += BLOCKSIZE; } @@ -66,10 +68,10 @@ static void write_trailer(void) { int tail = BLOCKSIZE - offset; memset(block + offset, 0, tail); - write_or_die(1, block, BLOCKSIZE); + write_or_die(output_fd, block, BLOCKSIZE); if (tail < 2 * RECORDSIZE) { memset(block, 0, offset); - write_or_die(1, block, BLOCKSIZE); + write_or_die(output_fd, block, BLOCKSIZE); } } @@ -234,11 +236,17 @@ static int git_tar_config(const char *var, const char *value, void *cb) return git_default_config(var, value, cb); } +static void setup_write_backend(struct archiver_args *args) +{ + output_fd = args->output_fd; +} + int write_tar_archive(struct archiver_args *args) { int err = 0; git_config(git_tar_config, NULL); + setup_write_backend(args); if (args->commit_sha1) err = write_global_extended_header(args); diff --git a/archive-zip.c b/archive-zip.c index cf28504..dd3ba27 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -14,6 +14,8 @@ static unsigned int zip_offset; static unsigned int zip_dir_offset; static unsigned int zip_dir_entries; +static int output_fd = 1; + #define ZIP_DIRECTORY_MIN_SIZE (1024 * 1024) struct zip_local_header { @@ -219,12 +221,12 @@ static int write_zip_entry(struct archiver_args *args, copy_le32(header.size, uncompressed_size); copy_le16(header.filename_length, pathlen); copy_le16(header.extra_length, 0); - write_or_die(1, &header, ZIP_LOCAL_HEADER_SIZE); + write_or_die(output_fd, &header, ZIP_LOCAL_HEADER_SIZE); zip_offset += ZIP_LOCAL_HEADER_SIZE; - write_or_die(1, path, pathlen); + write_or_die(output_fd, path, pathlen); zip_offset += pathlen; if (compressed_size > 0) { - write_or_die(1, out, compressed_size); + write_or_die(output_fd, out, compressed_size); zip_offset += compressed_size; } @@ -246,10 +248,10 @@ static void write_zip_trailer(const unsigned char *sha1) copy_le32(trailer.offset, zip_offset); copy_le16(trailer.comment_length, sha1 ? 40 : 0); - write_or_die(1, zip_dir, zip_dir_offset); - write_or_die(1, &trailer, ZIP_DIR_TRAILER_SIZE); + write_or_die(output_fd, zip_dir, zip_dir_offset); + write_or_die(output_fd, &trailer, ZIP_DIR_TRAILER_SIZE); if (sha1) - write_or_die(1, sha1_to_hex(sha1), 40); + write_or_die(output_fd, sha1_to_hex(sha1), 40); } static void dos_time(time_t *time, int *dos_date, int *dos_time) @@ -261,12 +263,17 @@ static void dos_time(time_t *time, int *dos_date, int *dos_time) *dos_time = t->tm_sec / 2 + t->tm_min * 32 + t->tm_hour * 2048; } +static void setup_write_backend(struct archiver_args *args) +{ + output_fd = args->output_fd; +} + int write_zip_archive(struct archiver_args *args) { int err; dos_time(&args->time, &zip_date, &zip_time); - + setup_write_backend(args); zip_dir = xmalloc(ZIP_DIRECTORY_MIN_SIZE); zip_dir_size = ZIP_DIRECTORY_MIN_SIZE; diff --git a/archive.c b/archive.c index e6de039..420b853 100644 --- a/archive.c +++ b/archive.c @@ -239,6 +239,16 @@ static void parse_treeish_arg(const char **argv, ar_args->time = archive_time; } +static void create_output_file(const char *output_file, struct archiver_args *ar_args) +{ + int fd = -1; + + fd = creat(output_file, S_IRUSR | S_IWUSR); + if(fd < 0) + die("could not create archive file"); + ar_args->output_fd = fd; +} + #define OPT__COMPR(s, v, h, p) \ { OPTION_SET_INT, (s), NULL, (v), NULL, (h), \ PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, (p) } @@ -253,6 +263,7 @@ static int parse_archive_args(int argc, const char **argv, const char *base = NULL; const char *remote = NULL; const char *exec = NULL; + const char *output = NULL; int compression_level = -1; int verbose = 0; int i; @@ -262,6 +273,7 @@ static int parse_archive_args(int argc, const char **argv, OPT_STRING(0, "format", &format, "fmt", "archive format"), OPT_STRING(0, "prefix", &base, "prefix", "prepend prefix to each pathname in the archive"), + OPT_STRING(0, "output", &output, "output file", "write the results to this file"), OPT__VERBOSE(&verbose), OPT__COMPR('0', &compression_level, "store only", 0), OPT__COMPR('1', &compression_level, "compress faster", 1), @@ -294,6 +306,14 @@ static int parse_archive_args(int argc, const char **argv, if (!base) base = ""; + if(output) + create_output_file(output, args); + else + /* + * Default to stdout + */ + args->output_fd = 1; + if (list) { for (i = 0; i < ARRAY_SIZE(archivers); i++) printf("%s\n", archivers[i].name); diff --git a/archive.h b/archive.h index 0b15b35..67524fa 100644 --- a/archive.h +++ b/archive.h @@ -9,6 +9,7 @@ struct archiver_args { const struct commit *commit; time_t time; const char **pathspec; + int output_fd; unsigned int verbose : 1; int compression_level; }; -- 1.6.0.2 >From 7cbd0a3edb1cf75b5a0644263e1755fd18a5c37d Mon Sep 17 00:00:00 2001 From: Carlos Manuel Duclos Vergara <carlos.duclos@xxxxxxxxxxxxx> Date: Fri, 13 Feb 2009 16:22:21 +0100 Subject: [PATCH] Updating documentation for git-archive in order to reflect the new "--output" option. Signed-off-by: Carlos Manuel Duclos Vergara <carlos.duclos@xxxxxxxxx> --- Documentation/git-archive.txt | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt index 41cbf9c..d1a9d95 100644 --- a/Documentation/git-archive.txt +++ b/Documentation/git-archive.txt @@ -47,6 +47,9 @@ OPTIONS --prefix=<prefix>/:: Prepend <prefix>/ to each filename in the archive. +--output=<output file>:: + Writes the archive to <output file> instead of stdout. + <extra>:: This can be any options that the archiver backend understand. See next section. -- 1.6.0.2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html