Bug: git archive not doing export-subst when using --prefix= option

3 messages, 2 authors, 2016-06-15 · open the first message on its own page

Bug: git archive not doing export-subst when using --prefix= option

From: Ulrik Sverdrup <hidden>
Date: 2016-06-15 22:44:27

In one of my small projects, I just tried to add an export-subst format to
my version file to have the git version in the released tarball. However it
seems git-archive --prefix="tarballname-version/" does not work well
together with export-subst.

I have very old git! (v1.5.4.4). So please help me and try to reproduce
this with newer versions:

The repo is publicly available at

git clone git://repo.or.cz/dragbox.git

The file in the repo having an export substitution format is
Dragbox/version.py.in

Now try to export the git tree with git-archive, with and without --prefix=
We will do some hackery and grep the binary output.

	$ git archive HEAD | grep --text "git_version"
	git_version = "9c3f6c0af7e67a354cac9a24e24e2057d17778ef"
	$ git archive --prefix="dragbox-git/" HEAD | grep --text "git_version"
	git_version = "$Format:%H$"


I noticed in another even smaller repository that it would not behave the
same but equally spurious; it would only perform the substitution for some
prefixes and not for others (for example with or without ending slash)

Regards
Ulrik Sverdrup

[PATCH] git-archive: ignore prefix when checking file attribute

From: René Scharfe <hidden>
Date: 2016-06-15 22:44:28

Ulrik Sverdrup noticed that git-archive doesn't correctly apply the attribute
export-subst when the option --prefix is given, too.

When it checked if a file has the attribute turned on, git-archive would try
to look up the full path -- including the prefix -- in .gitattributes.  That's
wrong, as the prefix doesn't need to have any relation to any existing
directories, tracked or not.

This patch makes git-archive ignore the prefix when looking up if value of the
attribute export-subst for a file.

Signed-off-by: Rene Scharfe <redacted>
---
Ulrik, does this patch fix the problem for you?  It applies to v1.5.4.4 and
v1.5.5 equally.

 archive-tar.c       |    6 ++++--
 archive-zip.c       |    6 ++++--
 t/t5000-tar-tree.sh |   15 ++++++++++++++-
 3 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/archive-tar.c b/archive-tar.c
index 30aa2e2..4add802 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -17,6 +17,7 @@ static time_t archive_time;
 static int tar_umask = 002;
 static int verbose;
 static const struct commit *commit;
+static size_t base_len;
 
 /* writes out the whole block, but only if it is full */
 static void write_if_needed(void)
@@ -251,8 +252,8 @@ static int write_tar_entry(const unsigned char *sha1,
 		buffer = NULL;
 		size = 0;
 	} else {
-		buffer = sha1_file_to_archive(path.buf, sha1, mode, &type,
-		                              &size, commit);
+		buffer = sha1_file_to_archive(path.buf + base_len, sha1, mode,
+				&type, &size, commit);
 		if (!buffer)
 			die("cannot read %s", sha1_to_hex(sha1));
 	}
@@ -272,6 +273,7 @@ int write_tar_archive(struct archiver_args *args)
 	archive_time = args->time;
 	verbose = args->verbose;
 	commit = args->commit;
+	base_len = args->base ? strlen(args->base) : 0;
 
 	if (args->commit_sha1)
 		write_global_extended_header(args->commit_sha1);
diff --git a/archive-zip.c b/archive-zip.c
index 74e30f6..18c0f87 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -13,6 +13,7 @@ static int verbose;
 static int zip_date;
 static int zip_time;
 static const struct commit *commit;
+static size_t base_len;
 
 static unsigned char *zip_dir;
 static unsigned int zip_dir_size;
@@ -197,8 +198,8 @@ static int write_zip_entry(const unsigned char *sha1,
 		if (S_ISREG(mode) && zlib_compression_level != 0)
 			method = 8;
 		result = 0;
-		buffer = sha1_file_to_archive(path, sha1, mode, &type, &size,
-		                              commit);
+		buffer = sha1_file_to_archive(path + base_len, sha1, mode,
+				&type, &size, commit);
 		if (!buffer)
 			die("cannot read %s", sha1_to_hex(sha1));
 		crc = crc32(crc, buffer, size);
@@ -321,6 +322,7 @@ int write_zip_archive(struct archiver_args *args)
 	zip_dir_size = ZIP_DIRECTORY_MIN_SIZE;
 	verbose = args->verbose;
 	commit = args->commit;
+	base_len = args->base ? strlen(args->base) : 0;
 
 	if (args->base && plen > 0 && args->base[plen - 1] == '/') {
 		char *base = xstrdup(args->base);
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index dca2067..fa62b6a 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -109,9 +109,10 @@ test_expect_success \
     'diff -r a c/prefix/a'
 
 test_expect_success \
-    'create an archive with a substfiles' \
+    'create archives with substfiles' \
     'echo "substfile?" export-subst >a/.gitattributes &&
      git archive HEAD >f.tar &&
+     git archive --prefix=prefix/ HEAD >g.tar &&
      rm a/.gitattributes'
 
 test_expect_success \
@@ -127,6 +128,18 @@ test_expect_success \
 '
 
 test_expect_success \
+    'extract substfiles from archive with prefix' \
+    '(mkdir g && cd g && $TAR xf -) <g.tar'
+
+test_expect_success \
+     'validate substfile contents from archive with prefix' \
+     'git log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \
+      >g/prefix/a/substfile1.expected &&
+      diff g/prefix/a/substfile1.expected g/prefix/a/substfile1 &&
+      diff a/substfile2 g/prefix/a/substfile2
+'
+
+test_expect_success \
     'git archive --format=zip' \
     'git archive --format=zip HEAD >d.zip'
 

Re: [PATCH] git-archive: ignore prefix when checking file attribute

From: Ulrik Sverdrup <hidden>
Date: 2016-06-15 22:44:28

2008/4/9, René Scharfe [off-list ref]:
Ulrik Sverdrup noticed that git-archive doesn't correctly apply the attribute
 export-subst when the option --prefix is given, too.

 When it checked if a file has the attribute turned on, git-archive would try
 to look up the full path -- including the prefix -- in .gitattributes.  That's
 wrong, as the prefix doesn't need to have any relation to any existing
 directories, tracked or not.

 This patch makes git-archive ignore the prefix when looking up if value of the
 attribute export-subst for a file.

 Signed-off-by: Rene Scharfe [off-list ref]
 ---
 Ulrik, does this patch fix the problem for you?  It applies to v1.5.4.4 and
 v1.5.5 equally.

Thanks for the patch René!

First I reproduced my problem on vanilla git v1.5.5, and it is still
there as in v.1.5.4.4.
I applied this patch and that fixed my issue, testing both tar and zip.

Ulrik Sverdrup
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help