visionmedia/git-extras — pull request #121 by trapd00r (2012-06-28 22:30:04+00:00)
Title: git-changelog: replace evil ls(1) pipe with find

Hi,

So tonight something bad happened.

Back story: half an hour before I decided to take a look at the progress of
this repo I pushed the following file to my utils/ repo: https://github.com/trapd00r/utils/blob/204cc67-11e785f51846b1134bbcc87778f1f8691/ls

It's called 'ls' and it has its place in $HOME/dev/utils - my $PATH for
illustration:

> echo $PATH| perl -pe 's/:/\n/g'
/home/scp1/dev/git-extras/bin
/home/scp1/dev/utils
/home/scp1/bin
/bin
/usr/bin
/usr/local/bin
/sbin
/usr/sbin
/usr/local/sbin
/usr/bin/site_perl
/usr/bin/vendor_perl
/usr/bin/core_perl

> /usr/bin/which -a ls
/home/scp1/dev/utils/ls
/bin/ls

Of course I'm well aware doing things like this can have interesting side
effects, but that doesn't make this a non-issue.

So I cloned the repo and checked out what's new.
I started with git-changelog.
I could only execute it once, and it didn't seem like it did anything the first
time... oh wait. The changelog was written to ./git-changelog.

sh ./git-changelog

made it fall through in the case switch, where it's executing

git-changelog --list >> $tmp # this is itself, in ./

sh ./git-changelog

mv /tmp/changelog ./git-changelog

I'm usually skimming through the source before I'm starting to play with things,
tonight I didn't and I was a bit shocked - good thing I didn't have any unstaged
modifications in *this* repo.

Here's how I believe it can be replicated:

git clone git://github.com/visionmedia/git-extras.git && cd git-extras/bin
mkdir -p $HOME/bin
wget https://raw.github.com/trapd00r/utils/204cc6711e785f51846b1134bbcc87778f1f8691/ls -O $HOME/bin
export PATH="$HOME/bin:$PATH"
hash -r || rehash
# ( now we can check how things are looking in $PATH )
type -a ls

sh ./git-changelog
cat !$

Now some notes:

It wasn't clear exactly what you were trying to grep for in the ls|grep pipe.
I haven't see a file named CHANGE, but I've seen CHANGES and CHANGELOG.
Adjust regex to taste...

However, I'd just as sad if I were to find that it would have silently truncated
a legitimate CHANGELOG in my repo.

Following the Principle of least astonishment, I'd suggest to completely skip
writing to a file and dumping the results on stdout instead (like most tools
do...). There's usually a way to specify a filename yourself
(-o flag is common), which I have nothing against, and if there isn't
it's even simpler redirecting the output to wherever it's wanted. Added
bonus is that you're not writing to a file before you've seen what the
results will look like on stdout.