diff --git a/t/t5547-push-quarantine.sh b/t/t5547-push-quarantine.sh index 1e5d32d068..6275ec807b 100755 --- a/t/t5547-push-quarantine.sh +++ b/t/t5547-push-quarantine.sh @@ -33,4 +33,23 @@ test_expect_success 'rejected objects are removed' ' test_cmp expect actual ' +# MINGW does not allow colons in pathnames in the first place +test_expect_success !MINGW 'push to repo path with colon' ' + # The interesting failure case here is when the + # receiving end cannot access its original object directory, + # so make it likely for us to generate a delta by having + # a non-trivial file with multiple versions. + + test-genrandom foo 4096 >file.bin && + git add file.bin && + git commit -m bin && + git clone --bare . xxx:yyy.git && + + echo change >>file.bin && + git commit -am change && + # Note that we have to use the full path here, or it gets confused + # with the ssh host:path syntax. + git push "$PWD/xxx:yyy.git" HEAD +' + test_done diff --git a/tmp-objdir.c b/tmp-objdir.c index 64435f23a4..b2d9280f10 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("ed, '"'); + quote_c_style(val, "ed, NULL, 1); + strbuf_addch("ed, '"'); + 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("ed); } static void env_replace(struct argv_array *env, const char *key, const char *val)