From 578625fa918922713a2ecce2b06611e4566778f5 Mon Sep 17 00:00:00 2001 From: SZEDER Gábor Date: Mon, 10 Aug 2015 11:46:06 +0200 Subject: config: add '--name-only' option to list only variable names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'git config' can only show values or name-value pairs, so if a shell script needs the names of set config variables it has to run 'git config --list' or '--get-regexp' and parse the output to separate config variable names from their values. However, such a parsing can't cope with multi-line values. Though 'git config' can produce null-terminated output for newline-safe parsing, that's of no use in such a case, becase shells can't cope with null characters. Even our own bash completion script suffers from these issues. Help the completion script, and shell scripts in general, by introducing the '--name-only' option to modify the output of '--list' and '--get-regexp' to list only the names of config variables, so they don't have to perform error-prone post processing to separate variable names from their values anymore. Signed-off-by: SZEDER Gábor Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 1 + 1 file changed, 1 insertion(+) (limited to 'contrib/completion/git-completion.bash') diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index bfc74e9d57..e9877e1fc8 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1887,6 +1887,7 @@ _git_config () --get --get-all --get-regexp --add --unset --unset-all --remove-section --rename-section + --name-only " return ;; -- cgit v1.3 From 905f2036d0975a828f764947384e732c2908d6eb Mon Sep 17 00:00:00 2001 From: SZEDER Gábor Date: Mon, 10 Aug 2015 11:46:07 +0200 Subject: completion: list variable names reliably with 'git config --name-only' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Recenty I created a multi-line branch description with '.' and '=' characters on one of the lines, and noticed that fragments of that line show up when completing set variable names for 'git config', e.g.: $ git config --get branch.b.description Branch description to fool the completion script with a second line containing dot . and equals = characters. $ git config --unset ... second line containing dot . and equals ... The completion script runs 'git config --list' and processes its output to strip the values and keep only the variable names. It does so by looking for lines containing '.' and '=' and outputting everything before the '=', which was fooled by my multi-line branch description. A similar issue exists with aliases and pretty format aliases with multi-line values, but in that case 'git config --get-regexp' is run and lines in its output are simply stripped after the first space, so subsequent lines don't even have to contain '.' and '=' to fool the completion script. Use the new '--name-only' option added in the previous commit to list config variable names reliably in both cases, without error-prone post processing. Signed-off-by: SZEDER Gábor Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'contrib/completion/git-completion.bash') diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index e9877e1fc8..0ec56942f6 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -744,9 +744,8 @@ __git_compute_porcelain_commands () __git_get_config_variables () { local section="$1" i IFS=$'\n' - for i in $(git --git-dir="$(__gitdir)" config --get-regexp "^$section\..*" 2>/dev/null); do - i="${i#$section.}" - echo "${i/ */}" + for i in $(git --git-dir="$(__gitdir)" config --name-only --get-regexp "^$section\..*" 2>/dev/null); do + echo "${i#$section.}" done } @@ -1774,15 +1773,7 @@ __git_config_get_set_variables () c=$((--c)) done - git --git-dir="$(__gitdir)" config $config_file --list 2>/dev/null | - while read -r line - do - case "$line" in - *.*=*) - echo "${line/=*/}" - ;; - esac - done + git --git-dir="$(__gitdir)" config $config_file --name-only --list 2>/dev/null } _git_config () -- cgit v1.3