TIL - Git --color-moved

Posted by Marcus Folkesson on Saturday, September 23, 2023

TIL - Git --color-moved

TIL, Today I Learned, is more of a "I just figured this out: here are my notes, you may find them useful too" rather than a full blog post

Did you know that Git is able to detect moved blocks and use different colors from the usual added/removed lines? Me neither until now.

The paremeter is --color-moved and has been around since v0.4.0, so there is no new feature.

This is from the git manual page [1] :

--color-moved[=<mode>]
Moved lines of code are colored differently. The <mode> defaults to no if the option is not given and to zebra if the option with no mode is given. The mode must be one of:

no
Moved lines are not highlighted.

default
Is a synonym for zebra. This may change to a more sensible mode in the future.

plain
Any line that is added in one location and was removed in another location will be colored with color.diff.newMoved. Similarly color.diff.oldMoved will be used for removed lines that are added somewhere else in the diff. This mode picks up any moved line, but it is not very useful in a review to determine if a block of code was moved without permutation.

blocks
Blocks of moved text of at least 20 alphanumeric characters are detected greedily. The detected blocks are painted using either the color.diff.{old,new}Moved color. Adjacent blocks cannot be told apart.

zebra
Blocks of moved text are detected as in blocks mode. The blocks are painted using either the color.diff.{old,new}Moved color or color.diff.{old,new}MovedAlternative. The change between the two colors indicates that a new block was detected.

dimmed-zebra
Similar to zebra, but additional dimming of uninteresting parts of moved code is performed. The bordering lines of two adjacent blocks are considered interesting, the rest is uninteresting. dimmed_zebra is a deprecated synonym.

The --color-moved argument can be used for any commands that generates a diff, such as git diff, git log -p, git stash show and more.

Example

This is an example of git diff where I have moved a function and made som small changes:

/media/git-block-diff.png

That the block is moved is clear, but it is not obvious what have changed in the block itself.

If we instead use --color-moved, we get a different style on the output:

/media/git-block-diff-color.png

The magenta and cyan is the moved block, and in addition, we get the red/green colors for removed/added lines.

Make it default

Set diff.colormoved to default (or any other mode) in your .gitconfig.

For example:

1$git config --global diff.colormoved default