git ls-files, how to escape spaces in files paths?

2.6k views Asked by At

A whole BUNCH of files got checked into our git repo before we introduced the .gitignore file. I'm currently trying to clean it up with:

git rm --cached `git ls-files -i --exclude-from=.gitignore`

The thing is MANY of the file paths have spaces in them.

For example:

......
Assets/Aoi Character Pack/Viewer/Resources/Aoi/Viewer BackGrounds/bg12.png.meta
Assets/Aoi Character Pack/Viewer/Resources/Aoi/Viewer BackGrounds/bg13.png.meta
Assets/Aoi Character Pack/Viewer/Resources/Aoi/Viewer BackGrounds/bg14.png.meta
Assets/Aoi Character Pack/Viewer/Resources/Aoi/Viewer BackGrounds/bg15.png.meta
Assets/Aoi Character Pack/Viewer/Resources/Aoi/Viewer BackGrounds/bg16.png.meta
Assets/Aoi Character Pack/Viewer/Resources/Aoi/Viewer BackGrounds/bg17.png.meta
Assets/Aoi Character Pack/Viewer/Resources/Aoi/Viewer BackGrounds/bg18.png.meta
.......

There's a WHOLE LOTTA SPACES in a whole lotta files that I need to get rid of.

I'm looking for an elegant way of either:

  • A: Escape the spaces with a "\", for example

    Assets/Aoi\ Character Pack/Viewer/Resources/Aoi/Viewer\ BackGrounds/bg18.png.meta

-or-

  • B: Have git ls-files pump out my list of files all snuggled neatly in between quotes.

    'Assets/Aoi Character Pack/Viewer/Resources/Aoi/Viewer BackGrounds/bg18.png.meta'

-EDIT-

So far I have tried git ls-files -i --exclude-from=.gitignore | sed 's/\ /\\\ /g'

While that happily outputs the file paths looking as I'd expect, with the spaces escaped..... When I try to execute

git rm --cached `git ls-files -i --exclude-from=.gitignore | sed 's/\ /\\\ /g'`

I get - error: unknown switch `\'

Where I expect something wonky is going on with the pipe.

2

There are 2 answers

1
AudioBubble On

The canonical way:

git ls-files -z | xargs -0 git rm

another way:

git ls-files | xargs -d '\n' git rm
1
Sean Novak On

Rachel Duncan's answer got me set in the right direction, and I've found a solution that works! I also borrowed tips from https://superuser.com/questions/401614/inserting-string-from-xargs-into-another-string

git ls-files -i --exclude-from=.gitignore | tr '\n' '\0' | xargs -0 -L1 -I '$' git rm --cached '$'

The above script compiles a list of all of your versioned git files that now fall within the .gitignore rules of exclusion, wraps quotes around each std line out (file path), then executes the git rm --cached command with the modified string.

I like this way because the terminal puts out a confirmation for each of the files it's removing from source control.

Cheers!