##// END OF EJS Templates
mq: remove qrefresh slow path (issue2025)...
Dan Villiom Podlaski Christiansen -
r10366:d355cebd stable
parent child Browse files
Show More
@@ -1166,16 +1166,17 b' class queue(object):'
1166 if newdate:
1166 if newdate:
1167 newdate = '%d %d' % util.parsedate(newdate)
1167 newdate = '%d %d' % util.parsedate(newdate)
1168 wlock = repo.wlock()
1168 wlock = repo.wlock()
1169
1169 try:
1170 try:
1170 self.check_toppatch(repo)
1171 self.check_toppatch(repo)
1171 (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name)
1172 (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name)
1172 top = bin(top)
1173 top = bin(top)
1173 if repo.changelog.heads(top) != [top]:
1174 if repo.changelog.heads(top) != [top]:
1174 raise util.Abort(_("cannot refresh a revision with children"))
1175 raise util.Abort(_("cannot refresh a revision with children"))
1176
1175 cparents = repo.changelog.parents(top)
1177 cparents = repo.changelog.parents(top)
1176 patchparent = self.qparents(repo, top)
1178 patchparent = self.qparents(repo, top)
1177 ph = patchheader(self.join(patchfn))
1179 ph = patchheader(self.join(patchfn))
1178
1179 diffopts = self.diffopts({'git': opts.get('git')}, patchfn)
1180 diffopts = self.diffopts({'git': opts.get('git')}, patchfn)
1180 if msg:
1181 if msg:
1181 ph.setmessage(msg)
1182 ph.setmessage(msg)
@@ -1191,172 +1192,147 b' class queue(object):'
1191 if comments:
1192 if comments:
1192 patchf.write(comments)
1193 patchf.write(comments)
1193
1194
1194 tip = repo.changelog.tip()
1195 # update the dirstate in place, strip off the qtip commit
1195 if top == tip:
1196 # and then commit.
1196 # if the top of our patch queue is also the tip, there is an
1197 #
1197 # optimization here. We update the dirstate in place and strip
1198 # this should really read:
1198 # off the tip commit. Then just commit the current directory
1199 # mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
1199 # tree. We can also send repo.commit the list of files
1200 # but we do it backwards to take advantage of manifest/chlog
1200 # changed to speed up the diff
1201 # caching against the next repo.status call
1201 #
1202 mm, aa, dd, aa2 = repo.status(patchparent, top)[:4]
1202 # in short mode, we only diff the files included in the
1203 changes = repo.changelog.read(top)
1203 # patch already plus specified files
1204 man = repo.manifest.read(changes[0])
1204 #
1205 aaa = aa[:]
1205 # this should really read:
1206 matchfn = cmdutil.match(repo, pats, opts)
1206 # mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
1207 # in short mode, we only diff the files included in the
1207 # but we do it backwards to take advantage of manifest/chlog
1208 # patch already plus specified files
1208 # caching against the next repo.status call
1209 if opts.get('short'):
1209 #
1210 # if amending a patch, we start with existing
1210 mm, aa, dd, aa2 = repo.status(patchparent, tip)[:4]
1211 # files plus specified files - unfiltered
1211 changes = repo.changelog.read(tip)
1212 match = cmdutil.matchfiles(repo, mm + aa + dd + matchfn.files())
1212 man = repo.manifest.read(changes[0])
1213 # filter with inc/exl options
1213 aaa = aa[:]
1214 matchfn = cmdutil.match(repo, opts=opts)
1214 matchfn = cmdutil.match(repo, pats, opts)
1215 else:
1215 if opts.get('short'):
1216 match = cmdutil.matchall(repo)
1216 # if amending a patch, we start with existing
1217 m, a, r, d = repo.status(match=match)[:4]
1217 # files plus specified files - unfiltered
1218 match = cmdutil.matchfiles(repo, mm + aa + dd + matchfn.files())
1219 # filter with inc/exl options
1220 matchfn = cmdutil.match(repo, opts=opts)
1221 else:
1222 match = cmdutil.matchall(repo)
1223 m, a, r, d = repo.status(match=match)[:4]
1224
1218
1225 # we might end up with files that were added between
1219 # we might end up with files that were added between
1226 # tip and the dirstate parent, but then changed in the
1220 # qtip and the dirstate parent, but then changed in the
1227 # local dirstate. in this case, we want them to only
1221 # local dirstate. in this case, we want them to only
1228 # show up in the added section
1222 # show up in the added section
1229 for x in m:
1223 for x in m:
1230 if x not in aa:
1224 if x not in aa:
1231 mm.append(x)
1225 mm.append(x)
1232 # we might end up with files added by the local dirstate that
1226 # we might end up with files added by the local dirstate that
1233 # were deleted by the patch. In this case, they should only
1227 # were deleted by the patch. In this case, they should only
1234 # show up in the changed section.
1228 # show up in the changed section.
1235 for x in a:
1229 for x in a:
1236 if x in dd:
1230 if x in dd:
1237 del dd[dd.index(x)]
1231 del dd[dd.index(x)]
1238 mm.append(x)
1232 mm.append(x)
1239 else:
1233 else:
1240 aa.append(x)
1234 aa.append(x)
1241 # make sure any files deleted in the local dirstate
1235 # make sure any files deleted in the local dirstate
1242 # are not in the add or change column of the patch
1236 # are not in the add or change column of the patch
1243 forget = []
1237 forget = []
1244 for x in d + r:
1238 for x in d + r:
1245 if x in aa:
1239 if x in aa:
1246 del aa[aa.index(x)]
1240 del aa[aa.index(x)]
1247 forget.append(x)
1241 forget.append(x)
1248 continue
1242 continue
1249 elif x in mm:
1243 elif x in mm:
1250 del mm[mm.index(x)]
1244 del mm[mm.index(x)]
1251 dd.append(x)
1245 dd.append(x)
1252
1246
1253 m = list(set(mm))
1247 m = list(set(mm))
1254 r = list(set(dd))
1248 r = list(set(dd))
1255 a = list(set(aa))
1249 a = list(set(aa))
1256 c = [filter(matchfn, l) for l in (m, a, r)]
1250 c = [filter(matchfn, l) for l in (m, a, r)]
1257 match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2]))
1251 match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2]))
1258 chunks = patch.diff(repo, patchparent, match=match,
1252 chunks = patch.diff(repo, patchparent, match=match,
1259 changes=c, opts=diffopts)
1253 changes=c, opts=diffopts)
1260 for chunk in chunks:
1254 for chunk in chunks:
1261 patchf.write(chunk)
1255 patchf.write(chunk)
1262
1256
1263 try:
1257 try:
1264 if diffopts.git:
1258 if diffopts.git:
1265 copies = {}
1259 copies = {}
1266 for dst in a:
1260 for dst in a:
1267 src = repo.dirstate.copied(dst)
1261 src = repo.dirstate.copied(dst)
1268 # during qfold, the source file for copies may
1262 # during qfold, the source file for copies may
1269 # be removed. Treat this as a simple add.
1263 # be removed. Treat this as a simple add.
1270 if src is not None and src in repo.dirstate:
1264 if src is not None and src in repo.dirstate:
1271 copies.setdefault(src, []).append(dst)
1265 copies.setdefault(src, []).append(dst)
1272 repo.dirstate.add(dst)
1266 repo.dirstate.add(dst)
1273 # remember the copies between patchparent and tip
1267 # remember the copies between patchparent and qtip
1274 for dst in aaa:
1268 for dst in aaa:
1275 f = repo.file(dst)
1269 f = repo.file(dst)
1276 src = f.renamed(man[dst])
1270 src = f.renamed(man[dst])
1277 if src:
1271 if src:
1278 copies.setdefault(src[0], []).extend(copies.get(dst, []))
1272 copies.setdefault(src[0], []).extend(copies.get(dst, []))
1279 if dst in a:
1273 if dst in a:
1280 copies[src[0]].append(dst)
1274 copies[src[0]].append(dst)
1281 # we can't copy a file created by the patch itself
1275 # we can't copy a file created by the patch itself
1282 if dst in copies:
1276 if dst in copies:
1283 del copies[dst]
1277 del copies[dst]
1284 for src, dsts in copies.iteritems():
1278 for src, dsts in copies.iteritems():
1285 for dst in dsts:
1279 for dst in dsts:
1286 repo.dirstate.copy(src, dst)
1280 repo.dirstate.copy(src, dst)
1287 else:
1281 else:
1288 for dst in a:
1282 for dst in a:
1289 repo.dirstate.add(dst)
1283 repo.dirstate.add(dst)
1290 # Drop useless copy information
1284 # Drop useless copy information
1291 for f in list(repo.dirstate.copies()):
1285 for f in list(repo.dirstate.copies()):
1292 repo.dirstate.copy(None, f)
1286 repo.dirstate.copy(None, f)
1293 for f in r:
1287 for f in r:
1294 repo.dirstate.remove(f)
1288 repo.dirstate.remove(f)
1295 # if the patch excludes a modified file, mark that
1289 # if the patch excludes a modified file, mark that
1296 # file with mtime=0 so status can see it.
1290 # file with mtime=0 so status can see it.
1297 mm = []
1291 mm = []
1298 for i in xrange(len(m)-1, -1, -1):
1292 for i in xrange(len(m)-1, -1, -1):
1299 if not matchfn(m[i]):
1293 if not matchfn(m[i]):
1300 mm.append(m[i])
1294 mm.append(m[i])
1301 del m[i]
1295 del m[i]
1302 for f in m:
1296 for f in m:
1303 repo.dirstate.normal(f)
1297 repo.dirstate.normal(f)
1304 for f in mm:
1298 for f in mm:
1305 repo.dirstate.normallookup(f)
1299 repo.dirstate.normallookup(f)
1306 for f in forget:
1300 for f in forget:
1307 repo.dirstate.forget(f)
1301 repo.dirstate.forget(f)
1308
1302
1309 if not msg:
1303 if not msg:
1310 if not ph.message:
1304 if not ph.message:
1311 message = "[mq]: %s\n" % patchfn
1305 message = "[mq]: %s\n" % patchfn
1312 else:
1313 message = "\n".join(ph.message)
1314 else:
1306 else:
1315 message = msg
1307 message = "\n".join(ph.message)
1316
1308 else:
1317 user = ph.user or changes[1]
1309 message = msg
1318
1310
1319 # assumes strip can roll itself back if interrupted
1311 user = ph.user or changes[1]
1320 repo.dirstate.setparents(*cparents)
1321 self.applied.pop()
1322 self.applied_dirty = 1
1323 self.strip(repo, top, update=False,
1324 backup='strip')
1325 except:
1326 repo.dirstate.invalidate()
1327 raise
1328
1312
1329 try:
1313 # assumes strip can roll itself back if interrupted
1330 # might be nice to attempt to roll back strip after this
1314 repo.dirstate.setparents(*cparents)
1331 patchf.rename()
1315 self.applied.pop()
1332 n = repo.commit(message, user, ph.date, match=match,
1316 self.applied_dirty = 1
1333 force=True)
1317 self.strip(repo, top, update=False,
1334 self.applied.append(statusentry(hex(n), patchfn))
1318 backup='strip')
1335 except:
1319 except:
1336 ctx = repo[cparents[0]]
1320 repo.dirstate.invalidate()
1337 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1321 raise
1338 self.save_dirty()
1322
1339 self.ui.warn(_('refresh interrupted while patch was popped! '
1323 try:
1340 '(revert --all, qpush to recover)\n'))
1324 # might be nice to attempt to roll back strip after this
1341 raise
1342 else:
1343 self.printdiff(repo, diffopts, patchparent, fp=patchf)
1344 patchf.rename()
1325 patchf.rename()
1345 added = repo.status()[1]
1326 n = repo.commit(message, user, ph.date, match=match,
1346 for a in added:
1327 force=True)
1347 f = repo.wjoin(a)
1328 self.applied.append(statusentry(hex(n), patchfn))
1348 try:
1329 except:
1349 os.unlink(f)
1330 ctx = repo[cparents[0]]
1350 except OSError, e:
1331 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1351 if e.errno != errno.ENOENT:
1332 self.save_dirty()
1352 raise
1333 self.ui.warn(_('refresh interrupted while patch was popped! '
1353 try: os.removedirs(os.path.dirname(f))
1334 '(revert --all, qpush to recover)\n'))
1354 except: pass
1335 raise
1355 # forget the file copies in the dirstate
1356 # push should readd the files later on
1357 repo.dirstate.forget(a)
1358 self.pop(repo, force=True)
1359 self.push(repo, force=True)
1360 finally:
1336 finally:
1361 wlock.release()
1337 wlock.release()
1362 self.removeundo(repo)
1338 self.removeundo(repo)
@@ -383,16 +383,11 b' copy to copy'
383 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
383 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
384 created new head
384 created new head
385 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
385 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
386 popping bar
387 adding branch
386 adding branch
388 adding changesets
387 adding changesets
389 adding manifests
388 adding manifests
390 adding file changes
389 adding file changes
391 added 1 changesets with 1 changes to 1 files
390 added 1 changesets with 1 changes to 1 files
392 patch queue now empty
393 (working directory not at a head)
394 applying bar
395 now at: bar
396 diff --git a/bar b/bar
391 diff --git a/bar b/bar
397 new file mode 100644
392 new file mode 100644
398 --- /dev/null
393 --- /dev/null
@@ -418,16 +413,11 b' diff --git a/foo b/baz'
418
413
419 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
414 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
420 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
415 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
421 popping bar
422 adding branch
416 adding branch
423 adding changesets
417 adding changesets
424 adding manifests
418 adding manifests
425 adding file changes
419 adding file changes
426 added 1 changesets with 1 changes to 1 files
420 added 1 changesets with 1 changes to 1 files
427 patch queue now empty
428 (working directory not at a head)
429 applying bar
430 now at: bar
431 diff --git a/foo b/bleh
421 diff --git a/foo b/bleh
432 rename from foo
422 rename from foo
433 rename to bleh
423 rename to bleh
General Comments 0
You need to be logged in to leave comments. Login now