mercurial/patch.py
changeset 10282 08a0f04b56bd
parent 10264 d6512b3e9ac0
child 10384 832f35386067
equal deleted inserted replaced
10281:e7d3b509af8b 10282:08a0f04b56bd
    76 
    76 
    77         if subject:
    77         if subject:
    78             if subject.startswith('[PATCH'):
    78             if subject.startswith('[PATCH'):
    79                 pend = subject.find(']')
    79                 pend = subject.find(']')
    80                 if pend >= 0:
    80                 if pend >= 0:
    81                     subject = subject[pend+1:].lstrip()
    81                     subject = subject[pend + 1:].lstrip()
    82             subject = subject.replace('\n\t', ' ')
    82             subject = subject.replace('\n\t', ' ')
    83             ui.debug('Subject: %s\n' % subject)
    83             ui.debug('Subject: %s\n' % subject)
    84         if user:
    84         if user:
    85             ui.debug('From: %s\n' % user)
    85             ui.debug('From: %s\n' % user)
    86         diffs_seen = 0
    86         diffs_seen = 0
   470             search_start = len(self.lines)
   470             search_start = len(self.lines)
   471         else:
   471         else:
   472             search_start = orig_start + self.skew
   472             search_start = orig_start + self.skew
   473 
   473 
   474         for fuzzlen in xrange(3):
   474         for fuzzlen in xrange(3):
   475             for toponly in [ True, False ]:
   475             for toponly in [True, False]:
   476                 old = h.old(fuzzlen, toponly)
   476                 old = h.old(fuzzlen, toponly)
   477 
   477 
   478                 cand = self.findlines(old[0][1:], search_start)
   478                 cand = self.findlines(old[0][1:], search_start)
   479                 for l in cand:
   479                 for l in cand:
   480                     if diffhelpers.testhunk(old, self.lines, l) == 0:
   480                     if diffhelpers.testhunk(old, self.lines, l) == 0:
   495                             msg = _("Hunk #%d succeeded at %d %s"
   495                             msg = _("Hunk #%d succeeded at %d %s"
   496                                     "(offset %d line).\n")
   496                                     "(offset %d line).\n")
   497                         else:
   497                         else:
   498                             msg = _("Hunk #%d succeeded at %d %s"
   498                             msg = _("Hunk #%d succeeded at %d %s"
   499                                     "(offset %d lines).\n")
   499                                     "(offset %d lines).\n")
   500                         f(msg % (h.number, l+1, fuzzstr, offset))
   500                         f(msg % (h.number, l + 1, fuzzstr, offset))
   501                         return fuzzlen
   501                         return fuzzlen
   502         self.printfile(True)
   502         self.printfile(True)
   503         self.ui.warn(_("Hunk #%d FAILED at %d\n") % (h.number, orig_start))
   503         self.ui.warn(_("Hunk #%d FAILED at %d\n") % (h.number, orig_start))
   504         self.rej.append(horig)
   504         self.rej.append(horig)
   505         return -1
   505         return -1
   506 
   506 
   507 class hunk(object):
   507 class hunk(object):
   508     def __init__(self, desc, num, lr, context, create=False, remove=False):
   508     def __init__(self, desc, num, lr, context, create=False, remove=False):
   509         self.number = num
   509         self.number = num
   510         self.desc = desc
   510         self.desc = desc
   511         self.hunk = [ desc ]
   511         self.hunk = [desc]
   512         self.a = []
   512         self.a = []
   513         self.b = []
   513         self.b = []
   514         self.starta = self.lena = None
   514         self.starta = self.lena = None
   515         self.startb = self.lenb = None
   515         self.startb = self.lenb = None
   516         if lr is not None:
   516         if lr is not None:
   619         for x in xrange(self.lenb):
   619         for x in xrange(self.lenb):
   620             l = lr.readline()
   620             l = lr.readline()
   621             if l.startswith('\ '):
   621             if l.startswith('\ '):
   622                 s = self.b[-1][:-1]
   622                 s = self.b[-1][:-1]
   623                 self.b[-1] = s
   623                 self.b[-1] = s
   624                 self.hunk[hunki-1] = s
   624                 self.hunk[hunki - 1] = s
   625                 continue
   625                 continue
   626             if not l:
   626             if not l:
   627                 lr.push(l)
   627                 lr.push(l)
   628                 break
   628                 break
   629             s = l[2:]
   629             s = l[2:]
   648                 if h == u:
   648                 if h == u:
   649                     break
   649                     break
   650                 elif h.startswith('-'):
   650                 elif h.startswith('-'):
   651                     continue
   651                     continue
   652                 else:
   652                 else:
   653                     self.hunk.insert(hunki-1, u)
   653                     self.hunk.insert(hunki - 1, u)
   654                     break
   654                     break
   655 
   655 
   656         if not self.a:
   656         if not self.a:
   657             # this happens when lines were only added to the hunk
   657             # this happens when lines were only added to the hunk
   658             for x in self.hunk:
   658             for x in self.hunk:
   687         fuzz = min(fuzz, len(l)-1)
   687         fuzz = min(fuzz, len(l)-1)
   688         if fuzz:
   688         if fuzz:
   689             top = 0
   689             top = 0
   690             bot = 0
   690             bot = 0
   691             hlen = len(self.hunk)
   691             hlen = len(self.hunk)
   692             for x in xrange(hlen-1):
   692             for x in xrange(hlen - 1):
   693                 # the hunk starts with the @@ line, so use x+1
   693                 # the hunk starts with the @@ line, so use x+1
   694                 if self.hunk[x+1][0] == ' ':
   694                 if self.hunk[x + 1][0] == ' ':
   695                     top += 1
   695                     top += 1
   696                 else:
   696                 else:
   697                     break
   697                     break
   698             if not toponly:
   698             if not toponly:
   699                 for x in xrange(hlen-1):
   699                 for x in xrange(hlen - 1):
   700                     if self.hunk[hlen-bot-1][0] == ' ':
   700                     if self.hunk[hlen - bot - 1][0] == ' ':
   701                         bot += 1
   701                         bot += 1
   702                     else:
   702                     else:
   703                         break
   703                         break
   704 
   704 
   705             # top and bot now count context in the hunk
   705             # top and bot now count context in the hunk
  1023         elif state == 'file':
  1023         elif state == 'file':
  1024             rejects += closefile()
  1024             rejects += closefile()
  1025             afile, bfile, first_hunk = values
  1025             afile, bfile, first_hunk = values
  1026             try:
  1026             try:
  1027                 if sourcefile:
  1027                 if sourcefile:
  1028                     current_file = patchfile(ui, sourcefile, opener, eolmode=eolmode)
  1028                     current_file = patchfile(ui, sourcefile, opener,
       
  1029                                              eolmode=eolmode)
  1029                 else:
  1030                 else:
  1030                     current_file, missing = selectfile(afile, bfile, first_hunk,
  1031                     current_file, missing = selectfile(afile, bfile,
  1031                                             strip)
  1032                                                        first_hunk, strip)
  1032                     current_file = patchfile(ui, current_file, opener, missing, eolmode)
  1033                     current_file = patchfile(ui, current_file, opener,
       
  1034                                              missing, eolmode)
  1033             except PatchError, err:
  1035             except PatchError, err:
  1034                 ui.warn(str(err) + '\n')
  1036                 ui.warn(str(err) + '\n')
  1035                 current_file, current_hunk = None, None
  1037                 current_file, current_hunk = None, None
  1036                 rejects += 1
  1038                 rejects += 1
  1037                 continue
  1039                 continue
  1194                                  files)
  1196                                  files)
  1195         else:
  1197         else:
  1196             try:
  1198             try:
  1197                 return internalpatch(patchname, ui, strip, cwd, files, eolmode)
  1199                 return internalpatch(patchname, ui, strip, cwd, files, eolmode)
  1198             except NoHunks:
  1200             except NoHunks:
  1199                 patcher = util.find_exe('gpatch') or util.find_exe('patch') or 'patch'
  1201                 patcher = (util.find_exe('gpatch') or util.find_exe('patch')
       
  1202                            or 'patch')
  1200                 ui.debug('no valid hunks found; trying with %r instead\n' %
  1203                 ui.debug('no valid hunks found; trying with %r instead\n' %
  1201                          patcher)
  1204                          patcher)
  1202                 if util.needbinarypatch():
  1205                 if util.needbinarypatch():
  1203                     args.append('--binary')
  1206                     args.append('--binary')
  1204                 return externalpatch(patcher, args, patchname, ui, strip, cwd,
  1207                 return externalpatch(patcher, args, patchname, ui, strip, cwd,
  1230 
  1233 
  1231     def chunk(text, csize=52):
  1234     def chunk(text, csize=52):
  1232         l = len(text)
  1235         l = len(text)
  1233         i = 0
  1236         i = 0
  1234         while i < l:
  1237         while i < l:
  1235             yield text[i:i+csize]
  1238             yield text[i:i + csize]
  1236             i += csize
  1239             i += csize
  1237 
  1240 
  1238     tohash = gitindex(to)
  1241     tohash = gitindex(to)
  1239     tnhash = gitindex(tn)
  1242     tnhash = gitindex(tn)
  1240     if tohash == tnhash:
  1243     if tohash == tnhash:
  1458 
  1461 
  1459         for chunk in diff(repo, prev, node, opts=opts):
  1462         for chunk in diff(repo, prev, node, opts=opts):
  1460             fp.write(chunk)
  1463             fp.write(chunk)
  1461 
  1464 
  1462     for seqno, rev in enumerate(revs):
  1465     for seqno, rev in enumerate(revs):
  1463         single(rev, seqno+1, fp)
  1466         single(rev, seqno + 1, fp)
  1464 
  1467 
  1465 def diffstatdata(lines):
  1468 def diffstatdata(lines):
  1466     filename, adds, removes = None, 0, 0
  1469     filename, adds, removes = None, 0, 0
  1467     for line in lines:
  1470     for line in lines:
  1468         if line.startswith('diff'):
  1471         if line.startswith('diff'):
  1493     hasbinary = False
  1496     hasbinary = False
  1494     for filename, adds, removes, isbinary in stats:
  1497     for filename, adds, removes, isbinary in stats:
  1495         totaladds += adds
  1498         totaladds += adds
  1496         totalremoves += removes
  1499         totalremoves += removes
  1497         maxname = max(maxname, len(filename))
  1500         maxname = max(maxname, len(filename))
  1498         maxtotal = max(maxtotal, adds+removes)
  1501         maxtotal = max(maxtotal, adds + removes)
  1499         if isbinary:
  1502         if isbinary:
  1500             hasbinary = True
  1503             hasbinary = True
  1501 
  1504 
  1502     countwidth = len(str(maxtotal))
  1505     countwidth = len(str(maxtotal))
  1503     if hasbinary and countwidth < 3:
  1506     if hasbinary and countwidth < 3: