From ca1f4ae4dfade677647928d28728a0cad125981d Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 18 Jul 2018 12:31:55 -0700 Subject: 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), 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: - A ... + A ... 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. Signed-off-by: Stefan Beller Signed-off-by: Junio C Hamano --- t/t4015-diff-whitespace.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) (limited to 't/t4015-diff-whitespace.sh') diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 000c3a2b7d..41facf7abf 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -1814,4 +1814,92 @@ test_expect_success 'only move detection ignores white spaces' ' test_cmp expected actual ' +test_expect_success 'compare whitespace delta across moved blocks' ' + + git reset --hard && + q_to_tab <<-\EOF >text.txt && + QIndented + QText across + Qsome lines + QBut! <- this stands out + QAdjusting with + QQdifferent starting + Qwhite spaces + QAnother outlier + QQQIndented + QQQText across + QQQfive lines + QQQthat has similar lines + QQQto previous blocks, but with different indent + QQQYetQAnotherQoutlierQ + EOF + + git add text.txt && + git commit -m "add text.txt" && + + q_to_tab <<-\EOF >text.txt && + QQIndented + QQText across + QQsome lines + QQQBut! <- this stands out + Adjusting with + Qdifferent starting + white spaces + AnotherQoutlier + QQIndented + QQText across + QQfive lines + QQthat has similar lines + QQto previous blocks, but with different indent + QQYetQAnotherQoutlier + EOF + + git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && + + q_to_tab <<-\EOF >expected && + diff --git a/text.txt b/text.txt + --- a/text.txt + +++ b/text.txt + @@ -1,14 +1,14 @@ + -QIndented + -QText across + -Qsome lines + -QBut! <- this stands out + -QAdjusting with + -QQdifferent starting + -Qwhite spaces + -QAnother outlier + -QQQIndented + -QQQText across + -QQQfive lines + -QQQthat has similar lines + -QQQto previous blocks, but with different indent + -QQQYetQAnotherQoutlierQ + +QQIndented + +QQText across + +QQsome lines + +QQQBut! <- this stands out + +Adjusting with + +Qdifferent starting + +white spaces + +AnotherQoutlier + +QQIndented + +QQText across + +QQfive lines + +QQthat has similar lines + +QQto previous blocks, but with different indent + +QQYetQAnotherQoutlier + EOF + + test_cmp expected actual +' + +test_expect_success 'compare whitespace delta incompatible with other space options' ' + test_must_fail git diff \ + --color-moved-ws=allow-indentation-change,ignore-all-space \ + 2>err && + test_i18ngrep allow-indentation-change err +' + test_done -- cgit v1.2.3