2

I am trying to set up a Git alias which has to convert a backslash to a forward slash to pass it later to filter-branch command (the need arises since I use Posh and will pass DOS based file path as a parameter).

So I have this alias:

echo-test = "!f() { path=$(echo $1 | tr '\\' '/'); echo $path; }; f"

But I get this error:

tr: warning: an unescaped backslash at end of string is not portable

I tried writing tr '\\\\' '/' inside, thinking that Git simply escapes the \ and bash gets a single \, but I get the same error.

Any ideas?

Gabrielius
  • 1,045
  • 12
  • 18
  • 3
    Have you tried 8 backslashes `'\\\\\\\\'`? – kennytm Apr 14 '17 at 19:10
  • @kennytm, holy crap, I thought you were teasing me, but it worked! So what is happening under the hood? 3 escapes? – Gabrielius Apr 14 '17 at 19:21
  • Yeah so there are definitely 3 escapes (once in `tr`), not sure above the other two, probably once in the alias definition and once in bash. – kennytm Apr 14 '17 at 19:26
  • @kennytm, nice catch, thanks. You can submit an answer, and I will accept it. – Gabrielius Apr 14 '17 at 19:28
  • I need to dig out the reference first :). All the above are just guessing. – kennytm Apr 14 '17 at 19:31
  • 1
    Since it doesn't appear to have anything to do with Git, you'd be better off making this as a shell alias or program and avoid Git's weird escaping. Alternatively, write the function in another file and `source` it into the Git alias. – Schwern Apr 14 '17 at 19:34

2 Answers2

3

You need to write 8 backslashes here, because the string will be unescaped three times.

echo-test = "!f() { path=$(echo $1 | tr '\\\\\\\\' '/'); echo $path; }; f"
  1. The first doubling is due to tr as OP have already used.
  2. The second doubling is due to the format of .gitconfig

    Inside double quotes, double quote " and backslash \ characters must be escaped: use \" for " and \\ for \.

  3. The third doubling is due to executing the command using sh -c "…".

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
0

I know the question is about tr but this is an equivalent alternative.

If you could write the |tr ... command,
it is much more clear (less confuse) to use |sed -r 's"[\]"/"g'.

I hope I can always avoid using \\\\\\\\\\\... I will never get used to it.

Aquarius Power
  • 3,729
  • 5
  • 32
  • 67