summaryrefslogtreecommitdiff
path: root/archive.c
diff options
context:
space:
mode:
Diffstat (limited to 'archive.c')
-rw-r--r--archive.c108
1 files changed, 50 insertions, 58 deletions
diff --git a/archive.c b/archive.c
index 1ee837d717..346f3b2f1a 100644
--- a/archive.c
+++ b/archive.c
@@ -7,10 +7,10 @@
#include "unpack-trees.h"
static char const * const archive_usage[] = {
- "git archive [options] <tree-ish> [<path>...]",
- "git archive --list",
- "git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [<path>...]",
- "git archive --remote <repo> [--exec <cmd>] --list",
+ N_("git archive [options] <tree-ish> [<path>...]"),
+ N_("git archive --list"),
+ N_("git archive --remote <repo> [--exec <cmd>] [options] <tree-ish> [<path>...]"),
+ N_("git archive --remote <repo> [--exec <cmd>] --list"),
NULL
};
@@ -59,12 +59,15 @@ static void format_subst(const struct commit *commit,
free(to_free);
}
-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 *sha1_file_to_archive(const struct archiver_args *args,
+ const char *path, const unsigned char *sha1,
+ unsigned int mode, enum object_type *type,
+ unsigned long *sizep)
{
void *buffer;
+ const struct commit *commit = args->convert ? args->commit : NULL;
+ path += args->baselen;
buffer = read_sha1_file(sha1, type, sizep);
if (buffer && S_ISREG(mode)) {
struct strbuf buf = STRBUF_INIT;
@@ -109,45 +112,37 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
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;
- void *buffer;
+ args->convert = 0;
strbuf_reset(&path);
strbuf_grow(&path, PATH_MAX);
strbuf_add(&path, args->base, args->baselen);
strbuf_add(&path, base, baselen);
strbuf_addstr(&path, filename);
+ if (S_ISDIR(mode) || S_ISGITLINK(mode))
+ strbuf_addch(&path, '/');
path_without_prefix = path.buf + args->baselen;
setup_archive_check(check);
if (!git_check_attr(path_without_prefix, ARRAY_SIZE(check), check)) {
if (ATTR_TRUE(check[0].value))
return 0;
- convert = ATTR_TRUE(check[1].value);
+ args->convert = ATTR_TRUE(check[1].value);
}
if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
- strbuf_addch(&path, '/');
if (args->verbose)
fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
- err = write_entry(args, sha1, path.buf, path.len, mode, NULL, 0);
+ err = write_entry(args, sha1, path.buf, path.len, mode);
if (err)
return err;
return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
}
- 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)
fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
- err = write_entry(args, sha1, path.buf, path.len, mode, buffer, size);
- free(buffer);
- return err;
+ return write_entry(args, sha1, path.buf, path.len, mode);
}
int write_archive_entries(struct archiver_args *args,
@@ -156,7 +151,6 @@ int write_archive_entries(struct archiver_args *args,
struct archiver_context context;
struct unpack_trees_options opts;
struct tree_desc t;
- struct pathspec pathspec;
int err;
if (args->baselen > 0 && args->base[args->baselen - 1] == '/') {
@@ -167,7 +161,7 @@ int write_archive_entries(struct archiver_args *args,
if (args->verbose)
fprintf(stderr, "%.*s\n", (int)len, args->base);
err = write_entry(args, args->tree->object.sha1, args->base,
- len, 040777, NULL, 0);
+ len, 040777);
if (err)
return err;
}
@@ -191,10 +185,8 @@ int write_archive_entries(struct archiver_args *args,
git_attr_set_direction(GIT_ATTR_INDEX, &the_index);
}
- init_pathspec(&pathspec, args->pathspec);
- err = read_tree_recursive(args->tree, "", 0, 0, &pathspec,
+ err = read_tree_recursive(args->tree, "", 0, 0, &args->pathspec,
write_archive_entry, &context);
- free_pathspec(&pathspec);
if (err == READ_TREE_RECURSIVE)
err = 0;
return err;
@@ -227,7 +219,7 @@ static int path_exists(struct tree *tree, const char *path)
struct pathspec pathspec;
int ret;
- init_pathspec(&pathspec, paths);
+ parse_pathspec(&pathspec, 0, 0, "", paths);
ret = read_tree_recursive(tree, "", 0, 0, &pathspec, reject_entry, NULL);
free_pathspec(&pathspec);
return ret != 0;
@@ -236,11 +228,18 @@ static int path_exists(struct tree *tree, const char *path)
static void parse_pathspec_arg(const char **pathspec,
struct archiver_args *ar_args)
{
- ar_args->pathspec = pathspec = get_pathspec("", pathspec);
+ /*
+ * must be consistent with parse_pathspec in path_exists()
+ * Also if pathspec patterns are dependent, we're in big
+ * trouble as we test each one separately
+ */
+ parse_pathspec(&ar_args->pathspec, 0,
+ PATHSPEC_PREFER_FULL,
+ "", pathspec);
if (pathspec) {
while (*pathspec) {
- if (!path_exists(ar_args->tree, *pathspec))
- die("path not found: %s", *pathspec);
+ if (**pathspec && !path_exists(ar_args->tree, *pathspec))
+ die(_("pathspec '%s' did not match any files"), *pathspec);
pathspec++;
}
}
@@ -260,18 +259,11 @@ static void parse_treeish_arg(const char **argv,
/* Remotes are only allowed to fetch actual refs */
if (remote) {
char *ref = NULL;
- const char *refname, *colon = NULL;
-
- colon = strchr(name, ':');
- if (colon)
- refname = xstrndup(name, colon - name);
- else
- refname = name;
-
- if (!dwim_ref(refname, strlen(refname), sha1, &ref))
- die("no such ref: %s", refname);
- if (refname != name)
- free((void *)refname);
+ const char *colon = strchr(name, ':');
+ int refnamelen = colon ? colon - name : strlen(name);
+
+ if (!dwim_ref(name, refnamelen, sha1, &ref))
+ die("no such ref: %.*s", refnamelen, name);
free(ref);
}
@@ -332,16 +324,16 @@ static int parse_archive_args(int argc, const char **argv,
int worktree_attributes = 0;
struct option opts[] = {
OPT_GROUP(""),
- OPT_STRING(0, "format", &format, "fmt", "archive format"),
- OPT_STRING(0, "prefix", &base, "prefix",
- "prepend prefix to each pathname in the archive"),
- OPT_STRING('o', "output", &output, "file",
- "write the archive to this file"),
+ OPT_STRING(0, "format", &format, N_("fmt"), N_("archive format")),
+ OPT_STRING(0, "prefix", &base, N_("prefix"),
+ N_("prepend prefix to each pathname in the archive")),
+ OPT_STRING('o', "output", &output, N_("file"),
+ N_("write the archive to this file")),
OPT_BOOL(0, "worktree-attributes", &worktree_attributes,
- "read .gitattributes in working directory"),
- OPT__VERBOSE(&verbose, "report archived files on stderr"),
- OPT__COMPR('0', &compression_level, "store only", 0),
- OPT__COMPR('1', &compression_level, "compress faster", 1),
+ N_("read .gitattributes in working directory")),
+ OPT__VERBOSE(&verbose, N_("report archived files on stderr")),
+ OPT__COMPR('0', &compression_level, N_("store only"), 0),
+ OPT__COMPR('1', &compression_level, N_("compress faster"), 1),
OPT__COMPR_HIDDEN('2', &compression_level, 2),
OPT__COMPR_HIDDEN('3', &compression_level, 3),
OPT__COMPR_HIDDEN('4', &compression_level, 4),
@@ -349,15 +341,15 @@ static int parse_archive_args(int argc, const char **argv,
OPT__COMPR_HIDDEN('6', &compression_level, 6),
OPT__COMPR_HIDDEN('7', &compression_level, 7),
OPT__COMPR_HIDDEN('8', &compression_level, 8),
- OPT__COMPR('9', &compression_level, "compress better", 9),
+ OPT__COMPR('9', &compression_level, N_("compress better"), 9),
OPT_GROUP(""),
OPT_BOOL('l', "list", &list,
- "list supported archive formats"),
+ N_("list supported archive formats")),
OPT_GROUP(""),
- OPT_STRING(0, "remote", &remote, "repo",
- "retrieve the archive from remote repository <repo>"),
- OPT_STRING(0, "exec", &exec, "cmd",
- "path to the remote git-upload-archive command"),
+ OPT_STRING(0, "remote", &remote, N_("repo"),
+ N_("retrieve the archive from remote repository <repo>")),
+ OPT_STRING(0, "exec", &exec, N_("command"),
+ N_("path to the remote git-upload-archive command")),
OPT_END()
};
@@ -448,7 +440,7 @@ static int match_extension(const char *filename, const char *ext)
* prefix is non-empty (k.e., we don't match .tar.gz with no actual
* filename).
*/
- if (prefixlen < 2 || filename[prefixlen-1] != '.')
+ if (prefixlen < 2 || filename[prefixlen - 1] != '.')
return 0;
return !strcmp(filename + prefixlen, ext);
}