comparison tests/test-import.t @ 26631:e077ce385609

localrepo: restore dirstate to one before rollbacking if not parent-gone 'localrepository.rollback()' explicilty restores dirstate, only if at least one of current parents of the working directory is removed at rollbacking (a.k.a "parent-gone"). After DirstateTransactionPlan, 'dirstate.write()' will cause marking '.hg/dirstate' as a file to be restored at rollbacking. https://mercurial.selenic.com/wiki/DirstateTransactionPlan Then, 'transaction.rollback()' restores '.hg/dirstate' regardless of parents of the working directory at that time, and this causes unexpected dirstate changes if not "parent-gone" (e.g. "hg update" to another branch after "hg commit" or so, then "hg rollback"). To avoid such situation, this patch restores dirstate to one before rollbacking if not "parent-gone". before: b1. restore dirstate explicitly, if "parent-gone" after: a1. save dirstate before actual rollbacking via dirstateguard a2. restore dirstate via 'transaction.rollback()' a3. if "parent-gone" - discard backup (a1) - restore dirstate from 'undo.dirstate' a4. otherwise, restore dirstate from backup (a1) Even though restoring dirstate at (a3) after (a2) seems redundant, this patch keeps this existing code path, because: - it isn't ensured that 'dirstate.write()' was invoked at least once while transaction running If not, '.hg/dirstate' isn't restored at (a2). In addition to it, rude 3rd party extension invoking 'dirstate.write()' without 'repo' while transaction running (see subsequent patches for detail) may break consistency of a file backup-ed by transaction. - this patch mainly focuses on changes for DirstateTransactionPlan Restoring dirstate at (a3) itself should be cheaper enough than rollbacking itself. Redundancy will be removed in next step. Newly added test is almost meaningless at this point. It will be used to detect regression while implementing delayed dirstate write out.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Tue, 13 Oct 2015 12:25:43 -0700
parents dd2f5e014806
children 9f9ec4abe700
comparison
equal deleted inserted replaced
26630:3111b45a2bbf 26631:e077ce385609
426 $ hg --cwd b rollback 426 $ hg --cwd b rollback
427 repository tip rolled back to revision 0 (undo import) 427 repository tip rolled back to revision 0 (undo import)
428 working directory now based on revision 0 428 working directory now based on revision 0
429 $ hg --cwd b parents --template 'parent: {rev}\n' 429 $ hg --cwd b parents --template 'parent: {rev}\n'
430 parent: 0 430 parent: 0
431
432 Test that "hg rollback" doesn't restore dirstate to one at the
433 beginning of the rollbacked transaction in not-"parent-gone" case.
434
435 invoking pretxncommit hook will cause marking '.hg/dirstate' as a file
436 to be restored at rollbacking, after DirstateTransactionPlan (see wiki
437 page for detail).
438
439 $ hg --cwd b branch -q foobar
440 $ hg --cwd b commit -m foobar
441 $ hg --cwd b update 0 -q
442 $ hg --cwd b import ../patch1 ../patch2 --config hooks.pretxncommit=true
443 applying ../patch1
444 applying ../patch2
445 $ hg --cwd b update -q 1
446 $ hg --cwd b rollback -q
447 $ hg --cwd b parents --template 'parent: {rev}\n'
448 parent: 1
449
431 $ rm -r b 450 $ rm -r b
432 451
433 452
434 importing a patch in a subdirectory failed at the commit stage 453 importing a patch in a subdirectory failed at the commit stage
435 454