davidchambers
davidchambers

Reputation: 24806

Verify that Git commit only moves lines

Does Git provide any mechanism for proving that a commit moves but does not modify lines within a file? I frequently use -w to determine whether any changes were made within a section of code whose indentation changed. If a section of code is moved vertically rather than laterally, is there anything one can do to highlight changes within the moved section?

Upvotes: 2

Views: 275

Answers (4)

j6t
j6t

Reputation: 13387

There is

git diff --color-moved <from-commit> <to-commit>

It shows moved lines in a color different from the usual added and removed lines. That's not a proof, but just a visual indication. (Also, this sort of highlighting kicks in only when the moved region spans a minimum number of characters.)

See for example

git show --color-moved aabc5617cdfb29ccf98048b0d99cae2a811df51f

in the Git source code.

Upvotes: 0

Joshua Goldberg
Joshua Goldberg

Reputation: 5333

You could try...

git diff -U0 | grep -vE '^[+-]{3}' | grep '^[+-]' | sort -k1.2 | uniq -cs1

... and check that all lines of interest start with a count of 2 (or an even number if there are duplicates also moving). The greps are optional if you don't mind a little extra output to ignore.

(-U0 skips the "context" lines in the diff output; sort -k1.2 ignores the first character (+/-) when sorting, and uniq -cs1 counts the number of matches in each group of identical lines and again ignores the first character (+/-) when comparing if lines are the same.)

This also works for regular diffs (diff -u0, rather than git diff -U0)

Upvotes: 0

Keith Thompson
Keith Thompson

Reputation: 263307

I don't think Git provides any direct way of doing this, but if sorting the old and new versions of a file yield the same result, that's equivalent to the change consisting only of moving lines.

Of course that won't distinguish between swapping two blocks of lines and completely scrambling the file.

Highlighting such changes is another matter. This question, which I asked several years ago, might be relevant:

Is there a diff-like algorithm that handles moving block of lines?

Upvotes: 1

bk2204
bk2204

Reputation: 76519

No, Git doesn't provide a way of proving this. It shouldn't be too hard to parse the diff output and verify that the groups of deleted lines and added lines are the same groups. This would require some scripting, but it is doable. This project may be interesting.

If you're looking to verify this visually, you can use --color-moved, which will color moved blocks in a different color than additions or removals that aren't moved lines.

Upvotes: 1

Related Questions