Show More
@@ -595,11 +595,11 b' def reposetup(ui, repo):' | |||
|
595 | 595 | wlock.release() |
|
596 | 596 | |
|
597 | 597 | # monkeypatches |
|
598 |
def kwpatchfile_init(orig, self, ui, fname, |
|
|
598 | def kwpatchfile_init(orig, self, ui, fname, backend, | |
|
599 | 599 | missing=False, eolmode=None): |
|
600 | 600 | '''Monkeypatch/wrap patch.patchfile.__init__ to avoid |
|
601 | 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 | 603 | # shrink keywords read from working dir |
|
604 | 604 | self.lines = kwt.shrinklines(self.fname, self.lines) |
|
605 | 605 |
@@ -381,48 +381,42 b' class linereader(object):' | |||
|
381 | 381 | break |
|
382 | 382 | yield l |
|
383 | 383 | |
|
384 | # @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1 | |
|
385 | unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@') | |
|
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 | |
|
384 | class abstractbackend(object): | |
|
385 | def __init__(self, ui): | |
|
395 | 386 | self.ui = ui |
|
396 | self.lines = [] | |
|
397 | self.exists = False | |
|
398 | self.missing = missing | |
|
399 | if not missing: | |
|
400 | try: | |
|
401 | self.lines = self.readlines(fname) | |
|
402 | self.exists = True | |
|
403 | except IOError: | |
|
404 | pass | |
|
405 | else: | |
|
406 | self.ui.warn(_("unable to find '%s' for patching\n") % self.fname) | |
|
387 | ||
|
388 | def readlines(self, fname): | |
|
389 | """Return target file lines, or its content as a single line | |
|
390 | for symlinks. | |
|
391 | """ | |
|
392 | raise NotImplementedError | |
|
393 | ||
|
394 | def writelines(self, fname, lines): | |
|
395 | """Write lines to target file.""" | |
|
396 | raise NotImplementedError | |
|
407 | 397 | |
|
408 | self.hash = {} | |
|
409 | self.dirty = False | |
|
410 | self.offset = 0 | |
|
411 | self.skew = 0 | |
|
412 | self.rej = [] | |
|
413 | self.fileprinted = False | |
|
414 | self.printfile(False) | |
|
415 | self.hunks = 0 | |
|
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 | """ | |
|
407 | pass | |
|
408 | ||
|
409 | class fsbackend(abstractbackend): | |
|
410 | def __init__(self, ui, opener): | |
|
411 | super(fsbackend, self).__init__(ui) | |
|
412 | self.opener = opener | |
|
416 | 413 | |
|
417 | 414 | def readlines(self, fname): |
|
418 | 415 | if os.path.islink(fname): |
|
419 | 416 | return [os.readlink(fname)] |
|
420 | 417 | fp = self.opener(fname, 'r') |
|
421 | 418 | try: |
|
422 | lr = linereader(fp, self.eolmode != 'strict') | |
|
423 | lines = list(lr) | |
|
424 | self.eol = lr.eol | |
|
425 | return lines | |
|
419 | return list(fp) | |
|
426 | 420 | finally: |
|
427 | 421 | fp.close() |
|
428 | 422 | |
@@ -442,20 +436,7 b' class patchfile(object):' | |||
|
442 | 436 | raise |
|
443 | 437 | fp = self.opener(fname, 'w') |
|
444 | 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 | fp.writelines(lines) | |
|
439 | fp.writelines(lines) | |
|
459 | 440 | if islink: |
|
460 | 441 | self.opener.symlink(fp.getvalue(), fname) |
|
461 | 442 | if st_mode is not None: |
@@ -466,6 +447,79 b' class patchfile(object):' | |||
|
466 | 447 | def unlink(self, fname): |
|
467 | 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 | 523 | def printfile(self, warn): |
|
470 | 524 | if self.fileprinted: |
|
471 | 525 | return |
@@ -503,18 +557,10 b' class patchfile(object):' | |||
|
503 | 557 | # creates rejects in the same form as the original patch. A file |
|
504 | 558 | # header is inserted so that you can run the reject through patch again |
|
505 | 559 | # without having to type the filename. |
|
506 | ||
|
507 | 560 | if not self.rej: |
|
508 | 561 | return |
|
509 | ||
|
510 | fname = self.fname + ".rej" | |
|
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() | |
|
562 | self.backend.writerej(self.fname, len(self.rej), self.hunks, | |
|
563 | self.makerejlines(self.fname)) | |
|
518 | 564 | |
|
519 | 565 | def apply(self, h): |
|
520 | 566 | if not h.complete(): |
@@ -535,7 +581,7 b' class patchfile(object):' | |||
|
535 | 581 | |
|
536 | 582 | if isinstance(h, binhunk): |
|
537 | 583 | if h.rmfile(): |
|
538 | self.unlink(self.fname) | |
|
584 | self.backend.unlink(self.fname) | |
|
539 | 585 | else: |
|
540 | 586 | self.lines[:] = h.new() |
|
541 | 587 | self.offset += len(h.new()) |
@@ -563,7 +609,7 b' class patchfile(object):' | |||
|
563 | 609 | # fast case code |
|
564 | 610 | if self.skew == 0 and diffhelpers.testhunk(old, self.lines, start) == 0: |
|
565 | 611 | if h.rmfile(): |
|
566 | self.unlink(self.fname) | |
|
612 | self.backend.unlink(self.fname) | |
|
567 | 613 | else: |
|
568 | 614 | self.lines[start : start + h.lena] = h.new() |
|
569 | 615 | self.offset += h.lenb - h.lena |
@@ -1112,7 +1158,7 b' def _applydiff(ui, fp, patcher, copyfn, ' | |||
|
1112 | 1158 | err = 0 |
|
1113 | 1159 | current_file = None |
|
1114 | 1160 | cwd = os.getcwd() |
|
1115 |
|
|
|
1161 | backend = fsbackend(ui, scmutil.opener(cwd)) | |
|
1116 | 1162 | |
|
1117 | 1163 | for state, values in iterhunks(fp): |
|
1118 | 1164 | if state == 'hunk': |
@@ -1130,7 +1176,7 b' def _applydiff(ui, fp, patcher, copyfn, ' | |||
|
1130 | 1176 | try: |
|
1131 | 1177 | current_file, missing = selectfile(afile, bfile, |
|
1132 | 1178 | first_hunk, strip) |
|
1133 |
current_file = patcher(ui, current_file, |
|
|
1179 | current_file = patcher(ui, current_file, backend, | |
|
1134 | 1180 | missing=missing, eolmode=eolmode) |
|
1135 | 1181 | except PatchError, inst: |
|
1136 | 1182 | ui.warn(str(inst) + '\n') |
General Comments 0
You need to be logged in to leave comments.
Login now