Show More
@@ -595,11 +595,11 b' def reposetup(ui, repo):' | |||||
595 | wlock.release() |
|
595 | wlock.release() | |
596 |
|
596 | |||
597 | # monkeypatches |
|
597 | # monkeypatches | |
598 |
def kwpatchfile_init(orig, self, ui, fname, |
|
598 | def kwpatchfile_init(orig, self, ui, fname, backend, | |
599 | missing=False, eolmode=None): |
|
599 | missing=False, eolmode=None): | |
600 | '''Monkeypatch/wrap patch.patchfile.__init__ to avoid |
|
600 | '''Monkeypatch/wrap patch.patchfile.__init__ to avoid | |
601 | rejects or conflicts due to expanded keywords in working dir.''' |
|
601 | rejects or conflicts due to expanded keywords in working dir.''' | |
602 |
orig(self, ui, fname, |
|
602 | orig(self, ui, fname, backend, missing, eolmode) | |
603 | # shrink keywords read from working dir |
|
603 | # shrink keywords read from working dir | |
604 | self.lines = kwt.shrinklines(self.fname, self.lines) |
|
604 | self.lines = kwt.shrinklines(self.fname, self.lines) | |
605 |
|
605 |
@@ -381,48 +381,42 b' class linereader(object):' | |||||
381 | break |
|
381 | break | |
382 | yield l |
|
382 | yield l | |
383 |
|
383 | |||
384 | # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 |
|
384 | class abstractbackend(object): | |
385 | unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@') |
|
385 | def __init__(self, ui): | |
386 | contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)') |
|
|||
387 | eolmodes = ['strict', 'crlf', 'lf', 'auto'] |
|
|||
388 |
|
||||
389 | class patchfile(object): |
|
|||
390 | def __init__(self, ui, fname, opener, missing=False, eolmode='strict'): |
|
|||
391 | self.fname = fname |
|
|||
392 | self.eolmode = eolmode |
|
|||
393 | self.eol = None |
|
|||
394 | self.opener = opener |
|
|||
395 | self.ui = ui |
|
386 | self.ui = ui | |
396 | self.lines = [] |
|
387 | ||
397 | self.exists = False |
|
388 | def readlines(self, fname): | |
398 | self.missing = missing |
|
389 | """Return target file lines, or its content as a single line | |
399 | if not missing: |
|
390 | for symlinks. | |
400 | try: |
|
391 | """ | |
401 | self.lines = self.readlines(fname) |
|
392 | raise NotImplementedError | |
402 | self.exists = True |
|
393 | ||
403 | except IOError: |
|
394 | def writelines(self, fname, lines): | |
|
395 | """Write lines to target file.""" | |||
|
396 | raise NotImplementedError | |||
|
397 | ||||
|
398 | def unlink(self, fname): | |||
|
399 | """Unlink target file.""" | |||
|
400 | raise NotImplementedError | |||
|
401 | ||||
|
402 | def writerej(self, fname, failed, total, lines): | |||
|
403 | """Write rejected lines for fname. total is the number of hunks | |||
|
404 | which failed to apply and total the total number of hunks for this | |||
|
405 | files. | |||
|
406 | """ | |||
404 |
|
|
407 | pass | |
405 | else: |
|
|||
406 | self.ui.warn(_("unable to find '%s' for patching\n") % self.fname) |
|
|||
407 |
|
408 | |||
408 | self.hash = {} |
|
409 | class fsbackend(abstractbackend): | |
409 | self.dirty = False |
|
410 | def __init__(self, ui, opener): | |
410 | self.offset = 0 |
|
411 | super(fsbackend, self).__init__(ui) | |
411 |
self. |
|
412 | self.opener = opener | |
412 | self.rej = [] |
|
|||
413 | self.fileprinted = False |
|
|||
414 | self.printfile(False) |
|
|||
415 | self.hunks = 0 |
|
|||
416 |
|
413 | |||
417 | def readlines(self, fname): |
|
414 | def readlines(self, fname): | |
418 | if os.path.islink(fname): |
|
415 | if os.path.islink(fname): | |
419 | return [os.readlink(fname)] |
|
416 | return [os.readlink(fname)] | |
420 | fp = self.opener(fname, 'r') |
|
417 | fp = self.opener(fname, 'r') | |
421 | try: |
|
418 | try: | |
422 | lr = linereader(fp, self.eolmode != 'strict') |
|
419 | return list(fp) | |
423 | lines = list(lr) |
|
|||
424 | self.eol = lr.eol |
|
|||
425 | return lines |
|
|||
426 | finally: |
|
420 | finally: | |
427 | fp.close() |
|
421 | fp.close() | |
428 |
|
422 | |||
@@ -442,19 +436,6 b' class patchfile(object):' | |||||
442 | raise |
|
436 | raise | |
443 | fp = self.opener(fname, 'w') |
|
437 | fp = self.opener(fname, 'w') | |
444 | try: |
|
438 | try: | |
445 | if self.eolmode == 'auto': |
|
|||
446 | eol = self.eol |
|
|||
447 | elif self.eolmode == 'crlf': |
|
|||
448 | eol = '\r\n' |
|
|||
449 | else: |
|
|||
450 | eol = '\n' |
|
|||
451 |
|
||||
452 | if self.eolmode != 'strict' and eol and eol != '\n': |
|
|||
453 | for l in lines: |
|
|||
454 | if l and l[-1] == '\n': |
|
|||
455 | l = l[:-1] + eol |
|
|||
456 | fp.write(l) |
|
|||
457 | else: |
|
|||
458 |
|
|
439 | fp.writelines(lines) | |
459 | if islink: |
|
440 | if islink: | |
460 | self.opener.symlink(fp.getvalue(), fname) |
|
441 | self.opener.symlink(fp.getvalue(), fname) | |
@@ -466,6 +447,79 b' class patchfile(object):' | |||||
466 | def unlink(self, fname): |
|
447 | def unlink(self, fname): | |
467 | os.unlink(fname) |
|
448 | os.unlink(fname) | |
468 |
|
449 | |||
|
450 | def writerej(self, fname, failed, total, lines): | |||
|
451 | fname = fname + ".rej" | |||
|
452 | self.ui.warn( | |||
|
453 | _("%d out of %d hunks FAILED -- saving rejects to file %s\n") % | |||
|
454 | (failed, total, fname)) | |||
|
455 | fp = self.opener(fname, 'w') | |||
|
456 | fp.writelines(lines) | |||
|
457 | fp.close() | |||
|
458 | ||||
|
459 | # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 | |||
|
460 | unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@') | |||
|
461 | contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)') | |||
|
462 | eolmodes = ['strict', 'crlf', 'lf', 'auto'] | |||
|
463 | ||||
|
464 | class patchfile(object): | |||
|
465 | def __init__(self, ui, fname, backend, missing=False, eolmode='strict'): | |||
|
466 | self.fname = fname | |||
|
467 | self.eolmode = eolmode | |||
|
468 | self.eol = None | |||
|
469 | self.backend = backend | |||
|
470 | self.ui = ui | |||
|
471 | self.lines = [] | |||
|
472 | self.exists = False | |||
|
473 | self.missing = missing | |||
|
474 | if not missing: | |||
|
475 | try: | |||
|
476 | self.lines = self.backend.readlines(fname) | |||
|
477 | if self.lines: | |||
|
478 | # Normalize line endings | |||
|
479 | if self.lines[0].endswith('\r\n'): | |||
|
480 | self.eol = '\r\n' | |||
|
481 | elif self.lines[0].endswith('\n'): | |||
|
482 | self.eol = '\n' | |||
|
483 | if eolmode != 'strict': | |||
|
484 | nlines = [] | |||
|
485 | for l in self.lines: | |||
|
486 | if l.endswith('\r\n'): | |||
|
487 | l = l[:-2] + '\n' | |||
|
488 | nlines.append(l) | |||
|
489 | self.lines = nlines | |||
|
490 | self.exists = True | |||
|
491 | except IOError: | |||
|
492 | pass | |||
|
493 | else: | |||
|
494 | self.ui.warn(_("unable to find '%s' for patching\n") % self.fname) | |||
|
495 | ||||
|
496 | self.hash = {} | |||
|
497 | self.dirty = 0 | |||
|
498 | self.offset = 0 | |||
|
499 | self.skew = 0 | |||
|
500 | self.rej = [] | |||
|
501 | self.fileprinted = False | |||
|
502 | self.printfile(False) | |||
|
503 | self.hunks = 0 | |||
|
504 | ||||
|
505 | def writelines(self, fname, lines): | |||
|
506 | if self.eolmode == 'auto': | |||
|
507 | eol = self.eol | |||
|
508 | elif self.eolmode == 'crlf': | |||
|
509 | eol = '\r\n' | |||
|
510 | else: | |||
|
511 | eol = '\n' | |||
|
512 | ||||
|
513 | if self.eolmode != 'strict' and eol and eol != '\n': | |||
|
514 | rawlines = [] | |||
|
515 | for l in lines: | |||
|
516 | if l and l[-1] == '\n': | |||
|
517 | l = l[:-1] + eol | |||
|
518 | rawlines.append(l) | |||
|
519 | lines = rawlines | |||
|
520 | ||||
|
521 | self.backend.writelines(fname, lines) | |||
|
522 | ||||
469 | def printfile(self, warn): |
|
523 | def printfile(self, warn): | |
470 | if self.fileprinted: |
|
524 | if self.fileprinted: | |
471 | return |
|
525 | return | |
@@ -503,18 +557,10 b' class patchfile(object):' | |||||
503 | # creates rejects in the same form as the original patch. A file |
|
557 | # creates rejects in the same form as the original patch. A file | |
504 | # header is inserted so that you can run the reject through patch again |
|
558 | # header is inserted so that you can run the reject through patch again | |
505 | # without having to type the filename. |
|
559 | # without having to type the filename. | |
506 |
|
||||
507 | if not self.rej: |
|
560 | if not self.rej: | |
508 | return |
|
561 | return | |
509 |
|
562 | self.backend.writerej(self.fname, len(self.rej), self.hunks, | ||
510 | fname = self.fname + ".rej" |
|
563 | self.makerejlines(self.fname)) | |
511 | self.ui.warn( |
|
|||
512 | _("%d out of %d hunks FAILED -- saving rejects to file %s\n") % |
|
|||
513 | (len(self.rej), self.hunks, fname)) |
|
|||
514 |
|
||||
515 | fp = self.opener(fname, 'w') |
|
|||
516 | fp.writelines(self.makerejlines(self.fname)) |
|
|||
517 | fp.close() |
|
|||
518 |
|
564 | |||
519 | def apply(self, h): |
|
565 | def apply(self, h): | |
520 | if not h.complete(): |
|
566 | if not h.complete(): | |
@@ -535,7 +581,7 b' class patchfile(object):' | |||||
535 |
|
581 | |||
536 | if isinstance(h, binhunk): |
|
582 | if isinstance(h, binhunk): | |
537 | if h.rmfile(): |
|
583 | if h.rmfile(): | |
538 | self.unlink(self.fname) |
|
584 | self.backend.unlink(self.fname) | |
539 | else: |
|
585 | else: | |
540 | self.lines[:] = h.new() |
|
586 | self.lines[:] = h.new() | |
541 | self.offset += len(h.new()) |
|
587 | self.offset += len(h.new()) | |
@@ -563,7 +609,7 b' class patchfile(object):' | |||||
563 | # fast case code |
|
609 | # fast case code | |
564 | if self.skew == 0 and diffhelpers.testhunk(old, self.lines, start) == 0: |
|
610 | if self.skew == 0 and diffhelpers.testhunk(old, self.lines, start) == 0: | |
565 | if h.rmfile(): |
|
611 | if h.rmfile(): | |
566 | self.unlink(self.fname) |
|
612 | self.backend.unlink(self.fname) | |
567 | else: |
|
613 | else: | |
568 | self.lines[start : start + h.lena] = h.new() |
|
614 | self.lines[start : start + h.lena] = h.new() | |
569 | self.offset += h.lenb - h.lena |
|
615 | self.offset += h.lenb - h.lena | |
@@ -1112,7 +1158,7 b' def _applydiff(ui, fp, patcher, copyfn, ' | |||||
1112 | err = 0 |
|
1158 | err = 0 | |
1113 | current_file = None |
|
1159 | current_file = None | |
1114 | cwd = os.getcwd() |
|
1160 | cwd = os.getcwd() | |
1115 |
|
|
1161 | backend = fsbackend(ui, scmutil.opener(cwd)) | |
1116 |
|
1162 | |||
1117 | for state, values in iterhunks(fp): |
|
1163 | for state, values in iterhunks(fp): | |
1118 | if state == 'hunk': |
|
1164 | if state == 'hunk': | |
@@ -1130,7 +1176,7 b' def _applydiff(ui, fp, patcher, copyfn, ' | |||||
1130 | try: |
|
1176 | try: | |
1131 | current_file, missing = selectfile(afile, bfile, |
|
1177 | current_file, missing = selectfile(afile, bfile, | |
1132 | first_hunk, strip) |
|
1178 | first_hunk, strip) | |
1133 |
current_file = patcher(ui, current_file, |
|
1179 | current_file = patcher(ui, current_file, backend, | |
1134 | missing=missing, eolmode=eolmode) |
|
1180 | missing=missing, eolmode=eolmode) | |
1135 | except PatchError, inst: |
|
1181 | except PatchError, inst: | |
1136 | ui.warn(str(inst) + '\n') |
|
1182 | ui.warn(str(inst) + '\n') |
General Comments 0
You need to be logged in to leave comments.
Login now