Git annotate all versions of a single file in one go

LIBPF development team has recently moved from subversion to the Git distributed version control system. The tool is very good and there is quite a lot to learn; today we are sharing a shell script we have written to report all changes to a file throughout the lifetime of the repository.

The git command annotate prints out the file, reporting for each line the commit which introduced or last modified the line. With git annotate each line is shown only once,  but we needed to query for all changes throughout all past commits.

Here is the script to achieve that:


# $1
# run git-annotate for all versions of $1 and eliminate duplicate lines

# delete temporary files (although they should not be there !)
rm $(basename $0).$$.tmp $(basename $0).$$.sh 2> /dev/null
# create a zero-sized temporary file for caching the git-annotate output
touch $(basename $0).$$.tmp
# generate the shell script to run annotate for all versions of S1 and cache the git-annotate output in the temporary file
git log $1 | grep commit | sed "s/commit \(.*\)/git --no-pager annotate  $1 \1 >> $(basename $0).$$.tmp/g" > $(basename $0).$$.sh
# make shell script executable
chmod 700 $(basename $0).$$.sh
# launch shell script
./$(basename $0).$$.sh
# eliminate duplicate lines
sort $(basename $0).$$.tmp | uniq | sort -k 3
# get rid of temporary files
rm $(basename $0).$$.tmp $(basename $0).$$.sh