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 |
|
|
1261 | # we might end up with files that were added between | |
1267 |
|
|
1262 | # qtip and the dirstate parent, but then changed in the | |
1268 |
|
|
1263 | # local dirstate. in this case, we want them to only | |
1269 |
|
|
1264 | # show up in the added section | |
1270 |
|
|
1265 | for x in m: | |
1271 |
|
|
1266 | if x not in aa: | |
1272 |
|
|
1267 | mm.append(x) | |
1273 |
|
|
1268 | # we might end up with files added by the local dirstate that | |
1274 |
|
|
1269 | # were deleted by the patch. In this case, they should only | |
1275 |
|
|
1270 | # show up in the changed section. | |
1276 |
|
|
1271 | for x in a: | |
1277 |
|
|
1272 | if x in dd: | |
1278 |
|
|
1273 | del dd[dd.index(x)] | |
1279 |
|
|
1274 | mm.append(x) | |
1280 |
|
|
1275 | else: | |
1281 |
|
|
1276 | aa.append(x) | |
1282 |
|
|
1277 | # make sure any files deleted in the local dirstate | |
1283 |
|
|
1278 | # are not in the add or change column of the patch | |
1284 |
|
|
1279 | forget = [] | |
1285 |
|
|
1280 | for x in d + r: | |
1286 |
|
|
1281 | if x in aa: | |
1287 |
|
|
1282 | del aa[aa.index(x)] | |
1288 |
|
|
1283 | forget.append(x) | |
1289 |
|
|
1284 | continue | |
1290 |
|
|
1285 | elif x in mm: | |
1291 |
|
|
1286 | del mm[mm.index(x)] | |
1292 |
|
|
1287 | dd.append(x) | |
1293 |
|
1288 | |||
1294 |
|
|
1289 | m = list(set(mm)) | |
1295 |
|
|
1290 | r = list(set(dd)) | |
1296 |
|
|
1291 | a = list(set(aa)) | |
1297 |
|
|
1292 | c = [filter(matchfn, l) for l in (m, a, r)] | |
1298 |
|
|
1293 | match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2])) | |
1299 |
|
|
1294 | chunks = patch.diff(repo, patchparent, match=match, | |
1300 |
|
|
1295 | changes=c, opts=diffopts) | |
1301 |
|
|
1296 | for chunk in chunks: | |
1302 |
|
|
1297 | patchf.write(chunk) | |
1303 |
|
1298 | |||
1304 |
|
|
1299 | try: | |
1305 |
|
|
1300 | if diffopts.git or diffopts.upgrade: | |
1306 |
|
|
1301 | copies = {} | |
1307 |
|
|
1302 | for dst in a: | |
1308 |
|
|
1303 | src = repo.dirstate.copied(dst) | |
1309 |
|
|
1304 | # during qfold, the source file for copies may | |
1310 |
|
|
1305 | # be removed. Treat this as a simple add. | |
1311 |
|
|
1306 | if src is not None and src in repo.dirstate: | |
1312 |
|
|
1307 | copies.setdefault(src, []).append(dst) | |
1313 |
|
|
1308 | repo.dirstate.add(dst) | |
1314 |
|
|
1309 | # remember the copies between patchparent and qtip | |
1315 |
|
|
1310 | for dst in aaa: | |
1316 |
|
|
1311 | f = repo.file(dst) | |
1317 |
|
|
1312 | src = f.renamed(man[dst]) | |
1318 |
|
|
1313 | if src: | |
1319 |
|
|
1314 | copies.setdefault(src[0], []).extend( | |
1320 |
|
|
1315 | copies.get(dst, [])) | |
1321 |
|
|
1316 | if dst in a: | |
1322 |
|
|
1317 | copies[src[0]].append(dst) | |
1323 |
|
|
1318 | # we can't copy a file created by the patch itself | |
1324 |
|
|
1319 | if dst in copies: | |
1325 |
|
|
1320 | del copies[dst] | |
1326 |
|
|
1321 | for src, dsts in copies.iteritems(): | |
1327 |
|
|
1322 | for dst in dsts: | |
1328 |
|
|
1323 | repo.dirstate.copy(src, dst) | |
1329 |
|
|
1324 | else: | |
1330 |
|
|
1325 | for dst in a: | |
1331 |
|
|
1326 | repo.dirstate.add(dst) | |
1332 |
|
|
1327 | # Drop useless copy information | |
1333 |
|
|
1328 | for f in list(repo.dirstate.copies()): | |
1334 |
|
|
1329 | repo.dirstate.copy(None, f) | |
1335 |
|
|
1330 | for f in r: | |
1336 |
|
|
1331 | repo.dirstate.remove(f) | |
1337 |
|
|
1332 | # if the patch excludes a modified file, mark that | |
1338 |
|
|
1333 | # file with mtime=0 so status can see it. | |
1339 |
|
|
1334 | mm = [] | |
1340 |
|
|
1335 | for i in xrange(len(m)-1, -1, -1): | |
1341 |
|
|
1336 | if not matchfn(m[i]): | |
1342 |
|
|
1337 | mm.append(m[i]) | |
1343 |
|
|
1338 | del m[i] | |
1344 |
|
|
1339 | for f in m: | |
1345 |
|
|
1340 | repo.dirstate.normal(f) | |
1346 |
|
|
1341 | for f in mm: | |
1347 |
|
|
1342 | repo.dirstate.normallookup(f) | |
1348 |
|
|
1343 | for f in forget: | |
1349 |
|
|
1344 | repo.dirstate.forget(f) | |
1350 |
|
1345 | |||
1351 |
|
|
1346 | if not msg: | |
1352 |
|
|
1347 | if not ph.message: | |
1353 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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 |
|
|
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