Show More
@@ -595,12 +595,10 b' def reposetup(ui, repo):' | |||
|
595 | 595 | wlock.release() |
|
596 | 596 | |
|
597 | 597 | # monkeypatches |
|
598 |
def kwpatchfile_init(orig, self, ui, |
|
|
599 | remove, eolmode=None, copysource=None): | |
|
598 | def kwpatchfile_init(orig, self, ui, gp, backend, store, eolmode=None): | |
|
600 | 599 | '''Monkeypatch/wrap patch.patchfile.__init__ to avoid |
|
601 | 600 | rejects or conflicts due to expanded keywords in working dir.''' |
|
602 |
orig(self, ui, |
|
|
603 | eolmode, copysource) | |
|
601 | orig(self, ui, gp, backend, store, eolmode) | |
|
604 | 602 | # shrink keywords read from working dir |
|
605 | 603 | self.lines = kwt.shrinklines(self.fname, self.lines) |
|
606 | 604 |
@@ -281,6 +281,14 b' class patchmeta(object):' | |||
|
281 | 281 | isexec = mode & 0100 |
|
282 | 282 | self.mode = (islink, isexec) |
|
283 | 283 | |
|
284 | def copy(self): | |
|
285 | other = patchmeta(self.path) | |
|
286 | other.oldpath = self.oldpath | |
|
287 | other.mode = self.mode | |
|
288 | other.op = self.op | |
|
289 | other.binary = self.binary | |
|
290 | return other | |
|
291 | ||
|
284 | 292 | def __repr__(self): |
|
285 | 293 | return "<patchmeta %s %r>" % (self.op, self.path) |
|
286 | 294 | |
@@ -509,9 +517,8 b" contextdesc = re.compile('(---|\\*\\*\\*) (" | |||
|
509 | 517 | eolmodes = ['strict', 'crlf', 'lf', 'auto'] |
|
510 | 518 | |
|
511 | 519 | class patchfile(object): |
|
512 |
def __init__(self, ui, |
|
|
513 | eolmode='strict', copysource=None): | |
|
514 | self.fname = fname | |
|
520 | def __init__(self, ui, gp, backend, store, eolmode='strict'): | |
|
521 | self.fname = gp.path | |
|
515 | 522 | self.eolmode = eolmode |
|
516 | 523 | self.eol = None |
|
517 | 524 | self.backend = backend |
@@ -519,17 +526,17 b' class patchfile(object):' | |||
|
519 | 526 | self.lines = [] |
|
520 | 527 | self.exists = False |
|
521 | 528 | self.missing = True |
|
522 | self.mode = mode | |
|
523 |
self.copysource = |
|
|
524 | self.create = create | |
|
525 |
self.remove = |
|
|
529 | self.mode = gp.mode | |
|
530 | self.copysource = gp.oldpath | |
|
531 | self.create = gp.op in ('ADD', 'COPY', 'RENAME') | |
|
532 | self.remove = gp.op == 'DELETE' | |
|
526 | 533 | try: |
|
527 | if copysource is None: | |
|
528 | data, mode = backend.getfile(fname) | |
|
534 | if self.copysource is None: | |
|
535 | data, mode = backend.getfile(self.fname) | |
|
529 | 536 | self.exists = True |
|
530 | 537 | else: |
|
531 | data, mode = store.getfile(copysource) | |
|
532 | self.exists = backend.exists(fname) | |
|
538 | data, mode = store.getfile(self.copysource) | |
|
539 | self.exists = backend.exists(self.fname) | |
|
533 | 540 | self.missing = False |
|
534 | 541 | if data: |
|
535 | 542 | self.lines = data.splitlines(True) |
@@ -549,7 +556,7 b' class patchfile(object):' | |||
|
549 | 556 | nlines.append(l) |
|
550 | 557 | self.lines = nlines |
|
551 | 558 | except IOError: |
|
552 | if create: | |
|
559 | if self.create: | |
|
553 | 560 | self.missing = False |
|
554 | 561 | if self.mode is None: |
|
555 | 562 | self.mode = (False, False) |
@@ -1016,14 +1023,7 b' def pathstrip(path, strip):' | |||
|
1016 | 1023 | count -= 1 |
|
1017 | 1024 | return path[:i].lstrip(), path[i:].rstrip() |
|
1018 | 1025 | |
|
1019 |
def |
|
|
1020 | if gp: | |
|
1021 | # Git patches do not play games. Excluding copies from the | |
|
1022 | # following heuristic avoids a lot of confusion | |
|
1023 | fname = pathstrip(gp.path, strip - 1)[1] | |
|
1024 | create = gp.op in ('ADD', 'COPY', 'RENAME') | |
|
1025 | remove = gp.op == 'DELETE' | |
|
1026 | return fname, create, remove | |
|
1026 | def makepatchmeta(backend, afile_orig, bfile_orig, hunk, strip): | |
|
1027 | 1027 | nulla = afile_orig == "/dev/null" |
|
1028 | 1028 | nullb = bfile_orig == "/dev/null" |
|
1029 | 1029 | create = nulla and hunk.starta == 0 and hunk.lena == 0 |
@@ -1065,7 +1065,12 b' def selectfile(backend, afile_orig, bfil' | |||
|
1065 | 1065 | else: |
|
1066 | 1066 | raise PatchError(_("undefined source and destination files")) |
|
1067 | 1067 | |
|
1068 | return fname, create, remove | |
|
1068 | gp = patchmeta(fname) | |
|
1069 | if create: | |
|
1070 | gp.op = 'ADD' | |
|
1071 | elif remove: | |
|
1072 | gp.op = 'DELETE' | |
|
1073 | return gp | |
|
1069 | 1074 | |
|
1070 | 1075 | def scangitpatch(lr, firstline): |
|
1071 | 1076 | """ |
@@ -1134,7 +1139,7 b' def iterhunks(fp):' | |||
|
1134 | 1139 | hunknum += 1 |
|
1135 | 1140 | if emitfile: |
|
1136 | 1141 | emitfile = False |
|
1137 | yield 'file', (afile, bfile, h, gp) | |
|
1142 | yield 'file', (afile, bfile, h, gp and gp.copy() or None) | |
|
1138 | 1143 | yield 'hunk', h |
|
1139 | 1144 | elif x.startswith('diff --git'): |
|
1140 | 1145 | m = gitre.match(x) |
@@ -1144,14 +1149,14 b' def iterhunks(fp):' | |||
|
1144 | 1149 | # scan whole input for git metadata |
|
1145 | 1150 | gitpatches = [('a/' + gp.path, 'b/' + gp.path, gp) for gp |
|
1146 | 1151 | in scangitpatch(lr, x)] |
|
1147 | yield 'git', [g[2] for g in gitpatches | |
|
1152 | yield 'git', [g[2].copy() for g in gitpatches | |
|
1148 | 1153 | if g[2].op in ('COPY', 'RENAME')] |
|
1149 | 1154 | gitpatches.reverse() |
|
1150 | 1155 | afile = 'a/' + m.group(1) |
|
1151 | 1156 | bfile = 'b/' + m.group(2) |
|
1152 | 1157 | while afile != gitpatches[-1][0] and bfile != gitpatches[-1][1]: |
|
1153 | 1158 | gp = gitpatches.pop()[2] |
|
1154 | yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp) | |
|
1159 | yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy()) | |
|
1155 | 1160 | gp = gitpatches[-1][2] |
|
1156 | 1161 | # copy/rename + modify should modify target, not source |
|
1157 | 1162 | if gp.op in ('COPY', 'DELETE', 'RENAME', 'ADD') or gp.mode: |
@@ -1191,7 +1196,7 b' def iterhunks(fp):' | |||
|
1191 | 1196 | |
|
1192 | 1197 | while gitpatches: |
|
1193 | 1198 | gp = gitpatches.pop()[2] |
|
1194 | yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp) | |
|
1199 | yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp.copy()) | |
|
1195 | 1200 | |
|
1196 | 1201 | def applydiff(ui, fp, backend, store, strip=1, eolmode='strict'): |
|
1197 | 1202 | """Reads a patch from fp and tries to apply it. |
@@ -1228,41 +1233,38 b' def _applydiff(ui, fp, patcher, backend,' | |||
|
1228 | 1233 | rejects += current_file.close() |
|
1229 | 1234 | current_file = None |
|
1230 | 1235 | afile, bfile, first_hunk, gp = values |
|
1231 | copysource = None | |
|
1232 | 1236 | if gp: |
|
1233 | 1237 | path = pstrip(gp.path) |
|
1238 | gp.path = pstrip(gp.path) | |
|
1234 | 1239 | if gp.oldpath: |
|
1235 |
|
|
|
1236 | if gp.op == 'RENAME': | |
|
1237 | backend.unlink(copysource) | |
|
1238 | if not first_hunk: | |
|
1239 | if gp.op == 'DELETE': | |
|
1240 | backend.unlink(path) | |
|
1241 | continue | |
|
1242 | data, mode = None, None | |
|
1243 | if gp.op in ('RENAME', 'COPY'): | |
|
1244 | data, mode = store.getfile(copysource) | |
|
1245 | if gp.mode: | |
|
1246 | mode = gp.mode | |
|
1247 | if gp.op == 'ADD': | |
|
1248 | # Added files without content have no hunk and | |
|
1249 | # must be created | |
|
1250 | data = '' | |
|
1251 | if data or mode: | |
|
1252 | if (gp.op in ('ADD', 'RENAME', 'COPY') | |
|
1253 | and backend.exists(path)): | |
|
1254 | raise PatchError(_("cannot create %s: destination " | |
|
1255 | "already exists") % path) | |
|
1256 | backend.setfile(path, data, mode, copysource) | |
|
1240 | gp.oldpath = pstrip(gp.oldpath) | |
|
1241 | else: | |
|
1242 | gp = makepatchmeta(backend, afile, bfile, first_hunk, strip) | |
|
1243 | if gp.op == 'RENAME': | |
|
1244 | backend.unlink(gp.oldpath) | |
|
1257 | 1245 | if not first_hunk: |
|
1246 | if gp.op == 'DELETE': | |
|
1247 | backend.unlink(gp.path) | |
|
1248 | continue | |
|
1249 | data, mode = None, None | |
|
1250 | if gp.op in ('RENAME', 'COPY'): | |
|
1251 | data, mode = store.getfile(gp.oldpath) | |
|
1252 | if gp.mode: | |
|
1253 | mode = gp.mode | |
|
1254 | if gp.op == 'ADD': | |
|
1255 | # Added files without content have no hunk and | |
|
1256 | # must be created | |
|
1257 | data = '' | |
|
1258 | if data or mode: | |
|
1259 | if (gp.op in ('ADD', 'RENAME', 'COPY') | |
|
1260 | and backend.exists(gp.path)): | |
|
1261 | raise PatchError(_("cannot create %s: destination " | |
|
1262 | "already exists") % gp.path) | |
|
1263 | backend.setfile(gp.path, data, mode, gp.oldpath) | |
|
1258 | 1264 | continue |
|
1259 | 1265 | try: |
|
1260 | mode = gp and gp.mode or None | |
|
1261 | current_file, create, remove = selectfile( | |
|
1262 | backend, afile, bfile, first_hunk, strip, gp) | |
|
1263 | current_file = patcher(ui, current_file, backend, store, mode, | |
|
1264 | create, remove, eolmode=eolmode, | |
|
1265 | copysource=copysource) | |
|
1266 | current_file = patcher(ui, gp, backend, store, | |
|
1267 | eolmode=eolmode) | |
|
1266 | 1268 | except PatchError, inst: |
|
1267 | 1269 | ui.warn(str(inst) + '\n') |
|
1268 | 1270 | current_file = None |
@@ -1395,14 +1397,14 b' def changedfiles(ui, repo, patchpath, st' | |||
|
1395 | 1397 | if state == 'file': |
|
1396 | 1398 | afile, bfile, first_hunk, gp = values |
|
1397 | 1399 | if gp: |
|
1398 |
|
|
|
1399 |
if gp.o |
|
|
1400 |
|
|
|
1401 |
|
|
|
1402 | continue | |
|
1403 | current_file, create, remove = selectfile( | |
|
1404 | backend, afile, bfile, first_hunk, strip, gp) | |
|
1405 |
changed.add( |
|
|
1400 | gp.path = pathstrip(gp.path, strip - 1)[1] | |
|
1401 | if gp.oldpath: | |
|
1402 | gp.oldpath = pathstrip(gp.oldpath, strip - 1)[1] | |
|
1403 | else: | |
|
1404 | gp = makepatchmeta(backend, afile, bfile, first_hunk, strip) | |
|
1405 | changed.add(gp.path) | |
|
1406 | if gp.op == 'RENAME': | |
|
1407 | changed.add(gp.oldpath) | |
|
1406 | 1408 | elif state not in ('hunk', 'git'): |
|
1407 | 1409 | raise util.Abort(_('unsupported parser state: %s') % state) |
|
1408 | 1410 | return changed |
General Comments 0
You need to be logged in to leave comments.
Login now