Mercurial > hg
view mercurial/cffi/bdiff.py @ 41930:cbdd2b56d4c3
copies: add test that makes both the merging csets dirty and run w/o error
This series of patches is to cover a case in fullcopytracing algorithms
where both the merging csets are not descendant of merge base.
In this algorithm we call a merging cset "dirty" if that cset is not the
descendant of merge base. That said, added test in this patch cover case
when both the merging csets are "dirty".
Actually this case of "both dirty" was encountered by Pulkit when he was
working on content-divergence where it is possible that both the csets
are not descendant of merging base.
For reference you can look into: https://phab.mercurial-scm.org/D3896
As this test run fine without any error and correctly traced the copies, I
added this test to make sure that it doesn't break even after I will modify
some code in next patches to fix an error. Next patch adds the tests where
this algorithm throws an error for the same case of "both dirty".
Differential Revision: https://phab.mercurial-scm.org/D5961
author | Sushil khanchi <sushilkhanchi97@gmail.com> |
---|---|
date | Thu, 14 Feb 2019 17:11:35 +0530 |
parents | 857876ebaed4 |
children | 2372284d9457 |
line wrap: on
line source
# bdiff.py - CFFI implementation of bdiff.c # # Copyright 2016 Maciej Fijalkowski <fijall@gmail.com> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import absolute_import import struct from ..pure.bdiff import * from . import _bdiff ffi = _bdiff.ffi lib = _bdiff.lib def blocks(sa, sb): a = ffi.new("struct bdiff_line**") b = ffi.new("struct bdiff_line**") ac = ffi.new("char[]", str(sa)) bc = ffi.new("char[]", str(sb)) l = ffi.new("struct bdiff_hunk*") try: an = lib.bdiff_splitlines(ac, len(sa), a) bn = lib.bdiff_splitlines(bc, len(sb), b) if not a[0] or not b[0]: raise MemoryError count = lib.bdiff_diff(a[0], an, b[0], bn, l) if count < 0: raise MemoryError rl = [None] * count h = l.next i = 0 while h: rl[i] = (h.a1, h.a2, h.b1, h.b2) h = h.next i += 1 finally: lib.free(a[0]) lib.free(b[0]) lib.bdiff_freehunks(l.next) return rl def bdiff(sa, sb): a = ffi.new("struct bdiff_line**") b = ffi.new("struct bdiff_line**") ac = ffi.new("char[]", str(sa)) bc = ffi.new("char[]", str(sb)) l = ffi.new("struct bdiff_hunk*") try: an = lib.bdiff_splitlines(ac, len(sa), a) bn = lib.bdiff_splitlines(bc, len(sb), b) if not a[0] or not b[0]: raise MemoryError count = lib.bdiff_diff(a[0], an, b[0], bn, l) if count < 0: raise MemoryError rl = [] h = l.next la = lb = 0 while h: if h.a1 != la or h.b1 != lb: lgt = (b[0] + h.b1).l - (b[0] + lb).l rl.append(struct.pack(">lll", (a[0] + la).l - a[0].l, (a[0] + h.a1).l - a[0].l, lgt)) rl.append(str(ffi.buffer((b[0] + lb).l, lgt))) la = h.a2 lb = h.b2 h = h.next finally: lib.free(a[0]) lib.free(b[0]) lib.bdiff_freehunks(l.next) return "".join(rl)