mercurial/mdiff.py
author mason@suse.com
Fri, 11 Nov 2005 18:20:24 -0800
changeset 1535 7ae0ce7a3dc4
parent 1452 f1755621cb7d
child 1540 8ca9f5b17257
permissions -rw-r--r--
Add revlog.strip to truncate away revisions. This updates the revlog data structures for index and nodemap in place so the .d and .i files don't need to be reread after stripping away a revision.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
239
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
     1
# mdiff.py - diff and patch routines for mercurial
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
     2
#
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
     3
# Copyright 2005 Matt Mackall <mpm@selenic.com>
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
     4
#
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
     5
# This software may be used and distributed according to the terms
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
75840796e8e2 mdiff.py: kill #! line, add copyright notice
mpm@selenic.com
parents: 184
diff changeset
     7
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
     8
import difflib, struct, bdiff, util, mpatch
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     9
1015
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 582
diff changeset
    10
def unidiff(a, ad, b, bd, fn, r=None, text=False):
396
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
    11
35
9197c26a414b unidiff: punt on comparing empty files
mpm@selenic.com
parents: 0
diff changeset
    12
    if not a and not b: return ""
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
    13
    epoch = util.datestr((0, 0))
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    14
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
    15
    if not text and (util.binary(a) or util.binary(b)):
1015
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 582
diff changeset
    16
        l = ['Binary file %s has changed\n' % fn]
22571b8d35d3 Add automatic binary file detection to diff and export
mpm@selenic.com
parents: 582
diff changeset
    17
    elif a == None:
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    18
        b = b.splitlines(1)
1378
a0fcfbbf52bb make diff dates be epoch for add/remove
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1015
diff changeset
    19
        l1 = "--- %s\t%s\n" % ("/dev/null", epoch)
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    20
        l2 = "+++ %s\t%s\n" % ("b/" + fn, bd)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    21
        l3 = "@@ -0,0 +1,%d @@\n" % len(b)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    22
        l = [l1, l2, l3] + ["+" + e for e in b]
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    23
    elif b == None:
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    24
        a = a.splitlines(1)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    25
        l1 = "--- %s\t%s\n" % ("a/" + fn, ad)
1378
a0fcfbbf52bb make diff dates be epoch for add/remove
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 1015
diff changeset
    26
        l2 = "+++ %s\t%s\n" % ("/dev/null", epoch)
264
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    27
        l3 = "@@ -1,%d +0,0 @@\n" % len(a)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    28
        l = [l1, l2, l3] + ["-" + e for e in a]
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    29
    else:
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    30
        a = a.splitlines(1)
4c1d7072d5cd Attempt to make diff deal with null sources properly
mpm@selenic.com
parents: 249
diff changeset
    31
        b = b.splitlines(1)
272
467cea2bf2d8 diff: use tab to separate date from filename
mpm@selenic.com
parents: 264
diff changeset
    32
        l = list(difflib.unified_diff(a, b, "a/" + fn, "b/" + fn))
278
777e388c06d6 unidiff: handle empty diffs more gracefully
mpm@selenic.com
parents: 272
diff changeset
    33
        if not l: return ""
272
467cea2bf2d8 diff: use tab to separate date from filename
mpm@selenic.com
parents: 264
diff changeset
    34
        # difflib uses a space, rather than a tab
467cea2bf2d8 diff: use tab to separate date from filename
mpm@selenic.com
parents: 264
diff changeset
    35
        l[0] = l[0][:-2] + "\t" + ad + "\n"
467cea2bf2d8 diff: use tab to separate date from filename
mpm@selenic.com
parents: 264
diff changeset
    36
        l[1] = l[1][:-2] + "\t" + bd + "\n"
170
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
    37
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
    38
    for ln in xrange(len(l)):
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
    39
        if l[ln][-1] != '\n':
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
    40
            l[ln] += "\n\ No newline at end of file\n"
e6c621a825f2 hg diff: fix missing final newline bug
mpm@selenic.com
parents: 127
diff changeset
    41
396
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
    42
    if r:
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
    43
        l.insert(0, "diff %s %s\n" %
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
    44
                    (' '.join(["-r %s" % rev for rev in r]), fn))
8f8bb77d560e Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 361
diff changeset
    45
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    46
    return "".join(l)
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    47
120
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
    48
def patchtext(bin):
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
    49
    pos = 0
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
    50
    t = []
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
    51
    while pos < len(bin):
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
    52
        p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
    53
        pos += 12
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
    54
        t.append(bin[pos:pos + l])
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
    55
        pos += l
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
    56
    return "".join(t)
bae6f0328f63 Add a function to return the new text from a binary diff
mpm@selenic.com
parents: 75
diff changeset
    57
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
    58
def patch(a, bin):
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
    59
    return mpatch.patches(a, [bin])
432
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
    60
1379
8ee7ce877be2 Clean up mdiff imports
Matt Mackall <mpm@selenic.com>
parents: 1378
diff changeset
    61
patches = mpatch.patches
432
3b9e3d3d2810 Start using bdiff for generating deltas
mpm@selenic.com
parents: 396
diff changeset
    62
textdiff = bdiff.bdiff