Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`git difftool` and witespaces in namefiles

It seems that when git difftool executes an external command, it does not quote the arguments correctly.

If .gitconfig contains the following lines:

[difftool.echo]
  cmd = echo "$LOCAL" "$REMOTE"

When I try to run difftool with a path containing spaces, such as

> git difftool -t echo HEAD^ HEAD spaces\ here/test.txt

I get the following result:

/tmp/RL2Nyi_test.txt spaces here/test.txt

As you can see, the filenames are not quoted (despite the explicit quotes in the command), hence the argument parsing fails. Removing the quotes in .gitconfig (EDIT: as well as escaping them as \") does not change the result.

(by replacing echo with any diff program, you get a more meaningful use case).

How can I get properly escaped filenames?

like image 793
Federico Poloni Avatar asked Jan 13 '14 08:01

Federico Poloni


2 Answers

You'll want to escape quotes around the command in .gitconfig:

cmd = difftoolname \"$LOCAL\" \"$REMOTE\"
like image 93
CharlesB Avatar answered Oct 24 '22 09:10

CharlesB


This should work:

[difftool.echo]
    cmd = 'echo "$LOCAL" "$REMOTE"'

Wrapping the entire command in single quotes causes Git to treat it as a single string, which gets assigned to the diftool.echo command unmodified. This is what we want.

This is very similar to one suggested in the comments above, which didn't work:

# This won't work
cmd = "echo '$LOCAL' '$REMOTE'"

The reason that this doesn't work has to do with the way quotes are handled in Bash (and most shells in general). This assigns echo '$LOCAL' '$REMOTE' as the command, but single quotes will not expand variables. This is why you were getting a literal output of $LOCAL $REMOTE.

The inner double-quotes in the working version at the top of this post will allow the arguments inside them to be expanded.

like image 34
Chris Avatar answered Oct 24 '22 09:10

Chris