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)