An outline of the steps
- A diff program - one that understands line reordering
- Using the new diff program - set your git config
A diff program:
So it turns out that git will call your diff program with the following arguments:
> my_diff_tool <filename> <old_location> <old_hash> <old_mode> <new_location> <new_hash> <new_mode>
So here is the simplest possible diff tool that does something close to what you want. It reads the files and then prints out the lines that are new and the lines that are old using set comparisons.
#!/usr/bin/python
import sys
old = open(sys.argv[2]).read().splitlines()
new = open(sys.argv[5]).read().splitlines()
print "-"* 80
print "Filename: %s" % sys.argv[1]
# Simple set method
for line in set(old) - set(new):
print '- %s' % line
for line in set(new) - set(old):
print '+ %s' % line
if set(new) == set(old):
print "Text reordering only"
Here is an example of what this outputs vs what diff would output:
my_diff_tool
Filename: test.txt
- luctus pellentesque.
+ luctus pellentesque. Puric huma te.
Diff
diff --git a/test.txt b/test.txt
index 2ec8f4b..797e2ad 100644
--- a/test.txt
+++ b/test.txt
@@ -4,15 +4,15 @@ dolor quis feugiat. Nullam vel interdum leo, a placerat elit. Mauris quis
faucibus dui.
Nullam eu sapien quis ex convallis tincidunt. Mauris tristique mauris ac
-luctus pellentesque.
+luctus pellentesque. Puric huma te.
Duis at imperdiet lacus. Sed malesuada elit vitae arcu semper, at fringilla
purus rhoncus. Sed vestibulum pellentesque libero in interdum. Fusce elementum
ornare vulputate.
+Nam sed enim at nisi tincidunt accumsan eu nec nisl. Duis suscipit hendrerit
+fermentum. Sed mattis purus congue velit aliquet, non placerat lectus varius.
+
Donec placerat, purus ac aliquet ullamcorper, elit leo accumsan ante, sed
lacinia leo sem sed metus. Morbi lacinia porttitor ante, eget consequat
libero accumsan in. Nunc sit amet lectus magna.
-
-Nam sed enim at nisi tincidunt accumsan eu nec nisl. Duis suscipit hendrerit
-fermentum. Sed mattis purus congue velit aliquet, non placerat lectus varius.
Obviously, there is much to be improved. For instance, sets will ignore duplicate lines. Sets also reorder so it's harder to understand if there are lots of new lines.
These improvements are left as an exercise to the reader.
Using the new diff program
Setting your git config to use the new tool is easy. You can also modify your .gitconfig
as you showed above.
> git config diff.external /location/to/your/diff/tool/my_diff_tool
You'll want to make sure that your diff tool is executable or you will get an error (fatal: cannot exec '/location/to/your/diff/tool/my_diff_tool': Permission denied
) so:
> chmod +x /location/to/your/diff/tool/my_diff_tool