git status doesn't escape paths of untracked files

Viewed 184

I noticed that when tracked paths contain spaces or special characters that need escaping, git status --short will properly escape them on output. However, for untracked paths, git status --short does not escape them, making it very difficult to quickly copy and paste them into a command. What gives? And is it possible to force git status --short to escape all paths, including the paths of untracked files?

> git --version                                                                                                                                                                                                                    
git version 2.27.0                                                                                                                                                                             
> git status --short                                                                                                                                                                                                 Mon Sep  7 22:27:36 2020
A  normal_filename
A  "this is also escaped ''"
A  "this is escaped"
?? i'm testing
?? spaced file path
2 Answers

Git does quote some paths, but not others. The criteria are specified in the core.quotePath configuration:

Commands that output paths (e.g. ls-files, diff), will quote "unusual" characters in the pathname by enclosing the pathname in double-quotes and escaping those characters with backslashes in the same way C escapes control characters (e.g. \t for TAB, \n for LF, \ for backslash) or bytes with values larger than 0x80 (e.g. octal \302\265 for "micro" in UTF-8).…Double-quotes, backslash and control characters are always escaped regardless of the setting of this variable. A simple space character is not considered "unusual".

So the intention is not to quote things to help you at the command line, but rather to provide the output in an unambiguous way. I've checked with the latest version of Git (and in the source code) and the same function is called for both tracked and untracked files, so the behavior is consistent, if not what you were looking for.

If you're looking for something to script, you definitely want git status --porcelain -z (or --porcelain=v2), which will provide a consistent format with NUL termination.

I filed a bug report. Within one hour, the helpful git maintainers quickly confirmed it was a bug and started patching it. See the bug report here. I'm expecting it to be fixed in git version > 2.28.

Related