Skip to content

Commit

Permalink
tmp-objdir: quote paths we add to alternates
Browse files Browse the repository at this point in the history
Commit 722ff7f (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>
  • Loading branch information
peff authored and gitster committed Dec 12, 2016
1 parent cf3c635 commit aae2ae4
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
19 changes: 19 additions & 0 deletions t/t5547-push-quarantine.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 17 additions & 1 deletion tmp-objdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "string-list.h"
#include "strbuf.h"
#include "argv-array.h"
#include "quote.h"

struct tmp_objdir {
struct strbuf path;
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit aae2ae4

Please sign in to comment.