I'm about to move a ton of files around in an existing project. Before I do this, I'd like to have a firm grasp on some techniques used to analyze code that has a multi-file history.
How can I use git to ask: "where did this line of code come from?" when the content has moved through multiple files in it's life time?
I know git doesn't track renames explicitly (for good reason) so it seems like I should be able to ask this, I'm just not sure how. If there are method's to visualize this that'd be great to know too.
I would recommend looking at three tools in the git toolbox. The first one is blame, which is very much the same as it is in cvs. It shows you which commit last touched each line in a file. If you want to look see what was there before, you can take the commit that touched the line and look at the previous commit.
git show <sha1_of_interesting_commit>^ -- file/path
You can repeat the blame to see what happened before that.
git blame <sha1_of_interesting_commit>^ -- file/path
The second tool is using --follow
to track files past renames.
git log --follow -- file/path
The third - and possibly the most useful tool - is the pickaxe option to log. This searches history for changes the removed, introduced or changed lines that include a given bit of text. This is especially useful for tracking things like function names. It may be new in a file in a particular commit, but did it come from a different source file? Was a call to it added at the same time, or before it moved?
git log -S"Interesting_Function"
If you are using a patch or stat option (e.g. -p
or --stat
) the output will be restricted to those files whose changes actually involved the search string unless you also use --pickaxe-all
where the whole change is displayed.
Combined with git grep
to show where all the current occurrences of a string are, pickaxe is an extremely useful history mining tool.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With