diff --git a/mercurial/context.py b/mercurial/context.py --- a/mercurial/context.py +++ b/mercurial/context.py @@ -35,7 +35,9 @@ fileset, match as matchmod, mdiff, + node as nodemod, obsolete as obsmod, + obsutil, patch, pathutil, phases, @@ -434,12 +436,49 @@ experiment with various message variants.""" if repo.filtername.startswith('visible'): msg = _("hidden revision '%s'") % changeid - hint = _('use --hidden to access hidden revisions') + + # Check if the changeset is obsolete + unfilteredrepo = repo.unfiltered() + ctx = unfilteredrepo[changeid] + + # If the changeset is obsolete, enrich the hint with the reason that + # made this changeset not visible + if ctx.obsolete(): + reason = _getobsoletereason(ctx, unfilteredrepo) + hint = _('use --hidden to access hidden revisions; %s') % reason + else: + hint = _('use --hidden to access hidden revisions') + return error.FilteredRepoLookupError(msg, hint=hint) msg = _("filtered revision '%s' (not in '%s' subset)") msg %= (changeid, repo.filtername) return error.FilteredRepoLookupError(msg) +def _getobsoletereason(ctx, unfilteredrepo): + successors = obsutil.successorssets(unfilteredrepo, ctx.node()) + reason = obsutil._getobsfate(successors) + + # Be more precise in case the revision is superseed + if reason == 'superseed': + reason = _("successor: %s") % nodemod.short(successors[0][0]) + elif reason == 'superseed_split': + + succs = [] + for node_id in successors[0]: + succs.append(nodemod.short(node_id)) + + if len(succs) <= 2: + reason = _("successors: %s") % ", ".join(succs) + else: + firstsuccessors = ", ".join(succs[:2]) + remainingnumber = len(succs) - 2 + + args = (firstsuccessors, remainingnumber) + successorsmsg = _("%s and %d more") % args + reason = _("successors: %s") % successorsmsg + + return reason + class changectx(basectx): """A changecontext object makes access to data related to a particular changeset convenient. It represents a read-only context already present in diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py --- a/mercurial/obsutil.py +++ b/mercurial/obsutil.py @@ -751,6 +751,32 @@ return values +def _getobsfate(successorssets): + """ Compute a changeset obsolescence fate based on his successorssets. + Successors can be the tipmost ones or the immediate ones. This function + return values are not meant to be shown directly to users, it is meant to + be used by internal functions only. + Returns one fate in the following list: + - pruned + - diverged + - superseed + - superseed_split + """ + + if len(successorssets) == 0: + # The commit has been pruned + return 'pruned' + elif len(successorssets) > 1: + return 'diverged' + else: + # No divergence, only one set of successors + successors = successorssets[0] + + if len(successors) == 1: + return 'superseed' + else: + return 'superseed_split' + def obsfateverb(successorset, markers): """ Return the verb summarizing the successorset and potentially using information from the markers diff --git a/tests/test-log.t b/tests/test-log.t --- a/tests/test-log.t +++ b/tests/test-log.t @@ -1718,7 +1718,7 @@ 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05 $ hg log -r a abort: hidden revision 'a'! - (use --hidden to access hidden revisions) + (use --hidden to access hidden revisions; pruned) [255] test that parent prevent a changeset to be hidden @@ -1775,7 +1775,7 @@ 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e $ hg log -T'{rev}:{node}\n' -r:0 abort: hidden revision '0'! - (use --hidden to access hidden revisions) + (use --hidden to access hidden revisions; pruned) [255] $ hg log -T'{rev}:{node}\n' -f 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e diff --git a/tests/test-obshistory.t b/tests/test-obshistory.t new file mode 100644 --- /dev/null +++ b/tests/test-obshistory.t @@ -0,0 +1,541 @@ +This test file test the various messages when accessing obsolete +revisions. + +Global setup +============ + + $ . $TESTDIR/testlib/obsmarker-common.sh + $ cat >> $HGRCPATH < [ui] + > interactive = true + > [phases] + > publish=False + > [experimental] + > evolution.createmarkers = yes + > evolution.effect-flags = yes + > EOF + +Test output on amended commit +============================= + +Test setup +---------- + + $ hg init $TESTTMP/local-amend + $ cd $TESTTMP/local-amend + $ mkcommit ROOT + $ mkcommit A0 + $ echo 42 >> A0 + $ hg commit --amend -m "A1 + > + > Better commit message" + $ hg log --hidden -G + @ changeset: 2:4ae3a4151de9 + | tag: tip + | parent: 0:ea207398892e + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A1 + | + | x changeset: 1:471f378eab4c + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: rewritten using amend as 2:4ae3a4151de9 + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + +Actual test +----------- + $ hg update 471f378eab4c + abort: hidden revision '471f378eab4c'! + (use --hidden to access hidden revisions; successor: 4ae3a4151de9) + [255] + $ hg update --hidden "desc(A0)" + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + +Test output with pruned commit +============================== + +Test setup +---------- + + $ hg init $TESTTMP/local-prune + $ cd $TESTTMP/local-prune + $ mkcommit ROOT + $ mkcommit A0 # 0 + $ mkcommit B0 # 1 + $ hg log --hidden -G + @ changeset: 2:0dec01379d3b + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: B0 + | + o changeset: 1:471f378eab4c + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + + $ hg debugobsolete --record-parents `getid 'desc(B0)'` + obsoleted 1 changesets + + $ hg log --hidden -G + @ changeset: 2:0dec01379d3b + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: pruned + | summary: B0 + | + o changeset: 1:471f378eab4c + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + + +Actual test +----------- + $ hg up 1 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg up 0dec01379d3b + abort: hidden revision '0dec01379d3b'! + (use --hidden to access hidden revisions; pruned) + [255] + $ hg up --hidden -r 'desc(B0)' + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + +Test output with splitted commit +================================ + +Test setup +---------- + + $ hg init $TESTTMP/local-split + $ cd $TESTTMP/local-split + $ mkcommit ROOT + $ echo 42 >> a + $ echo 43 >> b + $ hg commit -A -m "A0" + adding a + adding b + $ hg log --hidden -G + @ changeset: 1:471597cad322 + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + +# Simulate a split + $ hg up 0 + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + + $ echo 42 >> a + $ hg commit -A -m "A0" + adding a + created new head + + $ echo 43 >> b + $ hg commit -A -m "A0" + adding b + + $ hg debugobsolete `getid '1'` `getid '2'` `getid '3'` + obsoleted 1 changesets + + $ hg log --hidden -G + @ changeset: 3:f257fde29c7a + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + o changeset: 2:337fec4d2edc + | parent: 0:ea207398892e + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + | x changeset: 1:471597cad322 + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: split as 2:337fec4d2edc, 3:f257fde29c7a + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + +Actual test +----------- + $ hg update 471597cad322 + abort: hidden revision '471597cad322'! + (use --hidden to access hidden revisions; successors: 337fec4d2edc, f257fde29c7a) + [255] + $ hg update --hidden 'min(desc(A0))' + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + +Test output with lots of splitted commit +======================================== + +Test setup +---------- + + $ hg init $TESTTMP/local-lots-split + $ cd $TESTTMP/local-lots-split + $ mkcommit ROOT + $ echo 42 >> a + $ echo 43 >> b + $ echo 44 >> c + $ echo 45 >> d + $ hg commit -A -m "A0" + adding a + adding b + adding c + adding d + $ hg log --hidden -G + @ changeset: 1:de7290d8b885 + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + +# Simulate a split + $ hg up 0 + 0 files updated, 0 files merged, 4 files removed, 0 files unresolved + + $ echo 42 >> a + $ hg commit -A -m "A0" + adding a + created new head + + $ echo 43 >> b + $ hg commit -A -m "A0" + adding b + + $ echo 44 >> c + $ hg commit -A -m "A0" + adding c + + $ echo 45 >> d + $ hg commit -A -m "A0" + adding d + + $ hg debugobsolete `getid '1'` `getid '2'` `getid '3'` `getid '4'` `getid '5'` + obsoleted 1 changesets + + $ hg log --hidden -G + @ changeset: 5:c7f044602e9b + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + o changeset: 4:1ae8bc733a14 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + o changeset: 3:f257fde29c7a + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + o changeset: 2:337fec4d2edc + | parent: 0:ea207398892e + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + | x changeset: 1:de7290d8b885 + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: split as 2:337fec4d2edc, 3:f257fde29c7a, 4:1ae8bc733a14, 5:c7f044602e9b + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + +Actual test +----------- + $ hg update de7290d8b885 + abort: hidden revision 'de7290d8b885'! + (use --hidden to access hidden revisions; successors: 337fec4d2edc, f257fde29c7a and 2 more) + [255] + $ hg update --hidden 'min(desc(A0))' + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + +Test output with folded commit +============================== + +Test setup +---------- + + $ hg init $TESTTMP/local-fold + $ cd $TESTTMP/local-fold + $ mkcommit ROOT + $ mkcommit A0 + $ mkcommit B0 + $ hg log --hidden -G + @ changeset: 2:0dec01379d3b + | tag: tip + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: B0 + | + o changeset: 1:471f378eab4c + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + +# Simulate a fold + $ hg up 0 + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ echo "A0" > A0 + $ echo "B0" > B0 + $ hg add A0 B0 + $ hg commit -m "C0" + created new head + + $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(C0)'` + obsoleted 1 changesets + $ hg debugobsolete `getid 'desc(B0)'` `getid 'desc(C0)'` + obsoleted 1 changesets + + $ hg log --hidden -G + @ changeset: 3:eb5a0daa2192 + | tag: tip + | parent: 0:ea207398892e + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: C0 + | + | x changeset: 2:0dec01379d3b + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | obsolete: rewritten as 3:eb5a0daa2192 + | | summary: B0 + | | + | x changeset: 1:471f378eab4c + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: rewritten as 3:eb5a0daa2192 + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + + Actual test + ----------- + $ hg update 471f378eab4c + abort: hidden revision '471f378eab4c'! + (use --hidden to access hidden revisions; successor: eb5a0daa2192) + [255] + $ hg update --hidden 'desc(A0)' + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg update 0dec01379d3b + abort: hidden revision '0dec01379d3b'! + (use --hidden to access hidden revisions; successor: eb5a0daa2192) + [255] + $ hg update --hidden 'desc(B0)' + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + +Test output with divergence +=========================== + +Test setup +---------- + + $ hg init $TESTTMP/local-divergence + $ cd $TESTTMP/local-divergence + $ mkcommit ROOT + $ mkcommit A0 + $ hg commit --amend -m "A1" + $ hg log --hidden -G + @ changeset: 2:fdf9bde5129a + | tag: tip + | parent: 0:ea207398892e + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A1 + | + | x changeset: 1:471f378eab4c + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: rewritten using amend as 2:fdf9bde5129a + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + + $ hg update --hidden 'desc(A0)' + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg commit --amend -m "A2" + $ hg log --hidden -G + @ changeset: 3:65b757b745b9 + | tag: tip + | parent: 0:ea207398892e + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | instability: content-divergent + | summary: A2 + | + | o changeset: 2:fdf9bde5129a + |/ parent: 0:ea207398892e + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | instability: content-divergent + | summary: A1 + | + | x changeset: 1:471f378eab4c + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: rewritten using amend as 2:fdf9bde5129a + | obsolete: rewritten using amend as 3:65b757b745b9 + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + +Actual test +----------- + $ hg update 471f378eab4c + abort: hidden revision '471f378eab4c'! + (use --hidden to access hidden revisions; diverged) + [255] + $ hg update --hidden 'desc(A0)' + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + +Test output with amended + folded commit +======================================== + +Test setup +---------- + + $ hg init $TESTTMP/local-amend-fold + $ cd $TESTTMP/local-amend-fold + $ mkcommit ROOT + $ mkcommit A0 + $ mkcommit B0 + $ hg commit --amend -m "B1" + $ hg log --hidden -G + @ changeset: 3:b7ea6d14e664 + | tag: tip + | parent: 1:471f378eab4c + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: B1 + | + | x changeset: 2:0dec01379d3b + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: rewritten using amend as 3:b7ea6d14e664 + | summary: B0 + | + o changeset: 1:471f378eab4c + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + + +# Simulate a fold + $ hg up 0 + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ echo "A0" > A0 + $ echo "B0" > B0 + $ hg add A0 B0 + $ hg commit -m "C0" + created new head + + $ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(C0)'` + obsoleted 1 changesets + $ hg debugobsolete `getid 'desc(B1)'` `getid 'desc(C0)'` + obsoleted 1 changesets + + $ hg log --hidden -G + @ changeset: 4:eb5a0daa2192 + | tag: tip + | parent: 0:ea207398892e + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: C0 + | + | x changeset: 3:b7ea6d14e664 + | | parent: 1:471f378eab4c + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | obsolete: rewritten as 4:eb5a0daa2192 + | | summary: B1 + | | + | | x changeset: 2:0dec01379d3b + | |/ user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | obsolete: rewritten using amend as 3:b7ea6d14e664 + | | summary: B0 + | | + | x changeset: 1:471f378eab4c + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | obsolete: rewritten as 4:eb5a0daa2192 + | summary: A0 + | + o changeset: 0:ea207398892e + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: ROOT + + Actual test + ----------- + $ hg update 471f378eab4c + abort: hidden revision '471f378eab4c'! + (use --hidden to access hidden revisions; successor: eb5a0daa2192) + [255] + $ hg update --hidden 'desc(A0)' + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg update --hidden 0dec01379d3b + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg update 0dec01379d3b + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg update --hidden 'desc(B0)' + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t --- a/tests/test-obsolete.t +++ b/tests/test-obsolete.t @@ -197,7 +197,7 @@ [255] $ hg log -r 4 abort: hidden revision '4'! - (use --hidden to access hidden revisions) + (use --hidden to access hidden revisions; successor: 5601fb93a350) [255] $ hg debugrevspec 'rev(6)' $ hg debugrevspec 'rev(4)' @@ -1325,7 +1325,7 @@ $ hg book -d bookb $ hg log -r 13bedc178fce abort: hidden revision '13bedc178fce'! - (use --hidden to access hidden revisions) + (use --hidden to access hidden revisions; successor: a9b1f8652753) [255] Empty out the test extension, as it isn't compatible with later parts