1CVS annotate. 2 3The core GIT itself does not have a "cvs annotate" equivalent. 4It has something that you may want to use when you would use 5"cvs annotate". 6 7Let's step back a bit and think about the reason why you would 8want to do "cvs annotate a-file.c" to begin with. 9 10You would use "cvs annotate" on a file when you have trouble 11with a function (or even a single "if" statement in a function) 12that happens to be defined in the file, which does not do what 13you want it to do. And you would want to find out why it was 14written that way, because you are about to modify it to suit 15your needs, and at the same time you do not want to break its 16current callers. For that, you are trying to find out why the 17original author did things that way in the original context. 18 19Many times, it may be enough to see the commit log messages of 20commits that touch the file in question, possibly along with the 21patches themselves, like this: 22 23 $ git-whatchanged -p a-file.c 24 25This will show log messages and patches for each commit that 26touches a-file. 27 28This, however, may not be very useful when this file has many 29modifications that are not related to the piece of code you are 30interested in. You would see many log messages and patches that 31do not have anything to do with the piece of code you are 32interested in. As an example, assuming that you have this piece 33code that you are interested in in the HEAD version: 34 35 if (frotz) { 36 nitfol(); 37 } 38 39you would use git-rev-list and git-diff-tree like this: 40 41 $ git-rev-list HEAD | 42 git-diff-tree --stdin -v -p -S'if (frotz) { 43 nitfol(); 44 }' 45 46We have already talked about the "--stdin" form of git-diff-tree 47command that reads the list of commits and compares each commit 48with its parents. The git-whatchanged command internally runs 49the equivalent of the above command, and can be used like this: 50 51 $ git-whatchanged -p -S'if (frotz) { 52 nitfol(); 53 }' 54 55When the -S option is used, git-diff-tree command outputs 56differences between two commits only if one tree has the 57specified string in a file and the corresponding file in the 58other tree does not. The above example looks for a commit that 59has the "if" statement in it in a file, but its parent commit 60does not have it in the same shape in the corresponding file (or 61the other way around, where the parent has it and the commit 62does not), and the differences between them are shown, along 63with the commit message (thanks to the -v flag). It does not 64show anything for commits that do not touch this "if" statement. 65 66Also, in the original context, the same statement might have 67appeared at first in a different file and later the file was 68renamed to "a-file.c". CVS annotate would not help you to go 69back across such a rename, but GIT would still help you in such 70a situation. For that, you can give the -C flag to 71git-diff-tree, like this: 72 73 $ git-whatchanged -p -C -S'if (frotz) { 74 nitfol(); 75 }' 76 77When the -C flag is used, file renames and copies are followed. 78So if the "if" statement in question happens to be in "a-file.c" 79in the current HEAD commit, even if the file was originally 80called "o-file.c" and then renamed in an earlier commit, or if 81the file was created by copying an existing "o-file.c" in an 82earlier commit, you will not lose track. If the "if" statement 83did not change across such rename or copy, then the commit that 84does rename or copy would not show in the output, and if the 85"if" statement was modified while the file was still called 86"o-file.c", it would find the commit that changed the statement 87when it was in "o-file.c". 88 89[ BTW, the current versions of "git-diff-tree -C" is not eager 90 enough to find copies, and it will miss the fact that a-file.c 91 was created by copying o-file.c unless o-file.c was somehow 92 changed in the same commit.] 93 94You can use the --pickaxe-all flag in addition to the -S flag. 95This causes the differences from all the files contained in 96those two commits, not just the differences between the files 97that contain this changed "if" statement: 98 99 $ git-whatchanged -p -C -S'if (frotz) { 100 nitfol(); 101 }' --pickaxe-all 102 103[ Side note. This option is called "--pickaxe-all" because -S 104 option is internally called "pickaxe", a tool for software 105 archaeologists.]