view mercurial/mdiff.py @ 222:87484f627422

make pull work for multiple heads -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 make pull work for multiple heads add repository.heads() teach remoterepository and hgweb about heads command teach getchangegroup about multiple heads break apart addchangegroup and merge (cleaning up merge saved for later) after this change, it is now possible to pull and get multiple heads, but not possible to merge the heads manifest hash: 86fe3ede296254698fdd4c97df02944993ef2cbb -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCn8SZywK+sNU5EO8RAkSvAJ9NOA4UZ3cFyyzymlYBZnV+PpGRcACeLL+R PFaSgJHGKvxsXpvPYiZA0O0= =L2Xr -----END PGP SIGNATURE-----
author mpm@selenic.com
date Thu, 02 Jun 2005 18:46:49 -0800
parents 697f05bfe976
children 75840796e8e2 afe895fcc0d0
line wrap: on
line source

#!/usr/bin/python
import difflib, struct, mmap
from mercurial.mpatch import *

def unidiff(a, ad, b, bd, fn):
    if not a and not b: return ""
    a = a.splitlines(1)
    b = b.splitlines(1)
    l = list(difflib.unified_diff(a, b, "a/" + fn, "b/" + fn, ad, bd))

    for ln in xrange(len(l)):
        if l[ln][-1] != '\n':
            l[ln] += "\n\ No newline at end of file\n"

    return "".join(l)

def textdiff(a, b):
    return diff(a.splitlines(1), b.splitlines(1))

def sortdiff(a, b):
    la = lb = 0
    lena = len(a)
    lenb = len(b)
    while 1:
        am, bm, = la, lb
        while lb < lenb and la < len and a[la] == b[lb] :
            la += 1
            lb += 1
        if la>am: yield (am, bm, la-am)
        while lb < lenb and b[lb] < a[la]: lb += 1
        if lb>=lenb: break
        while la < lena and b[lb] > a[la]: la += 1
        if la>=lena: break
    yield (lena, lenb, 0)

def diff(a, b, sorted=0):
    if not a:
        s = "".join(b)
        return s and (struct.pack(">lll", 0, 0, len(s)) + s)

    bin = []
    p = [0]
    for i in a: p.append(p[-1] + len(i))

    if sorted:
        d = sortdiff(a, b)
    else:
        d = difflib.SequenceMatcher(None, a, b).get_matching_blocks()
    la = 0
    lb = 0
    for am, bm, size in d:
        s = "".join(b[lb:bm])
        if am > la or s:
            bin.append(struct.pack(">lll", p[la], p[am], len(s)) + s)
        la = am + size
        lb = bm + size
    
    return "".join(bin)

def patchtext(bin):
    pos = 0
    t = []
    while pos < len(bin):
        p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
        pos += 12
        t.append(bin[pos:pos + l])
        pos += l
    return "".join(t)

def patch(a, bin):
    return patches(a, [bin])