summaryrefslogtreecommitdiff
path: root/tmp-objdir.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2016-12-12 19:53:55 (GMT)
committerJunio C Hamano <gitster@pobox.com>2016-12-12 23:10:46 (GMT)
commitaae2ae4f74f91f434f7f5c3ac25f37d80a9b319e (patch)
tree01800d26a7669c4d2e0dabdb3b8084132052df43 /tmp-objdir.c
parentcf3c6352100a0d302276e46e3f9a7f0804e224d8 (diff)
downloadgit-aae2ae4f74f91f434f7f5c3ac25f37d80a9b319e.zip
git-aae2ae4f74f91f434f7f5c3ac25f37d80a9b319e.tar.gz
git-aae2ae4f74f91f434f7f5c3ac25f37d80a9b319e.tar.bz2
tmp-objdir: quote paths we add to alternates
Commit 722ff7f87 (receive-pack: quarantine objects until pre-receive accepts, 2016-10-03) regressed pushes to repositories with colon (or semi-colon in Windows in them) because it adds the repository's main object directory to GIT_ALTERNATE_OBJECT_DIRECTORIES. The receiver interprets the colon as a delimiter, not as part of the path, and index-pack is unable to find objects which it needs to resolve deltas. The previous commit introduced a quoting mechanism for the alternates list; let's use it here to cover this case. We'll avoid quoting when we can, though. This alternate setup is also used when calling hooks, so it's possible that the user may call older git implementations which don't understand the quoting mechanism. By quoting only when necessary, this setup will continue to work unless the user _also_ has a repository whose path contains the delimiter. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'tmp-objdir.c')
-rw-r--r--tmp-objdir.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/tmp-objdir.c b/tmp-objdir.c
index 64435f2..b2d9280 100644
--- a/tmp-objdir.c
+++ b/tmp-objdir.c
@@ -5,6 +5,7 @@
#include "string-list.h"
#include "strbuf.h"
#include "argv-array.h"
+#include "quote.h"
struct tmp_objdir {
struct strbuf path;
@@ -79,12 +80,27 @@ static void remove_tmp_objdir_on_signal(int signo)
*/
static void env_append(struct argv_array *env, const char *key, const char *val)
{
- const char *old = getenv(key);
+ struct strbuf quoted = STRBUF_INIT;
+ const char *old;
+ /*
+ * Avoid quoting if it's not necessary, for maximum compatibility
+ * with older parsers which don't understand the quoting.
+ */
+ if (*val == '"' || strchr(val, PATH_SEP)) {
+ strbuf_addch(&quoted, '"');
+ quote_c_style(val, &quoted, NULL, 1);
+ strbuf_addch(&quoted, '"');
+ val = quoted.buf;
+ }
+
+ old = getenv(key);
if (!old)
argv_array_pushf(env, "%s=%s", key, val);
else
argv_array_pushf(env, "%s=%s%c%s", key, old, PATH_SEP, val);
+
+ strbuf_release(&quoted);
}
static void env_replace(struct argv_array *env, const char *key, const char *val)