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@trolltech.com>
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@nokia.com>
---
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@trolltech.com>
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@nokia.com>
---
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@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html