As of Git 2.15, git show
now supports detection of moved lines with the --color-moved
option. It works for moves across files.
Is there a way to configure git that it apply --color-moved
option by default?
EDIT: Googling found this answer which works great: git config --global --add color. ui true .
The git config command is a convenience function that is used to set Git configuration values on a global or local project level. These configuration levels correspond to . gitconfig text files. Executing git config will modify a configuration text file.
The global git config is simply a text file, so it can be edited with whatever text editor you choose. Open, edit global git config, save and close, and the changes will take effect the next time you issue a git command. It's that easy.
Show global git config settings But at runtime, only the value set locally is used. If you would like to delete or edit a Git config value manually with a text editor, you can find the Git config file locations through the Git config list command's –show-origin switch.
The documentation of git diff
should be checked. Run next command to colorize moved code:
git config --global diff.colorMoved default
Note: with Git 2.19 (Q3 2018), the "git diff --color-moved
" feature has further been tweaked.
See commit 626c0b5, commit ca1f4ae (18 Jul 2018), and commit e2fe6ab, commit b309571, commit 51da15e, commit ee1df66, commit 3783aad, commit 74cfa7b, commit 21c770b, commit 25790be (16 Jul 2018) by Stefan Beller (stefanbeller
).
(Merged by Junio C Hamano -- gitster
-- in commit a81575a, 02 Aug 2018)
First, the new default option is blocks, not zebra
diff.c
: add a blocks mode for moved code detection
The new "
blocks
" mode provides a middle ground between plain and zebra.
It is as intuitive (few colors) as plain, but still has the requirement for a minimum of lines/characters to count a block as moved.
- With blocks, adjacent blocks cannot be told apart.
- With zebra, the change between the two colors indicates that a new block was detected.
So remember this when using the git config --global diff.colorMoved default
setting.
The default mode (see git diff
modes) will be blocks, no longer zebra.
Then a block comes with whitespace management:
diff.c
: add white space mode to move detection that allows indent changes
The option of
--color-moved
has proven to be useful as observed on the mailing list. However when refactoring sometimes the indentation changes, for example when partitioning a functions into smaller helper functions the code usually mostly moved around except for a decrease in indentation.To just review the moved code ignoring the change in indentation, a mode to ignore spaces in the move detection as implemented in a previous patch would be enough. However the whole move coloring as motivated in commit 2e2d5ac (diff.c: color moved lines differently, 2017-06-30, Git v2.15.0), brought up the notion of the reviewer being able to trust the move of a "block".
As there are languages such as python, which depend on proper relative indentation for the control flow of the program, ignoring any white space change in a block would not uphold the promises of 2e2d5ac that allows reviewers to pay less attention to the inside of a block, as inside the reviewer wants to assume the same program flow.
This new mode of white space ignorance will take this into account and will only allow the same white space changes per line in each block. This patch even allows only for the same change at the beginning of the lines.
As this is a white space mode, it is made exclusive to other white space modes in the move detection.
This patch brings some challenges, related to the detection of blocks.
We need a wide net to catch the possible moved lines, but then need to narrow down to check if the blocks are still intact. Consider this example (ignoring block sizes):- A - B - C + A + B + C
At the beginning of a block when checking if there is a counterpart for
A
, we have to ignore all space changes. However at the following lines we have to check if the indent change stayed the same.Checking if the indentation change did stay the same, is done by computing the indentation change by the difference in line length, and then assume the change is only in the beginning of the longer line, the common tail is the same. That is why the test contains lines like:
- <TAB> A ... + A <TAB> ...
As the first line starting a block is caught using a compare function that ignores white spaces unlike the rest of the block, where the white space delta is taken into account for the comparison, we also have to think about the following situation:
- A - B - A - B + A + B + A + B
When checking if the first
A
(both in the+
and-
lines) is a start of a block, we have to check all 'A
' and record all the white space deltas such that we can find the example above to be just one block that is indented.
And it is tweaked (again) in Git 2.21 (Q1 2019)
See commit 0cd51e9, commit 21536d0, commit 7a4252c, commit b0a2ba4, commit 2034b47, commit 10acc5f, commit b73bcba, commit 748aa1a, commit fbafb7c (23 Nov 2018) by Phillip Wood (phillipwood
).
(Merged by Junio C Hamano -- gitster
-- in commit 15b07cb, 29 Jan 2019)
Even if you have set this as default, you can turn it off temporarily with
--no-color-moved
Turn off move detection.
This can be used to override configuration settings. It is the same as--color-moved=no
.
And:
diff --color-moved-ws
: handle blank lines
When using
--color-moved-ws=allow-indentation-change
, allow lines with the same indentation change to be grouped across blank lines.
For now this only works if the blank lines have been moved as well, not for blocks that have just had their indentation changed.This completes the changes to the implementation of
--color-moved=allow-indentation-change
.
Running:git diff --color-moved=allow-indentation-change v2.18.0 v2.19.0
now takes 5.0s.
This is a saving of 41% from 8.5s for the optimized version of the previous implementation and 66% from the original which took 14.6s.
And with Git 2.35 (Q1 2022), "diff --color-moved
" is faster because it stops clearing potential moved blocks, amongst other optimizations.
See commit 72962e8, commit b4a5c5c, commit 25e6190, commit eec7f53, commit 0e488f1, commit ff046a0, commit 08fba10, commit 52d14e1, commit 76e32d6, commit eb89352, commit eb31545, commit 0990658, commit 7dfe427, commit bea084b, commit f73613a (09 Dec 2021) by Phillip Wood (phillipwood
).
(Merged by Junio C Hamano -- gitster
-- in commit 2b755b3, 05 Jan 2022)
diff --color-moved
: stop clearing potential moved blocksSigned-off-by: Phillip Wood
moved_block_clear()
was introduced in 74d156f ("diff --color-moved-ws: fix double free crash", 2018-10-04, Git v2.20.0-rc0 -- merge listed in batch #5) to free the memory that was allocated when initializing a potential moved block.
However since 21536d0 ("diff --color-moved-ws: modify allow-indentation-change", 2018-11-23, Git v2.21.0-rc0 -- merge listed in batch #4) initializing a potential moved block no longer allocates any memory.
Up until the last commit we were relying onmoved_block_clear()
to set thematch
pointer toNULL
when a block stopped matching, but since that commit we do not clear a moved block that does not match so it does not make sense to clear them elsewhere.
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