Mercurial > public > mercurial-scm > hg-stable
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 |