Dealing with whitespace in git diff-tree

I wanted to use a git post-commit hook to perform an action on every file that had been committed. A git command can be used to list files committed (from a question on stackoverflow):

git diff-tree -r --name-only --no-commit-id HEAD

However, this doesn’t escape spaces in the filename, which leads to problems when trying to use the command with a bash loop:

me@pc ~/tmp/testrepo $ git diff-tree -r --name-only --no-commit-id HEAD
a file
me@pc ~/tmp/testrepo $ for f in `git diff-tree -r --name-only --no-commit-id HEAD`; do ls $f; done
ls: cannot access a: No such file or directory
ls: cannot access file: No such file or directory

Using quotes with the ls command didn’t help:

me@pc ~/tmp/testrepo $ for f in `git diff-tree -r --name-only --no-commit-id HEAD`; do ls "$f"; done
ls: cannot access a: No such file or directory
ls: cannot access file: No such file or directory

I tried piping the output through sed, both to escape the spaces and surround each filename with quotes, but this didn’t help either:

me@pc ~/tmp/testrepo $ for f in `git diff-tree -r --name-only --no-commit-id HEAD | sed -e 's/ /\\\ /g'`; do ls $f; done
ls: cannot access a\: No such file or directory
ls: cannot access file: No such file or directory

me@pc ~/tmp/testrepo $ for f in `git diff-tree -r --name-only --no-commit-id HEAD | sed -e 's/.*/"&"/g'`; do ls $f; done
ls: cannot access "a: No such file or directory
ls: cannot access file": No such file or directory

It turns out you need quotes around both the git command and the ls command’s arguments:

me@pc ~/tmp/testrepo $ for f in "`git diff-tree -r --name-only --no-commit-id HEAD`"; do ls "$f"; done
a file

Last modified: 03/12/2011 Tags:

Related Pages

Other pages possibly of interest:

This website is a personal resource. Nothing here is guaranteed correct or complete, so use at your own risk and try not to delete the Internet. -Stephan

Site Info

Privacy policy

Go to top