comparison hgext/mq.py @ 2776:ae726521717c

merge with brendan.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Thu, 03 Aug 2006 11:12:02 -0700
parents ee48e5ef8753 663094f5595b
children f4d916351366
comparison
equal deleted inserted replaced
2775:ee48e5ef8753 2776:ae726521717c
65 self.series_path = "series" 65 self.series_path = "series"
66 self.status_path = "status" 66 self.status_path = "status"
67 67
68 if os.path.exists(os.path.join(self.path, self.series_path)): 68 if os.path.exists(os.path.join(self.path, self.series_path)):
69 self.full_series = self.opener(self.series_path).read().splitlines() 69 self.full_series = self.opener(self.series_path).read().splitlines()
70 self.read_series(self.full_series) 70 self.parse_series()
71 71
72 if os.path.exists(os.path.join(self.path, self.status_path)): 72 if os.path.exists(os.path.join(self.path, self.status_path)):
73 self.applied = [StatusEntry(l) 73 self.applied = [StatusEntry(l)
74 for l in self.opener(self.status_path).read().splitlines()] 74 for l in self.opener(self.status_path).read().splitlines()]
75 75
84 if s == patch: 84 if s == patch:
85 return index 85 return index
86 index += 1 86 index += 1
87 return None 87 return None
88 88
89 def read_series(self, list): 89 def parse_series(self):
90 def matcher(list):
91 pre = re.compile("(\s*)([^#]+)")
92 for l in list:
93 m = pre.match(l)
94 if m:
95 s = m.group(2)
96 s = s.rstrip()
97 if len(s) > 0:
98 yield s
99 self.series = [] 90 self.series = []
100 self.series = [ x for x in matcher(list) ] 91 for l in self.full_series:
92 s = l.split('#', 1)[0].strip()
93 if s:
94 self.series.append(s)
101 95
102 def save_dirty(self): 96 def save_dirty(self):
103 if self.applied_dirty: 97 def write_list(items, path):
104 if len(self.applied) > 0: 98 fp = self.opener(path, 'w')
105 nl = "\n" 99 for i in items:
106 else: 100 print >> fp, i
107 nl = "" 101 fp.close()
108 f = self.opener(self.status_path, "w") 102 if self.applied_dirty: write_list(map(str, self.applied), self.status_path)
109 f.write("\n".join([str(x) for x in self.applied]) + nl) 103 if self.series_dirty: write_list(self.full_series, self.series_path)
110 if self.series_dirty:
111 if len(self.full_series) > 0:
112 nl = "\n"
113 else:
114 nl = ""
115 f = self.opener(self.series_path, "w")
116 f.write("\n".join(self.full_series) + nl)
117 104
118 def readheaders(self, patch): 105 def readheaders(self, patch):
119 def eatdiff(lines): 106 def eatdiff(lines):
120 while lines: 107 while lines:
121 l = lines[-1] 108 l = lines[-1]
404 r.remove([patch], True) 391 r.remove([patch], True)
405 else: 392 else:
406 os.unlink(os.path.join(self.path, patch)) 393 os.unlink(os.path.join(self.path, patch))
407 i = self.find_series(patch) 394 i = self.find_series(patch)
408 del self.full_series[i] 395 del self.full_series[i]
409 self.read_series(self.full_series) 396 self.parse_series()
410 self.series_dirty = 1 397 self.series_dirty = 1
411 398
412 def check_toppatch(self, repo): 399 def check_toppatch(self, repo):
413 if len(self.applied) > 0: 400 if len(self.applied) > 0:
414 top = revlog.bin(self.applied[-1].rev) 401 top = revlog.bin(self.applied[-1].rev)
441 "New patch: %s" % patch, force=True, wlock=wlock) 428 "New patch: %s" % patch, force=True, wlock=wlock)
442 if n == None: 429 if n == None:
443 raise util.Abort(_("repo commit failed")) 430 raise util.Abort(_("repo commit failed"))
444 self.full_series[insert:insert] = [patch] 431 self.full_series[insert:insert] = [patch]
445 self.applied.append(StatusEntry(revlog.hex(n), patch)) 432 self.applied.append(StatusEntry(revlog.hex(n), patch))
446 self.read_series(self.full_series) 433 self.parse_series()
447 self.series_dirty = 1 434 self.series_dirty = 1
448 self.applied_dirty = 1 435 self.applied_dirty = 1
449 p = self.opener(patch, "w") 436 p = self.opener(patch, "w")
450 if msg: 437 if msg:
451 msg = msg + "\n" 438 msg = msg + "\n"
939 raise util.Abort(_("patch %s is not in series file") % patch) 926 raise util.Abort(_("patch %s is not in series file") % patch)
940 if not patch: 927 if not patch:
941 start = self.series_end() 928 start = self.series_end()
942 else: 929 else:
943 start = self.series.index(patch) + 1 930 start = self.series.index(patch) + 1
944 for p in self.series[start:]: 931 return [(i, self.series[i]) for i in xrange(start, len(self.series))]
945 if self.ui.verbose:
946 self.ui.write("%d " % self.series.index(p))
947 self.ui.write("%s\n" % p)
948 932
949 def qseries(self, repo, missing=None, summary=False): 933 def qseries(self, repo, missing=None, summary=False):
950 start = self.series_end() 934 start = self.series_end()
951 if not missing: 935 if not missing:
952 for i in range(len(self.series)): 936 for i in range(len(self.series)):
1017 self.ui.warn("No saved patch data found\n") 1001 self.ui.warn("No saved patch data found\n")
1018 return 1 1002 return 1
1019 self.ui.warn("restoring status: %s\n" % lines[0]) 1003 self.ui.warn("restoring status: %s\n" % lines[0])
1020 self.full_series = series 1004 self.full_series = series
1021 self.applied = applied 1005 self.applied = applied
1022 self.read_series(self.full_series) 1006 self.parse_series()
1023 self.series_dirty = 1 1007 self.series_dirty = 1
1024 self.applied_dirty = 1 1008 self.applied_dirty = 1
1025 heads = repo.changelog.heads() 1009 heads = repo.changelog.heads()
1026 if delete: 1010 if delete:
1027 if rev not in heads: 1011 if rev not in heads:
1163 if patch in self.series: 1147 if patch in self.series:
1164 raise util.Abort(_('patch %s is already in the series file') 1148 raise util.Abort(_('patch %s is already in the series file')
1165 % patch) 1149 % patch)
1166 index = self.full_series_end() + i 1150 index = self.full_series_end() + i
1167 self.full_series[index:index] = [patch] 1151 self.full_series[index:index] = [patch]
1168 self.read_series(self.full_series) 1152 self.parse_series()
1169 self.ui.warn("adding %s to series file\n" % patch) 1153 self.ui.warn("adding %s to series file\n" % patch)
1170 i += 1 1154 i += 1
1171 added.append(patch) 1155 added.append(patch)
1172 patch = None 1156 patch = None
1173 self.series_dirty = 1 1157 self.series_dirty = 1
1190 repo.mq.qapplied(repo, patch) 1174 repo.mq.qapplied(repo, patch)
1191 return 0 1175 return 0
1192 1176
1193 def unapplied(ui, repo, patch=None, **opts): 1177 def unapplied(ui, repo, patch=None, **opts):
1194 """print the patches not yet applied""" 1178 """print the patches not yet applied"""
1195 repo.mq.unapplied(repo, patch) 1179 for i, p in repo.mq.unapplied(repo, patch):
1196 return 0 1180 if ui.verbose:
1181 ui.write("%d " % i)
1182 ui.write("%s\n" % p)
1197 1183
1198 def qimport(ui, repo, *filename, **opts): 1184 def qimport(ui, repo, *filename, **opts):
1199 """import a patch""" 1185 """import a patch"""
1200 q = repo.mq 1186 q = repo.mq
1201 q.qimport(repo, filename, patch=opts['name'], 1187 q.qimport(repo, filename, patch=opts['name'],
1232 before that it has no patches applied. 1218 before that it has no patches applied.
1233 1219
1234 Source patch repository is looked for in <src>/.hg/patches by 1220 Source patch repository is looked for in <src>/.hg/patches by
1235 default. Use -p <url> to change. 1221 default. Use -p <url> to change.
1236 ''' 1222 '''
1237 commands.setremoteconfig(**opts) 1223 commands.setremoteconfig(ui, opts)
1238 if dest is None: 1224 if dest is None:
1239 dest = hg.defaultdest(source) 1225 dest = hg.defaultdest(source)
1240 sr = hg.repository(ui, ui.expandpath(source)) 1226 sr = hg.repository(ui, ui.expandpath(source))
1241 qbase, destrev = None, None 1227 qbase, destrev = None, None
1242 if sr.local(): 1228 if sr.local():
1301 changes unless -f is specified, in which case the patch will 1287 changes unless -f is specified, in which case the patch will
1302 be initialised with them. 1288 be initialised with them.
1303 1289
1304 -m or -l set the patch header as well as the commit message. 1290 -m or -l set the patch header as well as the commit message.
1305 If neither is specified, the patch header is empty and the 1291 If neither is specified, the patch header is empty and the
1306 commit message is 'New patch: PATCH' 1292 commit message is 'New patch: PATCH'"""
1307
1308 If -f is specified, the patch will be initialized with any
1309 uncommitted changes. Otherwise, if there outsta"""
1310 q = repo.mq 1293 q = repo.mq
1311 message=commands.logmessage(**opts) 1294 message=commands.logmessage(**opts)
1312 q.new(repo, patch, msg=message, force=opts['force']) 1295 q.new(repo, patch, msg=message, force=opts['force'])
1313 q.save_dirty() 1296 q.save_dirty()
1314 return 0 1297 return 0
1334 return 0 1317 return 0
1335 1318
1336 def fold(ui, repo, *files, **opts): 1319 def fold(ui, repo, *files, **opts):
1337 """fold the named patches into the current patch 1320 """fold the named patches into the current patch
1338 1321
1339 Patches must not yet be applied. 1322 Patches must not yet be applied. Each patch will be successively
1323 applied to the current patch in the order given. If all the
1324 patches apply successfully, the current patch will be refreshed
1325 with the new cumulative patch, and the folded patches will
1326 be deleted. With -f/--force, the folded patch files will
1327 be removed afterwards.
1328
1340 The header for each folded patch will be concatenated with 1329 The header for each folded patch will be concatenated with
1341 the current patch header, separated by a line of '* * *'.""" 1330 the current patch header, separated by a line of '* * *'."""
1342 1331
1343 q = repo.mq 1332 q = repo.mq
1344 1333
1382 message = ui.edit(message, user or ui.username()) 1371 message = ui.edit(message, user or ui.username())
1383 1372
1384 q.refresh(repo, msg=message) 1373 q.refresh(repo, msg=message)
1385 1374
1386 for patch in patches: 1375 for patch in patches:
1387 q.delete(repo, patch) 1376 q.delete(repo, patch, force=opts['force'])
1388 1377
1389 q.save_dirty() 1378 q.save_dirty()
1390 1379
1391 def header(ui, repo, patch=None): 1380 def header(ui, repo, patch=None):
1392 """Print the header of the topmost or specified patch""" 1381 """Print the header of the topmost or specified patch"""
1491 1480
1492 if ui.verbose: 1481 if ui.verbose:
1493 ui.write('Renaming %s to %s\n' % (patch, name)) 1482 ui.write('Renaming %s to %s\n' % (patch, name))
1494 i = q.find_series(patch) 1483 i = q.find_series(patch)
1495 q.full_series[i] = name 1484 q.full_series[i] = name
1496 q.read_series(q.full_series) 1485 q.parse_series()
1497 q.series_dirty = 1 1486 q.series_dirty = 1
1498 1487
1499 info = q.isapplied(patch) 1488 info = q.isapplied(patch)
1500 if info: 1489 if info:
1501 q.applied[info[0]] = StatusEntry(info[1], name) 1490 q.applied[info[0]] = StatusEntry(info[1], name)
1615 [('f', 'force', None, _('delete patch file'))], 1604 [('f', 'force', None, _('delete patch file'))],
1616 'hg qdelete [-f] PATCH'), 1605 'hg qdelete [-f] PATCH'),
1617 'qfold': 1606 'qfold':
1618 (fold, 1607 (fold,
1619 [('e', 'edit', None, _('edit patch header')), 1608 [('e', 'edit', None, _('edit patch header')),
1609 ('f', 'force', None, _('delete folded patch files')),
1620 ('m', 'message', '', _('set patch header to <text>')), 1610 ('m', 'message', '', _('set patch header to <text>')),
1621 ('l', 'logfile', '', _('set patch header to contents of <file>'))], 1611 ('l', 'logfile', '', _('set patch header to contents of <file>'))],
1622 'hg qfold [-e] [-m <text>] [-l <file] PATCH...'), 1612 'hg qfold [-e] [-m <text>] [-l <file] PATCH...'),
1623 'qheader': (header, [], 1613 'qheader': (header, [],
1624 _('hg qheader [PATCH]')), 1614 _('hg qheader [PATCH]')),