Federico Poloni
Federico Poloni

Reputation: 668

`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?

Upvotes: 6

Views: 873

Answers (2)

CharlesB
CharlesB

Reputation: 90396

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

cmd = difftoolname \"$LOCAL\" \"$REMOTE\"

Upvotes: 5

Chris
Chris

Reputation: 137068

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.

Upvotes: 1

Related Questions