summaryrefslogtreecommitdiff
path: root/archive.c
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2022-05-28 23:11:13 (GMT)
committerJunio C Hamano <gitster@pobox.com>2022-05-31 06:07:31 (GMT)
commitde1f68a968e64b3e1e2979222238fec1f045bbf3 (patch)
treef73cd5decd04211e3b4f855e43c6cc9d0929d45d /archive.c
parent237a1d138c4322a7e934f129dee02e2ea6a214cd (diff)
downloadgit-de1f68a968e64b3e1e2979222238fec1f045bbf3.zip
git-de1f68a968e64b3e1e2979222238fec1f045bbf3.tar.gz
git-de1f68a968e64b3e1e2979222238fec1f045bbf3.tar.bz2
archive --add-virtual-file: allow paths containing colons
By allowing the path to be enclosed in double-quotes, we can avoid the limitation that paths cannot contain colons. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'archive.c')
-rw-r--r--archive.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/archive.c b/archive.c
index 29a90c7..d5109ab 100644
--- a/archive.c
+++ b/archive.c
@@ -9,6 +9,7 @@
#include "parse-options.h"
#include "unpack-trees.h"
#include "dir.h"
+#include "quote.h"
static char const * const archive_usage[] = {
N_("git archive [<options>] <tree-ish> [<path>...]"),
@@ -535,22 +536,31 @@ static int add_file_cb(const struct option *opt, const char *arg, int unset)
die(_("Not a regular file: %s"), path);
info->content = NULL; /* read the file later */
} else if (!strcmp(opt->long_name, "add-virtual-file")) {
- const char *colon = strchr(arg, ':');
- char *p;
+ struct strbuf buf = STRBUF_INIT;
+ const char *p = arg;
+
+ if (*p != '"')
+ p = strchr(p, ':');
+ else if (unquote_c_style(&buf, p, &p) < 0)
+ die(_("unclosed quote: '%s'"), arg);
- if (!colon)
+ if (!p || *p != ':')
die(_("missing colon: '%s'"), arg);
- p = xstrndup(arg, colon - arg);
- if (!args->prefix)
- path = p;
- else {
- path = prefix_filename(args->prefix, p);
- free(p);
+ if (p == arg)
+ die(_("empty file name: '%s'"), arg);
+
+ path = buf.len ?
+ strbuf_detach(&buf, NULL) : xstrndup(arg, p - arg);
+
+ if (args->prefix) {
+ char *save = path;
+ path = prefix_filename(args->prefix, path);
+ free(save);
}
memset(&info->stat, 0, sizeof(info->stat));
info->stat.st_mode = S_IFREG | 0644;
- info->content = xstrdup(colon + 1);
+ info->content = xstrdup(p + 1);
info->stat.st_size = strlen(info->content);
} else {
BUG("add_file_cb() called for %s", opt->long_name);