Code

Merge branch 'maint-1.5.4' into maint
[git.git] / archive-zip.c
index f63dff383483c482b414432b697306c53b320d00..18c0f8710c6150e3b0211d311a70bf4b34608370 100644 (file)
@@ -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;
@@ -192,12 +193,13 @@ static int write_zip_entry(const unsigned char *sha1,
                compressed_size = 0;
        } else if (S_ISREG(mode) || S_ISLNK(mode)) {
                method = 0;
-               attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) : 0;
+               attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) :
+                       (mode & 0111) ? ((mode) << 16) : 0;
                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);
@@ -231,7 +233,8 @@ static int write_zip_entry(const unsigned char *sha1,
        }
 
        copy_le32(dirent.magic, 0x02014b50);
-       copy_le16(dirent.creator_version, S_ISLNK(mode) ? 0x0317 : 0);
+       copy_le16(dirent.creator_version,
+               S_ISLNK(mode) || (S_ISREG(mode) && (mode & 0111)) ? 0x0317 : 0);
        copy_le16(dirent.version, 10);
        copy_le16(dirent.flags, 0);
        copy_le16(dirent.compression_method, method);
@@ -319,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);