mercurial/mdiff.py
changeset 1452 f1755621cb7d
parent 1379 8ee7ce877be2
child 1540 8ca9f5b17257
equal deleted inserted replaced
1451:54e4b187f69c 1452:f1755621cb7d
    43         l.insert(0, "diff %s %s\n" %
    43         l.insert(0, "diff %s %s\n" %
    44                     (' '.join(["-r %s" % rev for rev in r]), fn))
    44                     (' '.join(["-r %s" % rev for rev in r]), fn))
    45 
    45 
    46     return "".join(l)
    46     return "".join(l)
    47 
    47 
    48 def sortdiff(a, b):
       
    49     la = lb = 0
       
    50     lena = len(a)
       
    51     lenb = len(b)
       
    52 
       
    53     while 1:
       
    54         am, bm, = la, lb
       
    55 
       
    56         # walk over matching lines
       
    57         while lb < lenb and la < lena and a[la] == b[lb] :
       
    58             la += 1
       
    59             lb += 1
       
    60 
       
    61         if la > am:
       
    62             yield (am, bm, la - am) # return a match
       
    63 
       
    64         # skip mismatched lines from b
       
    65         while la < lena and lb < lenb and b[lb] < a[la]:
       
    66             lb += 1
       
    67 
       
    68         if lb >= lenb:
       
    69             break
       
    70 
       
    71         # skip mismatched lines from a
       
    72         while la < lena and lb < lenb and b[lb] > a[la]:
       
    73             la += 1
       
    74 
       
    75         if la >= lena:
       
    76             break
       
    77 
       
    78     yield (lena, lenb, 0)
       
    79 
       
    80 def diff(a, b, sorted=0):
       
    81     if not a:
       
    82         s = "".join(b)
       
    83         return s and (struct.pack(">lll", 0, 0, len(s)) + s)
       
    84 
       
    85     bin = []
       
    86     p = [0]
       
    87     for i in a: p.append(p[-1] + len(i))
       
    88 
       
    89     if sorted:
       
    90         try:
       
    91             d = sortdiff(a, b)
       
    92         except:
       
    93             raise
       
    94     else:
       
    95         d = difflib.SequenceMatcher(None, a, b).get_matching_blocks()
       
    96     la = 0
       
    97     lb = 0
       
    98     for am, bm, size in d:
       
    99         s = "".join(b[lb:bm])
       
   100         if am > la or s:
       
   101             bin.append(struct.pack(">lll", p[la], p[am], len(s)) + s)
       
   102         la = am + size
       
   103         lb = bm + size
       
   104 
       
   105     return "".join(bin)
       
   106 
       
   107 def patchtext(bin):
    48 def patchtext(bin):
   108     pos = 0
    49     pos = 0
   109     t = []
    50     t = []
   110     while pos < len(bin):
    51     while pos < len(bin):
   111         p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
    52         p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
   117 def patch(a, bin):
    58 def patch(a, bin):
   118     return mpatch.patches(a, [bin])
    59     return mpatch.patches(a, [bin])
   119 
    60 
   120 patches = mpatch.patches
    61 patches = mpatch.patches
   121 textdiff = bdiff.bdiff
    62 textdiff = bdiff.bdiff
   122 
       
   123