contrib/hgdiff
author Sébastien Pierre <sebastien@xprima.com>
Tue, 01 Aug 2006 09:51:36 -0400
changeset 2749 d13e4ffaa79d
parent 1644 e7e6504c4989
child 3398 0f308690bda8
permissions -rwxr-xr-x
[darcs2hg] Windows compatibilty patct Originally submitted by Daiju Kito 1. single quote didn't work in several cases 2. os.unlink tries to delete tmpfile when it's called. It won't wait like unix.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1636
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     1
#!/usr/bin/env python
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     2
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     3
import os, sys, struct, stat
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     4
import difflib
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     5
import re
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     6
from optparse import OptionParser
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     7
from mercurial.bdiff import bdiff, blocks
1644
e7e6504c4989 Remove duplicate bunidiff code from hgdiff, importing from mdiff.py instead
mason@suse.com
parents: 1636
diff changeset
     8
from mercurial.mdiff import bunidiff
1636
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
     9
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    10
VERSION="0.2"
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    11
usage = "usage: %prog [options] file1 file2"
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    12
parser = OptionParser(usage=usage)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    13
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    14
parser.add_option("-d", "--difflib", action="store_true", default=False)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    15
parser.add_option('-x', '--count', default=1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    16
parser.add_option('-c', '--context', type="int", default=3)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    17
parser.add_option('-p', '--show-c-function', action="store_true", default=False)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    18
parser.add_option('-w', '--ignore-all-space', action="store_true", 
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    19
                  default=False)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    20
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    21
(options, args) = parser.parse_args()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    22
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    23
if not args:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    24
    parser.print_help()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    25
    sys.exit(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    26
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    27
# simple utility function to put all the
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    28
# files from a directory tree into a dict
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    29
def buildlist(names, top):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    30
    tlen = len(top)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    31
    for root, dirs, files in os.walk(top):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    32
        l = root[tlen + 1:]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    33
        for x in files:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    34
            p = os.path.join(root, x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    35
            st = os.lstat(p)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    36
            if stat.S_ISREG(st.st_mode):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    37
                names[os.path.join(l, x)] = (st.st_dev, st.st_ino)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    38
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    39
def diff_files(file1, file2):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    40
    if file1 == None:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    41
        b = file(file2).read().splitlines(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    42
        l1 = "--- %s\n" % (file2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    43
        l2 = "+++ %s\n" % (file2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    44
        l3 = "@@ -0,0 +1,%d @@\n" % len(b)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    45
        l = [l1, l2, l3] + ["+" + e for e in b]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    46
    elif file2 == None:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    47
        a = file(file1).read().splitlines(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    48
        l1 = "--- %s\n" % (file1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    49
        l2 = "+++ %s\n" % (file1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    50
        l3 = "@@ -1,%d +0,0 @@\n" % len(a)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    51
        l = [l1, l2, l3] + ["-" + e for e in a]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    52
    else:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    53
        t1 = file(file1).read()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    54
        t2 = file(file2).read()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    55
        l1 = t1.splitlines(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    56
        l2 = t2.splitlines(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    57
        if options.difflib:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    58
            l = difflib.unified_diff(l1, l2, file1, file2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    59
        else:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    60
            l = bunidiff(t1, t2, l1, l2, file1, file2, context=options.context,
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    61
                     showfunc=options.show_c_function,
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    62
                     ignorews=options.ignore_all_space)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    63
    for x in l:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    64
        if x[-1] != '\n':
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    65
            x += "\n\ No newline at end of file\n"
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    66
        print x,
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    67
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    68
file1 = args[0]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    69
file2 = args[1]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    70
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    71
if os.path.isfile(file1) and os.path.isfile(file2):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    72
    diff_files(file1, file2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    73
elif os.path.isdir(file1):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    74
    if not os.path.isdir(file2):
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    75
        sys.stderr.write("file types don't match\n")
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    76
        sys.exit(1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    77
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    78
    d1 = {}
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    79
    d2 = {}
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    80
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    81
    buildlist(d1, file1)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    82
    buildlist(d2, file2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    83
    keys = d1.keys()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    84
    keys.sort()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    85
    for x in keys:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    86
        if x not in d2:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    87
            f2 = None
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    88
        else:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    89
            f2 = os.path.join(file2, x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    90
            st1 = d1[x]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    91
            st2 = d2[x]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    92
            del d2[x]
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    93
            if st1[0] == st2[0] and st1[1] == st2[1]:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    94
                sys.stderr.write("%s is a hard link\n" % x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    95
                continue
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    96
        x = os.path.join(file1, x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    97
        diff_files(x, f2)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    98
    keys = d2.keys()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
    99
    keys.sort()
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   100
    for x in keys:
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   101
        f1 = None
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   102
        x = os.path.join(file2, x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   103
        diff_files(f1, x)
7da32bb3d1d3 contrib: add Chris Mason's stand-alone diff tool
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
   104