The current completion code doesn't deal properly with items
(tags, branches, etc.) that have ${} in them because they
get expanded by bash while using compgen.

This patch is a rewrite of Felipe Contreras's 25ae7cf, which
attempted to fix the problem by quoting the values we pass
to __gitcomp_nl. However, that patch ended up quoting the
whole list as a single item, which broke other completions.
Instead, we need to split the newline-delimited list into
elements and quote each one individually.

This is not a complete fix, as the completion result does
will still contain metacharacters, so it would need extra
quoting to actually be used on a command line. But it's
still a step in the right direction, because:

  1. The current code's expansion means that things that are
     broken expansions (e.g., "${foo:bar}") will actually
     cause the completion function to barf, breaking all
     completion (even if you weren't going to complete that
     item). This patch fixes that so you can at least
     complete "foo" when "${foo:bar}" exists.

  2. We don't know yet what the final fix will look like,
     but this is probably the first step towards it. It
     handles quoting on the input side of compgen; the next
     step will likely be handling the quoting on the output
     side of compgen to yield a usable string for the
     command line.

Signed-off-by: Jeff King <>
 contrib/completion/git-completion.bash | 14 +++++++++++++-
 t/                  |  2 +-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
index be800e0..b0416ea 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -225,6 +225,18 @@ fi
+# Quotes each element of an IFS-delimited list for shell reuse
+       local i
+       local delim
+       for i in $1; do
+               local quoted=${i//\'/\'\\\'\'}
+               printf "${delim:+$IFS}'%s'" "$quoted"
+               delim=t
+       done
 # Generates completion reply with compgen, appending a space to possible
 # completion words, if necessary.
 # It accepts 1 to 4 arguments:
@@ -261,7 +273,7 @@ __gitcomp_nl ()
 __gitcomp_nl ()
        local IFS=$'\n'
-       COMPREPLY=($(compgen -P "${2-}" -S "${4- }" -W "$1" -- "${3-$cur}"))
+       COMPREPLY=($(compgen -P "${2-}" -S "${4- }" -W "$(__git_quote "$1")" -- 
 __git_heads ()
diff --git a/t/ b/t/
index cbd0fb6..da67705 100755
--- a/t/
+++ b/t/
@@ -278,7 +278,7 @@ test_expect_success 'complete tree filename with spaces' '
-test_expect_failure 'complete tree filename with metacharacters' '
+test_expect_success 'complete tree filename with metacharacters' '
        echo content >"name with \${meta}" &&
        git add . &&
        git commit -m meta &&
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to
More majordomo info at

Reply via email to