I want to show a filtered history of commits. I need only those commits that have less than 60 seconds between each other, in order to see who did a bad job committing so fast. How to do this?
views:
58answers:
2You'll have to parse the output of git-log yourself; there's no built-in way to do that. The tricky thing is dealing appropriately with merges. If you had a linear history, it'd be very fast - use the output of git log --pretty="$H $at"
directly (that's printing full hash and UNIX timestamp). Once you have merges, though, there's no way to always end up with every commit immediately followed by the one you want to compare it with.
The obvious approach is then to look up the parent time for each commit individually. Of course, it's pretty inefficient to make an extra call to git log for every commit instead of intelligently remembering them, but the code sure is shorter. Here's what I came up with as a bash one-liner:
git log --no-merges --pretty="%H %at" |
while read line; do
time=${line#* }
commit=${line% *}
parent_time=$(git log --no-walk --pretty=%at $commit^)
dt=$((time - parent_time))
if [ $dt -lt 60 -a $dt -gt -60 ]; then
# modify this log format to whatever you like
git log --no-walk --pretty="%H %an %s" $commit
fi
done
It's not that horribly slow, so if you don't want to do this that much, it's probably good enough. You also only have to check all the way to the beginning of the repository once; after that you can limit the initial git log with a --since
.
You'll notice that I limited the difference in time between +-60 seconds. It's quite possible for it to be negative if there was a rebase; you probably still want to notice if someone made two commits quickly then swapped them, though, so I included the negative values.
in order to see who did a bad job committing so fast
There are very valid reasons for making two separate commits in a very short interval.
Suppose that you have been working for two hours, you made two bug fixes, you changes to file A fix bug #a, and changes to file B fix bug #b.
git add A
git commit -m"fixed bug #a"
git add B
git commit -m"fixed bug #b"
the difference between these commits might be 10 seconds, but there's nothing wrong with them.
In fact, most people will agree that the wrong thing to do is to squash these commits together.
This is of course a simplified scenario, there are many ways to split your changes into multiple commits, such as using the interactive staging command git add -p