gitgit-bash

How do I set a config value in Git which has a space in it?


In Git Bash in Windows 11 I try to set the user name via the command line. This fails as only the part before the first space is processed.

$ git config --global user.name "Your Name"    
$ git config user.name
Your

I tried different types of quoting and escaping:

$ git config --global user.name 'Your Name'   
$ git config user.name
Your
$ git config --global user.name 'Your\ Name'   
$ git config user.name
Your\
$ git config --global user.name Your\ Name  
$ git config user.name
Your

Command via -c also fails:

$ git -c user.name='John Doe' gui
git: 'Doe' is not a git command. See 'git --help'.

The most similar commands are
        clone
        log
        notes

$ git -c 'user.name=John Doe' gui
git: 'Doe' is not a git command. See 'git --help'.

The most similar commands are
        clone
        log
        notes

I updated Git to the latest version (2.49.0.windows.1) and also rebooted Windows. This did not help.

How do I set the username if it has spaces in it?

EDIT: It turns out I've set an alias to git on my system:

*go_to_folder() {
  cd "$1" || return 1
}*

git ()
{
    if [ $1 = "clonecd" ]; then
        output=$(git clone --progress ${@:2} 2>&1 | tee /dev/stderr);
        dir=$(echo "$output" | sed -n "s/Cloning into '\([^']*\)'\.\.\..*/\1/p;q");
        go_to_folder "$dir";
    else
        command git $@;
    fi
}

It is a custom command that changes directory to the repo that was just cloned. I think $@ is where the issue lies.


Solution

  • Answering with the new info from the comments: Your git is a shell function:

    git () {
         if [ $1 = "clonecd" ]; then
             output=$(git clone --progress ${@:2} 2>&1 | tee /dev/stderr);
             dir=$(echo "$output" | sed -n "s/Cloning into '\([^']*\)'\.\.\..*/\1/p;q");
             go_to_folder "$dir";
         else
             command git $@;
         fi
    }
    

    This shell function does not properly quote its shell variables. git $@ will perform word splitting after expansion, which you do not want here – this is going to break in almost every use case (e.g. git commit -m 'this is my message' will fail). It will also fail for the contrived case of git 'this will fail' foobar, since it does not quote $1 (but it unnecessarily quotes clonecd).

    git "$@" is what you want instead. "${@:2}" needs quoting as well. git clone should probably be command git clone, otherwise you are recursively calling the function again.

    Define your function as follows:

    git() {
         if [ "$1" = "clonecd" ]; then
             shift;
             output=$(command git clone --progress "$@" 2>&1 | tee /dev/stderr);
             dir=$(printf '%s\n' "$output" | sed -n "s/Cloning into '\([^']*\)'\.\.\..*/\1/p;q");
             go_to_folder "$dir";
         else
             command git "$@";
         fi
    }
    

    References:


    Old answer, below; unfortunately, you really do need a shell function, because cd from child processes cannot affect the parent shell.

    Now this whole function seems fishy (it tries to allow you to type `git clonecd url-to-repo`). You don't need shell functions or shell aliases to extend Git. Git has its own alias mechanism. For more complicated extensions, create a custom Git subcommand.

    Custom Git alias

    Run the following to define a git alias:

    git config --global alias.clonecd "$(cat <<'EOF'
    !f() {
             output=$(git clone --progress "$@" 2>&1 | tee /dev/stderr);
             dir=$(printf '%s\n' "$output" | sed -n "s/Cloning into '\([^']*\)'\.\.\..*/\1/p;q");
             cd "$dir";
    };f
    EOF
    )"
    

    then drop your shell function (e.g. unset git or unset -f git – but you likely need to remove it from your ~/.profile or ~/.bashrc file)

    Custom Git subcommand (preferred)

    Put the following file in your PATH (e.g. ~/bin) and name it git-clonecd:

    #!/bin/sh
    output=$(git clone --progress "$@" 2>&1 | tee /dev/stderr);
    dir=$(printf '%s\n' "$output" | sed -n "s/Cloning into '\([^']*\)'\.\.\..*/\1/p;q");
    cd "$dir";
    

    and make it executable (chmod +x ~/bin/git-clonecd). Then drop your existing shell function.

    You can then use git clonecd url-of-repo just as if it was a real git subcommand.

    PS. There's probably a better way to write this script. go_to_folder looks like a weird alias/function for cd?