Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/patch.py @ 24244:5918bb365c72
patch.pathtransform: add a prefix parameter
This is preparation for upcoming patches that will add support for applying a
patch within a subdirectory.
The prefix is applied after path components are stripped.
author | Siddharth Agarwal <sid0@fb.com> |
---|---|
date | Fri, 06 Mar 2015 22:17:24 -0800 |
parents | daee2039dd11 |
children | 740a17f885a1 |
comparison
equal
deleted
inserted
replaced
24243:daee2039dd11 | 24244:5918bb365c72 |
---|---|
1085 i = s.find(' ') | 1085 i = s.find(' ') |
1086 if i < 0: | 1086 if i < 0: |
1087 return s | 1087 return s |
1088 return s[:i] | 1088 return s[:i] |
1089 | 1089 |
1090 def pathtransform(path, strip): | 1090 def pathtransform(path, strip, prefix): |
1091 '''turn a path from a patch into a path suitable for the repository | 1091 '''turn a path from a patch into a path suitable for the repository |
1092 | 1092 |
1093 prefix, if not empty, is expected to be normalized with a / at the end. | |
1094 | |
1093 Returns (stripped components, path in repository). | 1095 Returns (stripped components, path in repository). |
1094 | 1096 |
1095 >>> pathtransform('a/b/c', 0) | 1097 >>> pathtransform('a/b/c', 0, '') |
1096 ('', 'a/b/c') | 1098 ('', 'a/b/c') |
1097 >>> pathtransform(' a/b/c ', 0) | 1099 >>> pathtransform(' a/b/c ', 0, '') |
1098 ('', ' a/b/c') | 1100 ('', ' a/b/c') |
1099 >>> pathtransform(' a/b/c ', 2) | 1101 >>> pathtransform(' a/b/c ', 2, '') |
1100 ('a/b/', 'c') | 1102 ('a/b/', 'c') |
1101 >>> pathtransform(' a//b/c ', 2) | 1103 >>> pathtransform(' a//b/c ', 2, 'd/e/') |
1102 ('a//b/', 'c') | 1104 ('a//b/', 'd/e/c') |
1103 >>> pathtransform('a/b/c', 3) | 1105 >>> pathtransform('a/b/c', 3, '') |
1104 Traceback (most recent call last): | 1106 Traceback (most recent call last): |
1105 PatchError: unable to strip away 1 of 3 dirs from a/b/c | 1107 PatchError: unable to strip away 1 of 3 dirs from a/b/c |
1106 ''' | 1108 ''' |
1107 pathlen = len(path) | 1109 pathlen = len(path) |
1108 i = 0 | 1110 i = 0 |
1117 i += 1 | 1119 i += 1 |
1118 # consume '//' in the path | 1120 # consume '//' in the path |
1119 while i < pathlen - 1 and path[i] == '/': | 1121 while i < pathlen - 1 and path[i] == '/': |
1120 i += 1 | 1122 i += 1 |
1121 count -= 1 | 1123 count -= 1 |
1122 return path[:i].lstrip(), path[i:].rstrip() | 1124 return path[:i].lstrip(), prefix + path[i:].rstrip() |
1123 | 1125 |
1124 def makepatchmeta(backend, afile_orig, bfile_orig, hunk, strip): | 1126 def makepatchmeta(backend, afile_orig, bfile_orig, hunk, strip): |
1125 nulla = afile_orig == "/dev/null" | 1127 nulla = afile_orig == "/dev/null" |
1126 nullb = bfile_orig == "/dev/null" | 1128 nullb = bfile_orig == "/dev/null" |
1127 create = nulla and hunk.starta == 0 and hunk.lena == 0 | 1129 create = nulla and hunk.starta == 0 and hunk.lena == 0 |
1128 remove = nullb and hunk.startb == 0 and hunk.lenb == 0 | 1130 remove = nullb and hunk.startb == 0 and hunk.lenb == 0 |
1129 abase, afile = pathtransform(afile_orig, strip) | 1131 abase, afile = pathtransform(afile_orig, strip, '') |
1130 gooda = not nulla and backend.exists(afile) | 1132 gooda = not nulla and backend.exists(afile) |
1131 bbase, bfile = pathtransform(bfile_orig, strip) | 1133 bbase, bfile = pathtransform(bfile_orig, strip, '') |
1132 if afile == bfile: | 1134 if afile == bfile: |
1133 goodb = gooda | 1135 goodb = gooda |
1134 else: | 1136 else: |
1135 goodb = not nullb and backend.exists(bfile) | 1137 goodb = not nullb and backend.exists(bfile) |
1136 missing = not goodb and not gooda and not create | 1138 missing = not goodb and not gooda and not create |
1366 | 1368 |
1367 def _applydiff(ui, fp, patcher, backend, store, strip=1, | 1369 def _applydiff(ui, fp, patcher, backend, store, strip=1, |
1368 eolmode='strict'): | 1370 eolmode='strict'): |
1369 | 1371 |
1370 def pstrip(p): | 1372 def pstrip(p): |
1371 return pathtransform(p, strip - 1)[1] | 1373 return pathtransform(p, strip - 1, '')[1] |
1372 | 1374 |
1373 rejects = 0 | 1375 rejects = 0 |
1374 err = 0 | 1376 err = 0 |
1375 current_file = None | 1377 current_file = None |
1376 | 1378 |
1555 changed = set() | 1557 changed = set() |
1556 for state, values in iterhunks(fp): | 1558 for state, values in iterhunks(fp): |
1557 if state == 'file': | 1559 if state == 'file': |
1558 afile, bfile, first_hunk, gp = values | 1560 afile, bfile, first_hunk, gp = values |
1559 if gp: | 1561 if gp: |
1560 gp.path = pathtransform(gp.path, strip - 1)[1] | 1562 gp.path = pathtransform(gp.path, strip - 1, '')[1] |
1561 if gp.oldpath: | 1563 if gp.oldpath: |
1562 gp.oldpath = pathtransform(gp.oldpath, strip - 1)[1] | 1564 gp.oldpath = pathtransform(gp.oldpath, strip - 1, '')[1] |
1563 else: | 1565 else: |
1564 gp = makepatchmeta(backend, afile, bfile, first_hunk, strip) | 1566 gp = makepatchmeta(backend, afile, bfile, first_hunk, strip) |
1565 changed.add(gp.path) | 1567 changed.add(gp.path) |
1566 if gp.op == 'RENAME': | 1568 if gp.op == 'RENAME': |
1567 changed.add(gp.oldpath) | 1569 changed.add(gp.oldpath) |