[ACCEPTED]-Can Git really track the movement of a single function from 1 file to another? If so, how?-git-log

Accepted answer
Score: 35

This functionality is provided through git blame -C <file>.

The 15 -C option drives git into trying to find matches 14 between addition or deletion of chunks of 13 text in the file being reviewed and the 12 files modified in the same changesets. Additional 11 -C -C, or -C -C -C extend the search.

Try for yourself 10 in a test repo with git blame -C and you'll see that 9 the block of code that you just moved is 8 originated in the original file where it 7 belonged to.

From the git help blame manual page:

The origin 6 of lines is automatically followed across 5 whole-file renames (currently there is no 4 option to turn the rename-following off). To 3 follow lines moved from one file to another, or 2 to follow lines that were copied and pasted 1 from another file, etc., see the -C and -M options.

Score: 21

As of Git 2.15, git diff now supports detection of moved lines with the 10 --color-moved option. It works for moves across files.

It 9 works, obviously, for colorized terminal 8 output. As far as I can tell, there is no 7 option to indicate moves in plain text patch 6 format, but that makes sense.

For default 5 behavior, try

git diff --color-moved

The command also takes options, which 4 currently are no, default, plain, zebra and dimmed_zebra (Use git help diff to get the 3 latest options and their descriptions). For 2 example:

git diff --color-moved=zebra

As to how it is done, you can glean 1 some understanding from this email exchange by the author of the functionality.

Score: 8

A bit of this functionality is in git gui blame (+ filename). It 13 shows an annotation of the lines of a file, each 12 indicating when it was created and when 11 last changed. For code movement across a 10 file, it shows the commit of the original 9 file as a creation, and the commit where 8 it was added to the current file as last change. Try 7 it.

What I really would want is to give git log as 6 some argument a line number range additionally 5 to a file path, and then it would show the 4 history of this code block. There is no 3 such option, if the documentation is right. Yes, from 2 Linus' statement I too would think such 1 a command should be readily available.

Score: 5

git doesn't actually track renames at all. A rename 16 is just a delete and add, that's all. Any 15 tools who show renames reconstruct them 14 from this history information.

As such, tracking 13 function renames is a simple matter of analyzing 12 the diffs of all files in each commit after 11 the fact. There's nothing particularly impossible 10 about it; the existing rename tracking already 9 handles 'fuzzy' renames, in which some changes 8 are done to the file as well as renaming 7 it; this requires looking at the contents 6 to the files. It would be a simple extension 5 to look for function renames as well.

I don't 4 know if the base git tools actually do this 3 however - they try to be language neutral, and 2 function identification is very much not 1 language neutral.

Score: 2

There's git diff that will show you that certain 12 lines disappeared from foo and reappeared in 11 bar. If there are no other changes in these 10 files in the same commit, the change will 9 be easy to spot.

An intellectual git client 8 would be able to show you how lines moved 7 from one file to another. A language-aware 6 IDE would be able to correspond this change 5 with a particular function.

A very similar 4 thing happens when a file gets renamed. It 3 just disappears under one name and reappears 2 under another, but any reasonable tool is 1 able to notice it and represent as a rename.

More Related questions