From: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
To: Git Mailing List <git@vger.kernel.org>
Cc: Junio C Hamano <junkio@cox.net>, Franck Bui-Huu <vagabon.xyz@gmail.com>
Subject: [PATCH] Add support for tgz archive format
Date: Sat, 02 Sep 2006 14:37:56 +0200 [thread overview]
Message-ID: <44F97B24.7090305@lsrfire.ath.cx> (raw)
In-Reply-To: <44F977C0.4060901@lsrfire.ath.cx>
Documentation/git-archive-tree.txt | 9 ++---
archive.h | 2 +
builtin-archive-tree.c | 4 +-
builtin-tar-tree.c | 63 ++++++++++++++++++++++++++++++++-----
4 files changed, 65 insertions(+), 13 deletions(-)
diff --git a/Documentation/git-archive-tree.txt b/Documentation/git-archive-tree.txt
index 122c482..25136d9 100644
--- a/Documentation/git-archive-tree.txt
+++ b/Documentation/git-archive-tree.txt
@@ -8,7 +8,7 @@ git-archive-tree - Creates a archive of the f
SYNOPSIS
--------
-'git-archive-tree' -f {tar|zip} [--prefix=<prefix>/] [-0|...|-9]
+'git-archive-tree' -f {tar|tgz|zip} [--prefix=<prefix>/] [-0|...|-9]
<tree-ish> [path...]
DESCRIPTION
@@ -29,7 +29,8 @@ OPTIONS
-------
-f::
- Format of the resulting archive, can be either 'tar' or 'zip'.
+ Format of the resulting archive, can be either 'tar', 'tgz'
+ or 'zip'.
<tree-ish>::
The tree or commit to produce an archive for.
@@ -71,11 +72,11 @@ git archive -f tar --prefix=junk/ HEAD |
latest commit on the current branch, and extracts it in
`/var/tmp/junk` directory.
-git archive -f tar --prefix=git-1.4.0/ v1.4.0 | gzip >git-1.4.0.tar.gz::
+git archive -f tgz --prefix=git-1.4.0/ v1.4.0 >git-1.4.0.tar.gz::
Create a compressed tarball for v1.4.0 release.
-git archive -f tar --prefix=git-1.4.0/ v1.4.0{caret}\{tree\} | gzip >git-1.4.0.tar.gz::
+git archive -f tgz --prefix=git-1.4.0/ v1.4.0{caret}\{tree\} >git-1.4.0.tar.gz::
Create a compressed tarball for v1.4.0 release, but without a
global extended pax header.
diff --git a/archive.h b/archive.h
index 7813962..6a03864 100644
--- a/archive.h
+++ b/archive.h
@@ -3,4 +3,6 @@ #include "tree.h"
typedef int (*write_archive_fn_t)(struct tree *tree, const unsigned char *commit_sha1, const char *prefix, time_t time, const char **pathspec);
int write_tar_archive(struct tree *tree, const unsigned char *commit_sha1, const char *prefix, time_t time, const char **pathspec);
+int write_tgz_archive(struct tree *tree, const unsigned char *commit_sha1,
+ const char *prefix, time_t time, const char **pathspec);
int write_zip_archive(struct tree *tree, const unsigned char *commit_sha1, const char *prefix, time_t time, const char **pathspec);
diff --git a/builtin-archive-tree.c b/builtin-archive-tree.c
index 2c6ee60..f61e26d 100644
--- a/builtin-archive-tree.c
+++ b/builtin-archive-tree.c
@@ -9,12 +9,14 @@ #include "tree-walk.h"
#include "archive.h"
static const char archive_usage[] =
-"git-archive-tree -f {tar|zip} [--prefix=<prefix>/] [-0|...|-9] <tree-ish> [path...]";
+"git-archive-tree -f {tar|tgz|zip} [--prefix=<prefix>/] [-0|...|-9] <tree-ish> [path...]";
static write_archive_fn_t parse_archive_format(const char *format)
{
if (!strcmp(format, "tar"))
return write_tar_archive;
+ if (!strcmp(format, "tgz"))
+ return write_tgz_archive;
if (!strcmp(format, "zip"))
return write_zip_archive;
return NULL;
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index e0da01e..743d53a 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -23,6 +23,10 @@ static unsigned long offset;
static time_t archive_time;
static int tar_umask;
+static gzFile gzstdout;
+
+typedef void (*blocked_write_fn)(const void *data, unsigned long size);
+
/* writes out the whole block, but only if it is full */
static void write_if_needed(void)
{
@@ -36,7 +40,7 @@ static void write_if_needed(void)
* queues up writes, so that all our write(2) calls write exactly one
* full block; pads writes to RECORDSIZE
*/
-static void write_blocked(const void *data, unsigned long size)
+static void do_write_blocked(const void *data, unsigned long size)
{
const char *buf = data;
unsigned long tail;
@@ -68,19 +72,20 @@ static void write_blocked(const void *da
write_if_needed();
}
+static blocked_write_fn write_blocked = do_write_blocked;
+
/*
* The end of tar archives is marked by 2*512 nul bytes and after that
* follows the rest of the block (if any).
*/
static void write_trailer(void)
{
- int tail = BLOCKSIZE - offset;
- memset(block + offset, 0, tail);
- write_or_die(1, block, BLOCKSIZE);
- if (tail < 2 * RECORDSIZE) {
- memset(block, 0, offset);
- write_or_die(1, block, BLOCKSIZE);
- }
+ char zeroes[RECORDSIZE];
+ memset(zeroes, 0, RECORDSIZE);
+ write_blocked(zeroes, RECORDSIZE);
+ write_blocked(zeroes, RECORDSIZE);
+ while (offset)
+ write_blocked(zeroes, RECORDSIZE);
}
static void strbuf_append_string(struct strbuf *sb, const char *s)
@@ -404,6 +409,48 @@ int write_tar_archive(struct tree *tree,
return 0;
}
+static void write_blocked_gzip(const void *data, unsigned long size)
+{
+ const char *p = data;
+ int written;
+ unsigned long tail = size % RECORDSIZE;
+
+ while (size > 0) {
+ written = gzwrite(gzstdout, p, size);
+ if (written == 0) {
+ if (errno == EPIPE)
+ exit(0);
+ die("gzwrite error (%s)", strerror(errno));
+ }
+ size -= written;
+ p += written;
+ }
+
+ if (tail) {
+ z_off_t result = gzseek(gzstdout, RECORDSIZE - tail, SEEK_CUR);
+ if (result == -1)
+ die("gzseek error (%s)", strerror(errno));
+ }
+}
+
+int write_tgz_archive(struct tree *tree, const unsigned char *commit_sha1,
+ const char *prefix, time_t time, const char **pathspec)
+{
+ int result;
+
+ gzstdout = gzdopen(1, "wb");
+ if (!gzstdout)
+ die("zlib is unable to open stdout");
+
+ write_blocked = write_blocked_gzip;
+ result = write_tar_archive(tree, commit_sha1, prefix, time, pathspec);
+
+ if (gzclose(gzstdout) != Z_OK)
+ result = 1;
+
+ return result;
+}
+
static const char *exec = "git-upload-tar";
static int remote_tar(int argc, const char **argv)
--
VGER BF report: U 0.497484
next prev parent reply other threads:[~2006-09-02 12:38 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-02 12:23 [PATCH][RFC] Add git-archive-tree Rene Scharfe
2006-09-02 12:37 ` Rene Scharfe [this message]
2006-09-02 13:10 ` Rene Scharfe
2006-09-02 20:13 ` Franck Bui-Huu
2006-09-04 18:22 ` Rene Scharfe
2006-09-04 20:09 ` Junio C Hamano
2006-09-04 22:02 ` Rene Scharfe
2006-09-04 22:20 ` Junio C Hamano
2006-09-05 11:43 ` Franck Bui-Huu
2006-09-02 21:19 ` Junio C Hamano
2006-09-02 14:17 ` Rene Scharfe
2006-09-02 15:24 ` Franck Bui-Huu
2006-09-02 16:08 ` Rene Scharfe
2006-09-02 21:27 ` Junio C Hamano
2006-09-06 18:05 ` Rene Scharfe
2006-09-06 21:47 ` Junio C Hamano
2006-09-17 11:54 ` Rene Scharfe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=44F97B24.7090305@lsrfire.ath.cx \
--to=rene.scharfe@lsrfire.ath.cx \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
--cc=vagabon.xyz@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).