mercurial/patch.py
changeset 10127 d8214e944b84
parent 10102 1720d70cd6d4
child 10128 ea7c392f2b08
equal deleted inserted replaced
10126:78b8acae2088 10127:d8214e944b84
   319         if islink:
   319         if islink:
   320             fp = cStringIO.StringIO()
   320             fp = cStringIO.StringIO()
   321         else:
   321         else:
   322             fp = self.opener(fname, 'w')
   322             fp = self.opener(fname, 'w')
   323         try:
   323         try:
   324             if self.eolmode == 'auto' and self.eol:
   324             if self.eolmode == 'auto':
   325                 eol = self.eol
   325                 eol = self.eol
   326             elif self.eolmode == 'crlf':
   326             elif self.eolmode == 'crlf':
   327                 eol = '\r\n'
   327                 eol = '\r\n'
   328             else:
   328             else:
   329                 eol = '\n'
   329                 eol = '\n'
   330 
   330 
   331             if self.eolmode != 'strict' and eol != '\n':
   331             if self.eolmode != 'strict' and eol and eol != '\n':
   332                 for l in lines:
   332                 for l in lines:
   333                     if l and l[-1] == '\n':
   333                     if l and l[-1] == '\n':
   334                         l = l[:-1] + eol
   334                         l = l[:-1] + eol
   335                     fp.write(l)
   335                     fp.write(l)
   336             else:
   336             else:
   430             else:
   430             else:
   431                 self.lines[:] = h.new()
   431                 self.lines[:] = h.new()
   432                 self.offset += len(h.new())
   432                 self.offset += len(h.new())
   433                 self.dirty = 1
   433                 self.dirty = 1
   434             return 0
   434             return 0
       
   435 
       
   436         horig = h
       
   437         if self.eolmode == 'auto' and self.eol:
       
   438             # If eolmode == 'auto' and target file exists and has line
       
   439             # endings we have to normalize input data before patching.
       
   440             # Otherwise, patchfile operates in 'strict' mode. If
       
   441             # eolmode is set to 'crlf' or 'lf', input hunk is already
       
   442             # normalized to avoid data copy.
       
   443             h = h.getnormalized()
   435 
   444 
   436         # fast case first, no offsets, no fuzz
   445         # fast case first, no offsets, no fuzz
   437         old = h.old()
   446         old = h.old()
   438         # patch starts counting at 1 unless we are adding the file
   447         # patch starts counting at 1 unless we are adding the file
   439         if h.starta == 0:
   448         if h.starta == 0:
   486                                     "(offset %d lines).\n")
   495                                     "(offset %d lines).\n")
   487                         f(msg % (h.number, l+1, fuzzstr, offset))
   496                         f(msg % (h.number, l+1, fuzzstr, offset))
   488                         return fuzzlen
   497                         return fuzzlen
   489         self.printfile(True)
   498         self.printfile(True)
   490         self.ui.warn(_("Hunk #%d FAILED at %d\n") % (h.number, orig_start))
   499         self.ui.warn(_("Hunk #%d FAILED at %d\n") % (h.number, orig_start))
   491         self.rej.append(h)
   500         self.rej.append(horig)
   492         return -1
   501         return -1
   493 
   502 
   494 class hunk(object):
   503 class hunk(object):
   495     def __init__(self, desc, num, lr, context, create=False, remove=False):
   504     def __init__(self, desc, num, lr, context, create=False, remove=False):
   496         self.number = num
   505         self.number = num
   498         self.hunk = [ desc ]
   507         self.hunk = [ desc ]
   499         self.a = []
   508         self.a = []
   500         self.b = []
   509         self.b = []
   501         self.starta = self.lena = None
   510         self.starta = self.lena = None
   502         self.startb = self.lenb = None
   511         self.startb = self.lenb = None
   503         if context:
   512         if lr is not None:
   504             self.read_context_hunk(lr)
   513             if context:
   505         else:
   514                 self.read_context_hunk(lr)
   506             self.read_unified_hunk(lr)
   515             else:
       
   516                 self.read_unified_hunk(lr)
   507         self.create = create
   517         self.create = create
   508         self.remove = remove and not create
   518         self.remove = remove and not create
       
   519 
       
   520     def getnormalized(self):
       
   521         """Return a copy with line endings normalized to LF."""
       
   522 
       
   523         def normalize(lines):
       
   524             nlines = []
       
   525             for line in lines:
       
   526                 if line.endswith('\r\n'):
       
   527                     line = line[:-2] + '\n'
       
   528                 nlines.append(line)
       
   529             return nlines
       
   530 
       
   531         # Dummy object, it is rebuilt manually
       
   532         nh = hunk(self.desc, self.number, None, None, False, False)
       
   533         nh.number = self.number
       
   534         nh.desc = self.desc
       
   535         nh.a = normalize(self.a)
       
   536         nh.b = normalize(self.b)
       
   537         nh.starta = self.starta
       
   538         nh.startb = self.startb
       
   539         nh.lena = self.lena
       
   540         nh.lenb = self.lenb
       
   541         nh.create = self.create
       
   542         nh.remove = self.remove
       
   543         return nh
   509 
   544 
   510     def read_unified_hunk(self, lr):
   545     def read_unified_hunk(self, lr):
   511         m = unidesc.match(self.desc)
   546         m = unidesc.match(self.desc)
   512         if not m:
   547         if not m:
   513             raise PatchError(_("bad hunk #%d") % self.number)
   548             raise PatchError(_("bad hunk #%d") % self.number)
   972     rejects = 0
  1007     rejects = 0
   973     err = 0
  1008     err = 0
   974     current_file = None
  1009     current_file = None
   975     gitpatches = None
  1010     gitpatches = None
   976     opener = util.opener(os.getcwd())
  1011     opener = util.opener(os.getcwd())
   977     textmode = eolmode != 'strict'
  1012     # In 'auto' mode, we must preserve original eols if target file
       
  1013     # eols are undefined. Otherwise, hunk data will be normalized
       
  1014     # later.
       
  1015     textmode = eolmode not in ('strict', 'auto')
   978 
  1016 
   979     def closefile():
  1017     def closefile():
   980         if not current_file:
  1018         if not current_file:
   981             return 0
  1019             return 0
   982         current_file.close()
  1020         current_file.close()