git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] git-archive: recursive prefix directory creation
@ 2007-05-19 11:37 René Scharfe
  2007-05-19 18:17 ` Junio C Hamano
  0 siblings, 1 reply; 5+ messages in thread
From: René Scharfe @ 2007-05-19 11:37 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List

Currently git-archive only adds a single directory entry for prefixes,
e.g. for --prefix=a/b/c/ only the directory a/b/c/ would be added to
the archive, not a/ nor a/b/.  While tar and unzip don't seem to have
a problem handling these missing entries, their omission was not
intended.

This patch replaces the prefix path creation code in git-archive with
calls to a new path walker similar to read_tree_recursive, named
descend_leading_dirs.  It calls a read_tree_fn_t function for each
leading directory while descending deeper into the path (e.g. first
a/, then a/b/ etc.).

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
 archive-tar.c |   11 ++---------
 archive-zip.c |   11 ++---------
 tree.c        |   45 +++++++++++++++++++++++++++++++++++++++++++++
 tree.h        |    5 +++++
 4 files changed, 54 insertions(+), 18 deletions(-)

diff --git a/archive-tar.c b/archive-tar.c
index 33e7657..7ea396d 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -308,15 +308,8 @@ int write_tar_archive(struct archiver_args *args)
 	if (args->commit_sha1)
 		write_global_extended_header(args->commit_sha1);
 
-	if (args->base && plen > 0 && args->base[plen - 1] == '/') {
-		char *base = xstrdup(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);
-	}
+	descend_leading_dirs(args->tree->object.sha1, args->base, plen,
+	                     040777, 0, write_tar_entry);
 	read_tree_recursive(args->tree, args->base, plen, 0,
 			    args->pathspec, write_tar_entry);
 	write_trailer();
diff --git a/archive-zip.c b/archive-zip.c
index 3cbf6bb..2fc22ff 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -317,15 +317,8 @@ int write_zip_archive(struct archiver_args *args)
 	zip_dir_size = ZIP_DIRECTORY_MIN_SIZE;
 	verbose = args->verbose;
 
-	if (args->base && plen > 0 && args->base[plen - 1] == '/') {
-		char *base = xstrdup(args->base);
-		int baselen = strlen(base);
-
-		while (baselen > 0 && base[baselen - 1] == '/')
-			base[--baselen] = '\0';
-		write_zip_entry(args->tree->object.sha1, "", 0, base, 040777, 0);
-		free(base);
-	}
+	descend_leading_dirs(args->tree->object.sha1, args->base, plen,
+	                     040777, 0, write_zip_entry);
 	read_tree_recursive(args->tree, args->base, plen, 0,
 			    args->pathspec, write_zip_entry);
 	write_zip_trailer(args->commit_sha1);
diff --git a/tree.c b/tree.c
index e4a39aa..5cd1f90 100644
--- a/tree.c
+++ b/tree.c
@@ -231,3 +231,48 @@ struct tree *parse_tree_indirect(const unsigned char *sha1)
 			parse_object(obj->sha1);
 	} while (1);
 }
+
+int descend_leading_dirs(const unsigned char *sha1,
+                         const char *path, size_t pathlen,
+                         unsigned int mode, int stage, read_tree_fn_t fn)
+{
+	int err;
+	size_t baselen;
+
+	if (!path)
+		return 0;
+
+	/* Discard file name part. */
+	while (pathlen > 0 && path[pathlen - 1] != '/')
+		pathlen--;
+	while (pathlen > 0 && path[pathlen - 1] == '/')
+		pathlen--;
+	if (pathlen == 0)
+		return 0;
+
+	/* Now separate base and current directory name. */
+	baselen = pathlen;
+	while (baselen > 0 && path[baselen - 1] != '/')
+		baselen--;
+
+	err = descend_leading_dirs(null_sha1, path, baselen, mode, stage, fn);
+
+	if (!err) {
+		/* We need a NUL-terminated version of the directory name. */
+		char *dirname = xstrndup(path + baselen, pathlen - baselen);
+		switch (fn(sha1, path, baselen, dirname, mode, stage)) {
+		case 0:
+			err = 1;
+			break;
+		case READ_TREE_RECURSIVE:
+			err = 0;
+			break;
+		default:
+			err = -1;
+			break;
+		}
+		free(dirname);
+	}
+
+	return err;
+}
diff --git a/tree.h b/tree.h
index dd25c53..6b0f5d9 100644
--- a/tree.h
+++ b/tree.h
@@ -30,4 +30,9 @@ extern int read_tree_recursive(struct tree *tree,
 
 extern int read_tree(struct tree *tree, int stage, const char **paths);
 
+extern int descend_leading_dirs(const unsigned char *sha1,
+                                const char *path, size_t pathlen,
+                                unsigned int mode, int stage,
+                                read_tree_fn_t fn);
+
 #endif /* TREE_H */

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] git-archive: recursive prefix directory creation
  2007-05-19 11:37 [PATCH] git-archive: recursive prefix directory creation René Scharfe
@ 2007-05-19 18:17 ` Junio C Hamano
  2007-05-19 19:56   ` René Scharfe
  0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2007-05-19 18:17 UTC (permalink / raw)
  To: René Scharfe; +Cc: Git Mailing List

René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:

> Currently git-archive only adds a single directory entry for prefixes,
> e.g. for --prefix=a/b/c/ only the directory a/b/c/ would be added to
> the archive, not a/ nor a/b/.  While tar and unzip don't seem to have
> a problem handling these missing entries, their omission was not
> intended.

Until we start tracking directories (we briefly discussed, and I
think I agree with Linus that it should not be too painful), I'd
rather keep the current behaviour which I feel is more
consistent with what we really are doing.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] git-archive: recursive prefix directory creation
  2007-05-19 18:17 ` Junio C Hamano
