view contrib/hgdiff @ 5119:0751c25ea0c0

raise util.Abort again if specified revision is not an integer. This was changed to NoRepo in 462cc56d898f, because specifying non-integer revisions for e.g. the Mercurial backend caused Abort to be raised in the subversion importer. Now util.Abort is raised again, but the check is done after verifying if it really is a subversion repository.
author Thomas Arendsen Hein <thomas@intevation.de>
date Tue, 07 Aug 2007 12:24:25 +0200
parents ea7b982b6c08
children
line wrap: on
line source

#!/usr/bin/env python

import os, sys, struct, stat
import difflib
import re
from optparse import OptionParser
from mercurial.bdiff import bdiff, blocks
from mercurial.mdiff import bunidiff, diffopts

VERSION="0.3"
usage = "usage: %prog [options] file1 file2"
parser = OptionParser(usage=usage)

parser.add_option("-d", "--difflib", action="store_true", default=False)
parser.add_option('-x', '--count', default=1)
parser.add_option('-c', '--context', type="int", default=3)
parser.add_option('-p', '--show-c-function', action="store_true", default=False)
parser.add_option('-w', '--ignore-all-space', action="store_true",
                  default=False)

(options, args) = parser.parse_args()

if not args:
    parser.print_help()
    sys.exit(1)

# simple utility function to put all the
# files from a directory tree into a dict
def buildlist(names, top):
    tlen = len(top)
    for root, dirs, files in os.walk(top):
        l = root[tlen + 1:]
        for x in files:
            p = os.path.join(root, x)
            st = os.lstat(p)
            if stat.S_ISREG(st.st_mode):
                names[os.path.join(l, x)] = (st.st_dev, st.st_ino)

def diff_files(file1, file2):
    if file1 == None:
        b = file(file2).read().splitlines(1)
        l1 = "--- %s\n" % (file2)
        l2 = "+++ %s\n" % (file2)
        l3 = "@@ -0,0 +1,%d @@\n" % len(b)
        l = [l1, l2, l3] + ["+" + e for e in b]
    elif file2 == None:
        a = file(file1).read().splitlines(1)
        l1 = "--- %s\n" % (file1)
        l2 = "+++ %s\n" % (file1)
        l3 = "@@ -1,%d +0,0 @@\n" % len(a)
        l = [l1, l2, l3] + ["-" + e for e in a]
    else:
        t1 = file(file1).read()
        t2 = file(file2).read()
        l1 = t1.splitlines(1)
        l2 = t2.splitlines(1)
        if options.difflib:
            l = difflib.unified_diff(l1, l2, file1, file2)
        else:
            l = bunidiff(t1, t2, l1, l2, file1, file2,
                         diffopts(context=options.context,
                                  showfunc=options.show_c_function,
                                  ignorews=options.ignore_all_space))
    for x in l:
        if x[-1] != '\n':
            x += "\n\ No newline at end of file\n"
        print x,

file1 = args[0]
file2 = args[1]

if os.path.isfile(file1) and os.path.isfile(file2):
    diff_files(file1, file2)
elif os.path.isdir(file1):
    if not os.path.isdir(file2):
        sys.stderr.write("file types don't match\n")
        sys.exit(1)

    d1 = {}
    d2 = {}

    buildlist(d1, file1)
    buildlist(d2, file2)
    keys = d1.keys()
    keys.sort()
    for x in keys:
        if x not in d2:
            f2 = None
        else:
            f2 = os.path.join(file2, x)
            st1 = d1[x]
            st2 = d2[x]
            del d2[x]
            if st1[0] == st2[0] and st1[1] == st2[1]:
                sys.stderr.write("%s is a hard link\n" % x)
                continue
        x = os.path.join(file1, x)
        diff_files(x, f2)
    keys = d2.keys()
    keys.sort()
    for x in keys:
        f1 = None
        x = os.path.join(file2, x)
        diff_files(f1, x)