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