@ 2007-05-19 19:56   ` René Scharfe
  2007-05-19 20:22     ` Junio C Hamano
  0 siblings, 1 reply; 5+ messages in thread
From: René Scharfe @ 2007-05-19 19:56 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List

Junio C Hamano schrieb:
> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
> 
>> Currently git-archive only adds a single directory entry for prefixes,
>> e.g. for --prefix=a/b/c/ only the directory a/b/c/ would be added to
>> the archive, not a/ nor a/b/.  While tar and unzip don't seem to have
>> a problem handling these missing entries, their omission was not
>> intended.
> 
> Until we start tracking directories (we briefly discussed, and I
> think I agree with Linus that it should not be too painful), I'd
> rather keep the current behaviour which I feel is more
> consistent with what we really are doing.

Hmm, fair enough.  I started out with a simple cleanup and then I guess
went a bit overboard with that overblown path walker. :-]

René

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] git-archive: recursive prefix directory creation
  2007-05-19 19:56   ` René Scharfe
@ 2007-05-19 20:22     ` Junio C Hamano
  2007-05-20 10:51       ` René Scharfe
  0 siblings, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2007-05-19 20:22 UTC (permalink / raw)
  To: René Scharfe; +Cc: Git Mailing List

René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:

> Junio C Hamano schrieb:
>> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
>> 
>>> Currently git-archive only adds a single directory entry for prefixes,
>>> e.g. for --prefix=a/b/c/ only the directory a/b/c/ would be added to
>>> the archive, not a/ nor a/b/.  While tar and unzip don't seem to have
>>> a problem handling these missing entries, their omission was not
>>> intended.
>> 
>> Until we start tracking directories (we briefly discussed, and I
>> think I agree with Linus that it should not be too painful), I'd
>> rather keep the current behaviour which I feel is more
>> consistent with what we really are doing.
>
> Hmm, fair enough.  I started out with a simple cleanup and then I guess
> went a bit overboard with that overblown path walker. :-]

Well, I take that back -- I did not realize you were primarily
talking about the LEADING part of the path.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] git-archive: recursive prefix directory creation
  2007-05-19 20:22     ` Junio C Hamano
@ 2007-05-20 10:51       ` René Scharfe
  0 siblings, 0 replies; 5+ messages in thread
From: René Scharfe @ 2007-05-20 10:51 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Git Mailing List

Junio C Hamano schrieb:
> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
> 
>> Junio C Hamano schrieb:
>>> René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
>>> 
>>>> Currently git-archive only adds a single directory entry for
>>>> prefixes, e.g. for --prefix=a/b/c/ only the directory a/b/c/
>>>> would be added to the archive, not a/ nor a/b/.  While tar and
>>>> unzip don't seem to have a problem handling these missing
>>>> entries, their omission was not intended.
>>> Until we start tracking directories (we briefly discussed, and I 
>>> think I agree with Linus that it should not be too painful), I'd 
>>> rather keep the current behaviour which I feel is more consistent
>>> with what we really are doing.
>> Hmm, fair enough.  I started out with a simple cleanup and then I
>> guess went a bit overboard with that overblown path walker. :-]
> 
> Well, I take that back -- I did not realize you were primarily 
> talking about the LEADING part of the path.

In any case, please don't apply this patch.  I checked again, and it
turns out both tar and zip don't always add leading directories to
archives.  So my "cleanup" only adds bloat.  I'll try to find another
way to beautify the code.

René

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-05-20 10:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-05-19 11:37 [PATCH] git-archive: recursive prefix directory creation René Scharfe
2007-05-19 18:17 ` Junio C Hamano
2007-05-19 19:56   ` René Scharfe
2007-05-19 20:22     ` Junio C Hamano
2007-05-20 10:51       ` René Scharfe

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).