archive: unify file attribute handling
authorRené Scharfe <rene.scharfe@lsrfire.ath.cx>
Mon, 14 Jul 2008 19:22:29 +0000 (21:22 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 15 Jul 2008 14:18:04 +0000 (07:18 -0700)
Now that all file attribute handling for git archive has moved to archive.c,
we can unexport sha1_file_to_archive() and is_archive_path_ignored() even
disappears.

Add setup_archive_check(), modelled after similar functions used in the code
of other commands that support multiple file attributes.

Also remove convert_to_archive(), as it's only remaining function with
attribute handling gone was to call format_subst() if commit was not NULL,
which is now checked in sha1_file_to_archive().

Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
archive.c
archive.h

index 58de55e..b8b45ba 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -36,34 +36,9 @@ static void format_subst(const struct commit *commit,
        free(to_free);
 }
 
-static int convert_to_archive(const char *path,
-                              const void *src, size_t len,
-                              struct strbuf *buf,
-                              const struct commit *commit)
-{
-       static struct git_attr *attr_export_subst;
-       struct git_attr_check check[1];
-
-       if (!commit)
-               return 0;
-
-       if (!attr_export_subst)
-               attr_export_subst = git_attr("export-subst", 12);
-
-       check[0].attr = attr_export_subst;
-       if (git_checkattr(path, ARRAY_SIZE(check), check))
-               return 0;
-       if (!ATTR_TRUE(check[0].value))
-               return 0;
-
-       format_subst(commit, src, len, buf);
-       return 1;
-}
-
-void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
-                           unsigned int mode, enum object_type *type,
-                           unsigned long *sizep,
-                           const struct commit *commit)
+static void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
+               unsigned int mode, enum object_type *type,
+               unsigned long *sizep, const struct commit *commit)
 {
        void *buffer;
 
@@ -75,7 +50,8 @@ void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
                strbuf_init(&buf, 0);
                strbuf_attach(&buf, buffer, *sizep, *sizep + 1);
                convert_to_working_tree(path, buf.buf, buf.len, &buf);
-               convert_to_archive(path, buf.buf, buf.len, &buf, commit);
+               if (commit)
+                       format_subst(commit, buf.buf, buf.len, &buf);
                buffer = strbuf_detach(&buf, &size);
                *sizep = size;
        }
@@ -83,18 +59,17 @@ void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
        return buffer;
 }
 
-int is_archive_path_ignored(const char *path)
+static void setup_archive_check(struct git_attr_check *check)
 {
        static struct git_attr *attr_export_ignore;
-       struct git_attr_check check[1];
+       static struct git_attr *attr_export_subst;
 
-       if (!attr_export_ignore)
+       if (!attr_export_ignore) {
                attr_export_ignore = git_attr("export-ignore", 13);
-
+               attr_export_subst = git_attr("export-subst", 12);
+       }
        check[0].attr = attr_export_ignore;
-       if (git_checkattr(path, ARRAY_SIZE(check), check))
-               return 0;
-       return ATTR_TRUE(check[0].value);
+       check[1].attr = attr_export_subst;
 }
 
 struct archiver_context {
@@ -110,6 +85,9 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
        struct archiver_context *c = context;
        struct archiver_args *args = c->args;
        write_archive_entry_fn_t write_entry = c->write_entry;
+       struct git_attr_check check[2];
+       const char *path_without_prefix;
+       int convert = 0;
        int err;
        enum object_type type;
        unsigned long size;
@@ -119,9 +97,14 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
        strbuf_grow(&path, PATH_MAX);
        strbuf_add(&path, base, baselen);
        strbuf_addstr(&path, filename);
+       path_without_prefix = path.buf + args->baselen;
 
-       if (is_archive_path_ignored(path.buf + args->baselen))
-               return 0;
+       setup_archive_check(check);
+       if (!git_checkattr(path_without_prefix, ARRAY_SIZE(check), check)) {
+               if (ATTR_TRUE(check[0].value))
+                       return 0;
+               convert = ATTR_TRUE(check[1].value);
+       }
 
        if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
                strbuf_addch(&path, '/');
@@ -133,8 +116,8 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
                return READ_TREE_RECURSIVE;
        }
 
-       buffer = sha1_file_to_archive(path.buf + args->baselen, sha1, mode,
-                       &type, &size, args->commit);
+       buffer = sha1_file_to_archive(path_without_prefix, sha1, mode,
+                       &type, &size, convert ? args->commit : NULL);
        if (!buffer)
                return error("cannot read %s", sha1_to_hex(sha1));
        if (args->verbose)
index 4e44549..88ee3be 100644 (file)
--- a/archive.h
+++ b/archive.h
@@ -43,9 +43,6 @@ extern int write_tar_archive(struct archiver_args *);
 extern int write_zip_archive(struct archiver_args *);
 extern void *parse_extra_zip_args(int argc, const char **argv);
 
-extern void *sha1_file_to_archive(const char *path, const unsigned char *sha1, unsigned int mode, enum object_type *type, unsigned long *size, const struct commit *commit);
-extern int is_archive_path_ignored(const char *path);
-
 extern int write_archive_entries(struct archiver_args *args, write_archive_entry_fn_t write_entry);
 
 #endif /* ARCHIVE_H */