mercurial/mdiff.py
changeset 2580 a20a1bb0c396
parent 2470 fe1689273f84
child 2858 345bac2bc4ec
equal deleted inserted replaced
2579:0875cda033fd 2580:a20a1bb0c396
    18         else:
    18         else:
    19             lines[-1] = lines[-1][:-1]
    19             lines[-1] = lines[-1][:-1]
    20     return lines
    20     return lines
    21 
    21 
    22 def unidiff(a, ad, b, bd, fn, r=None, text=False,
    22 def unidiff(a, ad, b, bd, fn, r=None, text=False,
    23             showfunc=False, ignorews=False):
    23             showfunc=False, ignorews=False, ignorewsamount=False,
       
    24             ignoreblanklines=False):
    24 
    25 
    25     if not a and not b: return ""
    26     if not a and not b: return ""
    26     epoch = util.datestr((0, 0))
    27     epoch = util.datestr((0, 0))
    27 
    28 
    28     if not text and (util.binary(a) or util.binary(b)):
    29     if not text and (util.binary(a) or util.binary(b)):
    47         l = [l1, l2, l3] + ["-" + e for e in a]
    48         l = [l1, l2, l3] + ["-" + e for e in a]
    48     else:
    49     else:
    49         al = splitnewlines(a)
    50         al = splitnewlines(a)
    50         bl = splitnewlines(b)
    51         bl = splitnewlines(b)
    51         l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn,
    52         l = list(bunidiff(a, b, al, bl, "a/" + fn, "b/" + fn,
    52                           showfunc=showfunc, ignorews=ignorews))
    53                           showfunc=showfunc, ignorews=ignorews,
       
    54                           ignorewsamount=ignorewsamount,
       
    55                           ignoreblanklines=ignoreblanklines))
    53         if not l: return ""
    56         if not l: return ""
    54         # difflib uses a space, rather than a tab
    57         # difflib uses a space, rather than a tab
    55         l[0] = "%s\t%s\n" % (l[0][:-2], ad)
    58         l[0] = "%s\t%s\n" % (l[0][:-2], ad)
    56         l[1] = "%s\t%s\n" % (l[1][:-2], bd)
    59         l[1] = "%s\t%s\n" % (l[1][:-2], bd)
    57 
    60 
    70 # l1 and l2 are the text broken up into lines
    73 # l1 and l2 are the text broken up into lines
    71 # header1 and header2 are the filenames for the diff output
    74 # header1 and header2 are the filenames for the diff output
    72 # context is the number of context lines
    75 # context is the number of context lines
    73 # showfunc enables diff -p output
    76 # showfunc enables diff -p output
    74 # ignorews ignores all whitespace changes in the diff
    77 # ignorews ignores all whitespace changes in the diff
       
    78 # ignorewsamount ignores changes in the amount of whitespace
       
    79 # ignoreblanklines ignores changes whose lines are all blank
    75 def bunidiff(t1, t2, l1, l2, header1, header2, context=3, showfunc=False,
    80 def bunidiff(t1, t2, l1, l2, header1, header2, context=3, showfunc=False,
    76              ignorews=False):
    81              ignorews=False, ignorewsamount=False, ignoreblanklines=False):
    77     def contextend(l, len):
    82     def contextend(l, len):
    78         ret = l + context
    83         ret = l + context
    79         if ret > len:
    84         if ret > len:
    80             ret = len
    85             ret = len
    81         return ret
    86         return ret
   114 
   119 
   115     header = [ "--- %s\t\n" % header1, "+++ %s\t\n" % header2 ]
   120     header = [ "--- %s\t\n" % header1, "+++ %s\t\n" % header2 ]
   116 
   121 
   117     if showfunc:
   122     if showfunc:
   118         funcre = re.compile('\w')
   123         funcre = re.compile('\w')
       
   124     if ignorewsamount:
       
   125         wsamountre = re.compile('[ \t]+')
       
   126         wsappendedre = re.compile(' \n')
       
   127     if ignoreblanklines:
       
   128         wsblanklinesre = re.compile('\n')
   119     if ignorews:
   129     if ignorews:
   120         wsre = re.compile('[ \t]')
   130         wsre = re.compile('[ \t]')
   121 
   131 
   122     # bdiff.blocks gives us the matching sequences in the files.  The loop
   132     # bdiff.blocks gives us the matching sequences in the files.  The loop
   123     # below finds the spaces between those matching sequences and translates
   133     # below finds the spaces between those matching sequences and translates
   146 
   156 
   147         # bdiff sometimes gives huge matches past eof, this check eats them,
   157         # bdiff sometimes gives huge matches past eof, this check eats them,
   148         # and deals with the special first match case described above
   158         # and deals with the special first match case described above
   149         if not old and not new:
   159         if not old and not new:
   150             continue
   160             continue
       
   161 
       
   162         if ignoreblanklines:
       
   163             wsold = wsblanklinesre.sub('', "".join(old))
       
   164             wsnew = wsblanklinesre.sub('', "".join(new))
       
   165             if wsold == wsnew:
       
   166                 continue
       
   167 
       
   168         if ignorewsamount:
       
   169             wsold = wsamountre.sub(' ', "".join(old))
       
   170             wsold = wsappendedre.sub('\n', wsold)
       
   171             wsnew = wsamountre.sub(' ', "".join(new))
       
   172             wsnew = wsappendedre.sub('\n', wsnew)
       
   173             if wsold == wsnew:
       
   174                 continue
   151 
   175 
   152         if ignorews:
   176         if ignorews:
   153             wsold = wsre.sub('', "".join(old))
   177             wsold = wsre.sub('', "".join(old))
   154             wsnew = wsre.sub('', "".join(new))
   178             wsnew = wsre.sub('', "".join(new))
   155             if wsold == wsnew:
   179             if wsold == wsnew: