Hacker News new | past | comments | ask | show | jobs | submit login

That pipeline sure does look convenient. Let's see how it will handle a path with spaces.

  $ git status -s | grep '^ D' | awk '{ print $2 }' | xargs git checkout --
  xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option
  $ git status -s                                                          
   D "g h i"
I'd be lying if I said I was surprised, to be honest.



Yeah, it's annoying that unix filenames and shell quoting are both fundamentally broken and that (as above) people would generally (knowingly) write a a broken-for-spaces-in-filenames version by default because it's easier (and the author no doubt knew he'd not encounter spaces in his repo). Having said that, it's not very hard to fix, I'd probably write something like:

    git status -s | awk -vORS="\0" 'gsub(/^ D /,"")' | xargs -0 git checkout --
Which is about the same length. This will still break for malicious input (newlines in filename), but for the original use case that's not a concern.


But now you require gnu awk, it no longer works under posix (so for example busybox). Which sucks a bit.


It'll work with more than gawk (e.g. mawk as well) but yeah, it will not work with busybox awk. In the context of an interactive shell command I doubt many people care much about posix; indeed I struggle to recall any context in which I ever cared about posix compliance as such. Unless you have an personal or professional interest in fringe operating systems posix compliance is mostly of interest as an imperfect proxy for answering the question will it work on both Linux, macOS/iOS (and maybe busybox).

Anyway, I suspect the following is POSIX compliant:

    git status -s | awk 'gsub(/^ M /,"")' | tr \\0 \\n | ...


> Unless you have an personal or professional interest in fringe operating systems posix compliance

I mostly hit things like these with alpine containers and openwrt. OpenWRT I guess could be considered "fringe operating system", but alpine (at least for containers) seems reasonably mainstream?


Ugh, should of course have been

    git status -s | awk 'gsub(/^ D /,"")' | tr \\n \\0 | ...


You can fix it by replacing the awk with "cut -d ' ' -f 2-"

Haven't tested it, but you may also need to throw a "tr '\n' '\0'" in there and call xargs with "-0" to make it happy.

This will still break on files with a CR in the filename.

(CRs are allowed in unix filenames but, imho, they should not be.)


you also want to tell xargs not to run the command on an empty set, otherwise you'll just do 'git checkout --' which will just kill all your local changes, probably.


I think people who routinely write this kind of commands in an interactive shell are well aware of the shortcomings, they just deal with it when they need to and not before. One example is that people very rarely handle '\n' or spaces in filenames (e.g. using the -0 option from `xargs`). Whatever works is fine as long as one knows the risks.

For a one-off thing like the one mentioned in the article I'd say it's almost ok, although I'd put `git checkout --` in the category of risky commands if you don't have any backup.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: