comparison mercurial/patch.py @ 5652:e90e72c6b4c7

patch: write rej files for missing targets (issue 853)
author Patrick Mezard <pmezard@gmail.com>
date Mon, 17 Dec 2007 23:42:46 +0100
parents e11940d84606
children 1b35bc1c1968
comparison
equal deleted inserted replaced
5651:e11940d84606 5652:e90e72c6b4c7
300 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 300 # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
301 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@') 301 unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@')
302 contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)') 302 contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)')
303 303
304 class patchfile: 304 class patchfile:
305 def __init__(self, ui, fname): 305 def __init__(self, ui, fname, missing=False):
306 self.fname = fname 306 self.fname = fname
307 self.ui = ui 307 self.ui = ui
308 try: 308 self.lines = []
309 fp = file(fname, 'rb') 309 self.exists = False
310 self.lines = fp.readlines() 310 self.missing = missing
311 self.exists = True 311 if not missing:
312 except IOError: 312 try:
313 fp = file(fname, 'rb')
314 self.lines = fp.readlines()
315 self.exists = True
316 except IOError:
317 pass
318 else:
319 self.ui.warn(_("unable to find '%s' for patching\n") % self.fname)
320
321 if not self.exists:
313 dirname = os.path.dirname(fname) 322 dirname = os.path.dirname(fname)
314 if dirname and not os.path.isdir(dirname): 323 if dirname and not os.path.isdir(dirname):
315 dirs = dirname.split(os.path.sep) 324 dirs = dirname.split(os.path.sep)
316 d = "" 325 d = ""
317 for x in dirs: 326 for x in dirs:
318 d = os.path.join(d, x) 327 d = os.path.join(d, x)
319 if not os.path.isdir(d): 328 if not os.path.isdir(d):
320 os.mkdir(d) 329 os.mkdir(d)
321 self.lines = []
322 self.exists = False
323 330
324 self.hash = {} 331 self.hash = {}
325 self.dirty = 0 332 self.dirty = 0
326 self.offset = 0 333 self.offset = 0
327 self.rej = [] 334 self.rej = []
424 h.lenb)) 431 h.lenb))
425 432
426 self.hunks += 1 433 self.hunks += 1
427 if reverse: 434 if reverse:
428 h.reverse() 435 h.reverse()
436
437 if self.missing:
438 self.rej.append(h)
439 return -1
429 440
430 if self.exists and h.createfile(): 441 if self.exists and h.createfile():
431 self.ui.warn(_("file %s already exists\n") % self.fname) 442 self.ui.warn(_("file %s already exists\n") % self.fname)
432 self.rej.append(h) 443 self.rej.append(h)
433 return -1 444 return -1
803 else: 814 else:
804 goodb = not nullb and os.path.exists(bfile) 815 goodb = not nullb and os.path.exists(bfile)
805 createfunc = hunk.createfile 816 createfunc = hunk.createfile
806 if reverse: 817 if reverse:
807 createfunc = hunk.rmfile 818 createfunc = hunk.rmfile
808 if not goodb and not gooda and not createfunc(): 819 missing = not goodb and not gooda and not createfunc()
809 raise PatchError(_("unable to find %s or %s for patching") % 820 fname = None
810 (afile, bfile)) 821 if not missing:
811 if gooda and goodb: 822 if gooda and goodb:
812 fname = bfile 823 fname = (afile in bfile) and afile or bfile
813 if afile in bfile: 824 elif gooda:
814 fname = afile 825 fname = afile
815 elif gooda: 826
816 fname = afile 827 if not fname:
817 elif not nullb: 828 if not nullb:
818 fname = bfile 829 fname = (afile in bfile) and afile or bfile
819 if afile in bfile: 830 elif not nulla:
820 fname = afile 831 fname = afile
821 elif not nulla: 832 else:
822 fname = afile 833 raise PatchError(_("undefined source and destination files"))
823 return fname 834
835 return fname, missing
824 836
825 class linereader: 837 class linereader:
826 # simple class to allow pushing lines back into the input stream 838 # simple class to allow pushing lines back into the input stream
827 def __init__(self, fp): 839 def __init__(self, fp):
828 self.fp = fp 840 self.fp = fp
1007 afile, bfile, first_hunk = values 1019 afile, bfile, first_hunk = values
1008 try: 1020 try:
1009 if sourcefile: 1021 if sourcefile:
1010 current_file = patchfile(ui, sourcefile) 1022 current_file = patchfile(ui, sourcefile)
1011 else: 1023 else:
1012 current_file = selectfile(afile, bfile, first_hunk, 1024 current_file, missing = selectfile(afile, bfile, first_hunk,
1013 strip, reverse) 1025 strip, reverse)
1014 current_file = patchfile(ui, current_file) 1026 current_file = patchfile(ui, current_file, missing)
1015 except PatchError, err: 1027 except PatchError, err:
1016 ui.warn(str(err) + '\n') 1028 ui.warn(str(err) + '\n')
1017 current_file, current_hunk = None, None 1029 current_file, current_hunk = None, None
1018 rejects += 1 1030 rejects += 1
1019 continue 1031 continue