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 |
|
|
|
1267 |
|
|
|
1268 |
|
|
|
1269 |
|
|
|
1270 |
|
|
|
1271 |
|
|
|
1272 |
|
|
|
1273 |
|
|
|
1274 |
|
|
|
1275 |
|
|
|
1276 |
|
|
|
1277 |
|
|
|
1278 |
|
|
|
1279 |
|
|
|
1280 |
|
|
|
1281 |
|
|
|
1282 |
|
|
|
1283 |
|
|
|
1284 |
|
|
|
1285 |
|
|
|
1286 |
|
|
|
1287 |
|
|
|
1288 |
|
|
|
1289 |
|
|
|
1290 |
|
|
|
1291 |
|
|
|
1292 |
|
|
|
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 |
|
|
|
1295 |
|
|
|
1296 |
|
|
|
1297 |
|
|
|
1298 |
|
|
|
1299 |
|
|
|
1300 |
|
|
|
1301 |
|
|
|
1302 |
|
|
|
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 |
|
|
|
1305 |
|
|
|
1306 |
|
|
|
1307 |
|
|
|
1308 |
|
|
|
1309 |
|
|
|
1310 |
|
|
|
1311 |
|
|
|
1312 |
|
|
|
1313 |
|
|
|
1314 |
|
|
|
1315 |
|
|
|
1316 |
|
|
|
1317 |
|
|
|
1318 |
|
|
|
1319 |
|
|
|
1320 |
|
|
|
1321 |
|
|
|
1322 |
|
|
|
1323 |
|
|
|
1324 |
|
|
|
1325 |
|
|
|
1326 |
|
|
|
1327 |
|
|
|
1328 |
|
|
|
1329 |
|
|
|
1330 |
|
|
|
1331 |
|
|
|
1332 |
|
|
|
1333 |
|
|
|
1334 |
|
|
|
1335 |
|
|
|
1336 |
|
|
|
1337 |
|
|
|
1338 |
|
|
|
1339 |
|
|
|
1340 |
|
|
|
1341 |
|
|
|
1342 |
|
|
|
1343 |
|
|
|
1344 |
|
|
|
1345 |
|
|
|
1346 |
|
|
|
1347 |
|
|
|
1348 |
|
|
|
1349 |
|
|
|
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 |
|
|
|
1352 |
|
|
|
1353 |
|
|
|
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 |
|
|
|
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 |
|
|
|
1374 | n = repo.commit(message, user, ph.date, match=match, | |
|
1375 | force=True) | |
|
1376 | self.applied.append(statusentry(hex(n), patchfn)) | |
|
1377 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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