##// END OF EJS Templates
Merge with crew-stable
Patrick Mezard -
r10368:f05e0d54 merge default
parent child Browse files
Show More
@@ -1208,12 +1208,14 b' class queue(object):'
1208 1208 if newdate:
1209 1209 newdate = '%d %d' % util.parsedate(newdate)
1210 1210 wlock = repo.wlock()
1211
1211 1212 try:
1212 1213 self.check_toppatch(repo)
1213 1214 (top, patchfn) = (self.applied[-1].rev, self.applied[-1].name)
1214 1215 top = bin(top)
1215 1216 if repo.changelog.heads(top) != [top]:
1216 1217 raise util.Abort(_("cannot refresh a revision with children"))
1218
1217 1219 cparents = repo.changelog.parents(top)
1218 1220 patchparent = self.qparents(repo, top)
1219 1221 ph = patchheader(self.join(patchfn))
@@ -1232,173 +1234,148 b' class queue(object):'
1232 1234 if comments:
1233 1235 patchf.write(comments)
1234 1236
1235 tip = repo.changelog.tip()
1236 if top == tip:
1237 # if the top of our patch queue is also the tip, there is an
1238 # optimization here. We update the dirstate in place and strip
1239 # off the tip commit. Then just commit the current directory
1240 # tree. We can also send repo.commit the list of files
1241 # changed to speed up the diff
1242 #
1243 # in short mode, we only diff the files included in the
1244 # patch already plus specified files
1245 #
1246 # this should really read:
1247 # mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
1248 # but we do it backwards to take advantage of manifest/chlog
1249 # caching against the next repo.status call
1250 #
1251 mm, aa, dd, aa2 = repo.status(patchparent, tip)[:4]
1252 changes = repo.changelog.read(tip)
1253 man = repo.manifest.read(changes[0])
1254 aaa = aa[:]
1255 matchfn = cmdutil.match(repo, pats, opts)
1256 if opts.get('short'):
1257 # if amending a patch, we start with existing
1258 # files plus specified files - unfiltered
1259 match = cmdutil.matchfiles(repo, mm + aa + dd + matchfn.files())
1260 # filter with inc/exl options
1261 matchfn = cmdutil.match(repo, opts=opts)
1262 else:
1263 match = cmdutil.matchall(repo)
1264 m, a, r, d = repo.status(match=match)[:4]
1237 # update the dirstate in place, strip off the qtip commit
1238 # and then commit.
1239 #
1240 # this should really read:
1241 # mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
1242 # but we do it backwards to take advantage of manifest/chlog
1243 # caching against the next repo.status call
1244 mm, aa, dd, aa2 = repo.status(patchparent, top)[:4]
1245 changes = repo.changelog.read(top)
1246 man = repo.manifest.read(changes[0])
1247 aaa = aa[:]
1248 matchfn = cmdutil.match(repo, pats, opts)
1249 # in short mode, we only diff the files included in the
1250 # patch already plus specified files
1251 if opts.get('short'):
1252 # if amending a patch, we start with existing
1253 # files plus specified files - unfiltered
1254 match = cmdutil.matchfiles(repo, mm + aa + dd + matchfn.files())
1255 # filter with inc/exl options
1256 matchfn = cmdutil.match(repo, opts=opts)
1257 else:
1258 match = cmdutil.matchall(repo)
1259 m, a, r, d = repo.status(match=match)[:4]
1265 1260
1266 # we might end up with files that were added between
1267 # tip and the dirstate parent, but then changed in the
1268 # local dirstate. in this case, we want them to only
1269 # show up in the added section
1270 for x in m:
1271 if x not in aa:
1272 mm.append(x)
1273 # we might end up with files added by the local dirstate that
1274 # were deleted by the patch. In this case, they should only
1275 # show up in the changed section.
1276 for x in a:
1277 if x in dd:
1278 del dd[dd.index(x)]
1279 mm.append(x)
1280 else:
1281 aa.append(x)
1282 # make sure any files deleted in the local dirstate
1283 # are not in the add or change column of the patch
1284 forget = []
1285 for x in d + r:
1286 if x in aa:
1287 del aa[aa.index(x)]
1288 forget.append(x)
1289 continue
1290 elif x in mm:
1291 del mm[mm.index(x)]
1292 dd.append(x)
1261 # we might end up with files that were added between
1262 # qtip and the dirstate parent, but then changed in the
1263 # local dirstate. in this case, we want them to only
1264 # show up in the added section
1265 for x in m:
1266 if x not in aa:
1267 mm.append(x)
1268 # we might end up with files added by the local dirstate that
1269 # were deleted by the patch. In this case, they should only
1270 # show up in the changed section.
1271 for x in a:
1272 if x in dd:
1273 del dd[dd.index(x)]
1274 mm.append(x)
1275 else:
1276 aa.append(x)
1277 # make sure any files deleted in the local dirstate
1278 # are not in the add or change column of the patch
1279 forget = []
1280 for x in d + r:
1281 if x in aa:
1282 del aa[aa.index(x)]
1283 forget.append(x)
1284 continue
1285 elif x in mm:
1286 del mm[mm.index(x)]
1287 dd.append(x)
1293 1288
1294 m = list(set(mm))
1295 r = list(set(dd))
1296 a = list(set(aa))
1297 c = [filter(matchfn, l) for l in (m, a, r)]
1298 match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2]))
1299 chunks = patch.diff(repo, patchparent, match=match,
1300 changes=c, opts=diffopts)
1301 for chunk in chunks:
1302 patchf.write(chunk)
1289 m = list(set(mm))
1290 r = list(set(dd))
1291 a = list(set(aa))
1292 c = [filter(matchfn, l) for l in (m, a, r)]
1293 match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2]))
1294 chunks = patch.diff(repo, patchparent, match=match,
1295 changes=c, opts=diffopts)
1296 for chunk in chunks:
1297 patchf.write(chunk)
1303 1298
1304 try:
1305 if diffopts.git or diffopts.upgrade:
1306 copies = {}
1307 for dst in a:
1308 src = repo.dirstate.copied(dst)
1309 # during qfold, the source file for copies may
1310 # be removed. Treat this as a simple add.
1311 if src is not None and src in repo.dirstate:
1312 copies.setdefault(src, []).append(dst)
1313 repo.dirstate.add(dst)
1314 # remember the copies between patchparent and tip
1315 for dst in aaa:
1316 f = repo.file(dst)
1317 src = f.renamed(man[dst])
1318 if src:
1319 copies.setdefault(src[0], []).extend(
1320 copies.get(dst, []))
1321 if dst in a:
1322 copies[src[0]].append(dst)
1323 # we can't copy a file created by the patch itself
1324 if dst in copies:
1325 del copies[dst]
1326 for src, dsts in copies.iteritems():
1327 for dst in dsts:
1328 repo.dirstate.copy(src, dst)
1329 else:
1330 for dst in a:
1331 repo.dirstate.add(dst)
1332 # Drop useless copy information
1333 for f in list(repo.dirstate.copies()):
1334 repo.dirstate.copy(None, f)
1335 for f in r:
1336 repo.dirstate.remove(f)
1337 # if the patch excludes a modified file, mark that
1338 # file with mtime=0 so status can see it.
1339 mm = []
1340 for i in xrange(len(m)-1, -1, -1):
1341 if not matchfn(m[i]):
1342 mm.append(m[i])
1343 del m[i]
1344 for f in m:
1345 repo.dirstate.normal(f)
1346 for f in mm:
1347 repo.dirstate.normallookup(f)
1348 for f in forget:
1349 repo.dirstate.forget(f)
1299 try:
1300 if diffopts.git or diffopts.upgrade:
1301 copies = {}
1302 for dst in a:
1303 src = repo.dirstate.copied(dst)
1304 # during qfold, the source file for copies may
1305 # be removed. Treat this as a simple add.
1306 if src is not None and src in repo.dirstate:
1307 copies.setdefault(src, []).append(dst)
1308 repo.dirstate.add(dst)
1309 # remember the copies between patchparent and qtip
1310 for dst in aaa:
1311 f = repo.file(dst)
1312 src = f.renamed(man[dst])
1313 if src:
1314 copies.setdefault(src[0], []).extend(
1315 copies.get(dst, []))
1316 if dst in a:
1317 copies[src[0]].append(dst)
1318 # we can't copy a file created by the patch itself
1319 if dst in copies:
1320 del copies[dst]
1321 for src, dsts in copies.iteritems():
1322 for dst in dsts:
1323 repo.dirstate.copy(src, dst)
1324 else:
1325 for dst in a:
1326 repo.dirstate.add(dst)
1327 # Drop useless copy information
1328 for f in list(repo.dirstate.copies()):
1329 repo.dirstate.copy(None, f)
1330 for f in r:
1331 repo.dirstate.remove(f)
1332 # if the patch excludes a modified file, mark that
1333 # file with mtime=0 so status can see it.
1334 mm = []
1335 for i in xrange(len(m)-1, -1, -1):
1336 if not matchfn(m[i]):
1337 mm.append(m[i])
1338 del m[i]
1339 for f in m:
1340 repo.dirstate.normal(f)
1341 for f in mm:
1342 repo.dirstate.normallookup(f)
1343 for f in forget:
1344 repo.dirstate.forget(f)
1350 1345
1351 if not msg:
1352 if not ph.message:
1353 message = "[mq]: %s\n" % patchfn
1354 else:
1355 message = "\n".join(ph.message)
1346 if not msg:
1347 if not ph.message:
1348 message = "[mq]: %s\n" % patchfn
1356 1349 else:
1357 message = msg
1358
1359 user = ph.user or changes[1]
1350 message = "\n".join(ph.message)
1351 else:
1352 message = msg
1360 1353
1361 # assumes strip can roll itself back if interrupted
1362 repo.dirstate.setparents(*cparents)
1363 self.applied.pop()
1364 self.applied_dirty = 1
1365 self.strip(repo, top, update=False,
1366 backup='strip')
1367 except:
1368 repo.dirstate.invalidate()
1369 raise
1354 user = ph.user or changes[1]
1370 1355
1371 try:
1372 # might be nice to attempt to roll back strip after this
1373 patchf.rename()
1374 n = repo.commit(message, user, ph.date, match=match,
1375 force=True)
1376 self.applied.append(statusentry(hex(n), patchfn))
1377 except:
1378 ctx = repo[cparents[0]]
1379 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1380 self.save_dirty()
1381 self.ui.warn(_('refresh interrupted while patch was popped! '
1382 '(revert --all, qpush to recover)\n'))
1383 raise
1384 else:
1385 self.printdiff(repo, diffopts, patchparent, fp=patchf)
1356 # assumes strip can roll itself back if interrupted
1357 repo.dirstate.setparents(*cparents)
1358 self.applied.pop()
1359 self.applied_dirty = 1
1360 self.strip(repo, top, update=False,
1361 backup='strip')
1362 except:
1363 repo.dirstate.invalidate()
1364 raise
1365
1366 try:
1367 # might be nice to attempt to roll back strip after this
1386 1368 patchf.rename()
1387 added = repo.status()[1]
1388 for a in added:
1389 f = repo.wjoin(a)
1390 try:
1391 os.unlink(f)
1392 except OSError, e:
1393 if e.errno != errno.ENOENT:
1394 raise
1395 try: os.removedirs(os.path.dirname(f))
1396 except: pass
1397 # forget the file copies in the dirstate
1398 # push should readd the files later on
1399 repo.dirstate.forget(a)
1400 self.pop(repo, force=True)
1401 self.push(repo, force=True)
1369 n = repo.commit(message, user, ph.date, match=match,
1370 force=True)
1371 self.applied.append(statusentry(hex(n), patchfn))
1372 except:
1373 ctx = repo[cparents[0]]
1374 repo.dirstate.rebuild(ctx.node(), ctx.manifest())
1375 self.save_dirty()
1376 self.ui.warn(_('refresh interrupted while patch was popped! '
1377 '(revert --all, qpush to recover)\n'))
1378 raise
1402 1379 finally:
1403 1380 wlock.release()
1404 1381 self.removeundo(repo)
@@ -155,6 +155,31 b' hg qrefresh'
155 155 hg qdiff --nodates
156 156 cd ..
157 157
158 echo '% issue2025: qrefresh does not honor filtering options when tip != qtip'
159 hg init repo-2025
160 cd repo-2025
161 echo a > a
162 echo b > b
163 hg ci -qAm addab
164 echo a >> a
165 echo b >> b
166 hg qnew -f patch
167 hg up -qC 0
168 echo c > c
169 hg ci -qAm addc
170 hg up -qC 1
171 echo '% refresh with tip != qtip'
172 hg --config diff.nodates=1 qrefresh -I b 2>&1 \
173 | sed 's/saving bundle.*/saving bundle.../g'
174 echo '% status after refresh'
175 hg st
176 echo '% b after refresh'
177 cat b
178 echo '% patch file after refresh'
179 cat .hg/patches/patch
180 cd ..
181
182
158 183 echo % issue1441 with git patches
159 184 hg init repo-1441-git
160 185 cd repo-1441-git
@@ -259,6 +259,26 b' diff -r 000000000000 b'
259 259 +++ b/b
260 260 @@ -0,0 +1,1 @@
261 261 +a
262 % issue2025: qrefresh does not honor filtering options when tip != qtip
263 % refresh with tip != qtip
264 saving bundle...
265 adding branch
266 adding changesets
267 adding manifests
268 adding file changes
269 added 1 changesets with 1 changes to 1 files
270 % status after refresh
271 M a
272 % b after refresh
273 b
274 b
275 % patch file after refresh
276 diff -r 1a60229be7ac b
277 --- a/b
278 +++ b/b
279 @@ -1,1 +1,2 @@
280 b
281 +b
262 282 % issue1441 with git patches
263 283 diff --git a/b b/b
264 284 new file mode 100644
@@ -392,16 +392,11 b' copy to copy'
392 392 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
393 393 created new head
394 394 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
395 popping bar
396 395 adding branch
397 396 adding changesets
398 397 adding manifests
399 398 adding file changes
400 399 added 1 changesets with 1 changes to 1 files
401 patch queue now empty
402 (working directory not at a head)
403 applying bar
404 now at: bar
405 400 diff --git a/bar b/bar
406 401 new file mode 100644
407 402 --- /dev/null
@@ -427,16 +422,11 b' diff --git a/foo b/baz'
427 422 % test file move chains in the slow path
428 423 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
429 424 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
430 popping bar
431 425 adding branch
432 426 adding changesets
433 427 adding manifests
434 428 adding file changes
435 429 added 1 changesets with 1 changes to 1 files
436 patch queue now empty
437 (working directory not at a head)
438 applying bar
439 now at: bar
440 430 diff --git a/foo b/bleh
441 431 rename from foo
442 432 rename to bleh
General Comments 0
You need to be logged in to leave comments. Login now