11

I have a file that managed to get itself named:

# file's name (both lines)
companies.yml
companies.yml

# entry in my git working tree
"test/fixtures/companies.yml\342\200\250companies.yml"

For annoying reasons, the working tree on this particular project is full of other files that still need organizing. I would like to get the above entry out of there, but when I try git add "test/fixtures..." or git rm "test/fixtures..." it fails:
fatal: pathspec 'test/fixtures/companies.yml\342\200\250companies.yml' did not match any files

How can I deal with this?


Git status

On branch master
# Your branch is ahead of 'production/master' by 4 commits.
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)

modified:   [other files]
modified:   "test/fixtures/companies.yml\342\200\250companies.yml"
Community
  • 1
  • 1
sscirrus
  • 55,407
  • 41
  • 135
  • 228

3 Answers3

14

Git is printing the literal octets of the UTF-8 encoding of the filename because they are non-ASCII characters, and printing them as octal escapes. However, your shell does not understand them and is sending literal backslashes and digits to the git command when you cut and paste, so you're actually entering a different filename.

Either use tab-completion after typing test/fixtures/companies.yml (if your shell supports this) which will enter the actual characters or a wildcard in place of the escapes thus test/fixtures/companies.yml*companies.yml. The latter might, but probably won't, match other filenames.

Another possibility is to just rename the file to something more sane, of course, and then use git add -u / git add . to get git to notice the rename.

pndc
  • 3,710
  • 2
  • 23
  • 34
  • I didn't have tab-completion in my shell, so I copied the name from Finder directly into `git rm "text/fixtures/[paste]"`. This worked! +1 – sscirrus Nov 06 '12 at 12:42
  • @sscirrus a quite complete explanation of the issue, and a working solution. +1 from me as well. – VonC Nov 06 '12 at 12:47
  • I was removing a wordpress installation from my local repo (with uploads that had UTF8 characters in), and `git rm blog/*` worked wonders. Thanks! – h2ooooooo Feb 05 '13 at 11:39
12

Since you are in bash, you could use the printf command:

git rm --cached `printf "test/fixtures/companies.yml\342\200\250companies.yml"`

Octal escapes beginning with \0 may contain up to four digits.
(POSIX specifies up to three)

You can see a similar solution at "Git: how to specify file names containing octal notation on the command line".

That will remove the file from the index while still keeping it on the working tree.
You can then rename it if you want.


Update with Git 2.18 (Q2 2018, 6 years later), using a simple completion should work.

See commit 3dfe23b (16 Apr 2018) by SZEDER Gábor (szeder).

completion: support completing non-ASCII pathnames

Unless the user has 'core.quotePath=false' somewhere in the configuration, both 'git ls-files' and 'git diff-index' will by default quote any pathnames that contain bytes with values higher than 0x80, and escape those bytes as '\nnn' octal values.
This prevents completing paths when the current path component to be completed contains any non-ASCII, most notably UTF-8, characters, because none of the listed quoted paths will match the current word on the command line.

Set 'core.quotePath=false' for those 'git ls-files' and 'git diff-index' invocations, so they won't consider bytes higher than 0x80 as "unusual", and won't quote pathnames containing such characters.

Note that pathnames containing backslash, double quote, or control characters will still be quoted; a later patch in this series will deal with those.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I just realized these solutions are just moving the file into `changes to be committed`. It's not leaving my working tree alone... – sscirrus Nov 06 '12 at 13:16
  • @sscirrus I have edited the answer to make sure the working tree isn't affected. – VonC Nov 06 '12 at 13:57
1

I wanted to remove a folder in my git repository that had name containing Russian letters: "Файлы Mail.Ru Агента". First I deleted the folder manually and wanted to delete it in git with

git rm "..."

command in the next step. But git showed me a very acryptic name of the deleted folder: "\320\244\320\260\320\271\320\273\321\213 Mail.Ru \320\220\320\263\320\265\320\275\321\202\320\260". I restored the folder with

git checkout

and than just copied the name of the folder and executed command

git rm "Файлы Mail.Ru Агента/*"

It worked!

Andrushenko Alexander
  • 1,839
  • 19
  • 14