diff --git a/mercurial/branchmap.py b/mercurial/branchmap.py --- a/mercurial/branchmap.py +++ b/mercurial/branchmap.py @@ -40,6 +40,7 @@ unpack_from = struct.unpack_from subsettable = {None: 'visible', 'visible-hidden': 'visible', 'visible': 'served', + 'served.hidden': 'served', 'served': 'immutable', 'immutable': 'base'} diff --git a/mercurial/repoview.py b/mercurial/repoview.py --- a/mercurial/repoview.py +++ b/mercurial/repoview.py @@ -86,6 +86,14 @@ def computehidden(repo, visibilityexcept _revealancestors(pfunc, hidden, visible) return frozenset(hidden) +def computesecret(repo, visibilityexceptions=None): + """compute the set of revision that can never be exposed through hgweb + + Changeset in the secret phase (or above) should stay unaccessible.""" + assert not repo.changelog.filteredrevs + secrets = repo._phasecache.getrevset(repo, phases.remotehiddenphases) + return frozenset(secrets) + def computeunserved(repo, visibilityexceptions=None): """compute the set of revision that should be filtered when used a server @@ -93,9 +101,9 @@ def computeunserved(repo, visibilityexce assert not repo.changelog.filteredrevs # fast path in simple case to avoid impact of non optimised code hiddens = filterrevs(repo, 'visible') - secrets = repo._phasecache.getrevset(repo, phases.remotehiddenphases) + secrets = filterrevs(repo, 'served.hidden') if secrets: - return frozenset(hiddens | frozenset(secrets)) + return frozenset(hiddens | secrets) else: return hiddens @@ -141,6 +149,7 @@ def computeimpactable(repo, visibilityex # from scratch (very slow). filtertable = {'visible': computehidden, 'visible-hidden': computehidden, + 'served.hidden': computesecret, 'served': computeunserved, 'immutable': computemutable, 'base': computeimpactable} diff --git a/tests/test-remote-hidden.t b/tests/test-remote-hidden.t new file mode 100644 --- /dev/null +++ b/tests/test-remote-hidden.t @@ -0,0 +1,97 @@ +======================================================== +Test the ability to access a hidden revision on a server +======================================================== + +#require serve + + $ . $TESTDIR/testlib/obsmarker-common.sh + $ cat >> $HGRCPATH << EOF + > [phases] + > # public changeset are not obsolete + > publish=false + > [experimental] + > evolution=all + > [ui] + > logtemplate='{rev}:{node|short} {desc} [{phase}]\n' + > EOF + +Setup a simple repository with some hidden revisions +---------------------------------------------------- + +Testing the `served.hidden` view + + $ hg init repo-with-hidden + $ cd repo-with-hidden + + $ echo 0 > a + $ hg ci -qAm "c_Public" + $ hg phase --public + $ echo 1 > a + $ hg ci -m "c_Amend_Old" + $ echo 2 > a + $ hg ci -m "c_Amend_New" --amend + $ hg up ".^" + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo 3 > a + $ hg ci -m "c_Pruned" + created new head + $ hg debugobsolete --record-parents `getid 'desc("c_Pruned")'` -d '0 0' + obsoleted 1 changesets + $ hg up ".^" + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo 4 > a + $ hg ci -m "c_Secret" --secret + created new head + $ echo 5 > a + $ hg ci -m "c_Secret_Pruned" --secret + $ hg debugobsolete --record-parents `getid 'desc("c_Secret_Pruned")'` -d '0 0' + obsoleted 1 changesets + $ hg up null + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + + $ hg log -G -T '{rev}:{node|short} {desc} [{phase}]\n' --hidden + x 5:8d28cbe335f3 c_Secret_Pruned [secret] + | + o 4:1c6afd79eb66 c_Secret [secret] + | + | x 3:5d1575e42c25 c_Pruned [draft] + |/ + | o 2:c33affeb3f6b c_Amend_New [draft] + |/ + | x 1:be215fbb8c50 c_Amend_Old [draft] + |/ + o 0:5f354f46e585 c_Public [public] + + $ hg debugobsolete + be215fbb8c5090028b00154c1fe877ad1b376c61 c33affeb3f6b4e9621d1839d6175ddc07708807c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'amend', 'user': 'test'} + 5d1575e42c25b7f2db75cd4e0b881b1c35158fae 0 {5f354f46e5853535841ec7a128423e991ca4d59b} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} + 8d28cbe335f311bc89332d7bbe8a07889b6914a0 0 {1c6afd79eb6663275bbe30097e162b1c24ced0f0} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} + + $ cd .. + +Test the feature +================ + +Check that the `served.hidden` repoview +--------------------------------------- + + $ hg -R repo-with-hidden serve -p $HGPORT -d --pid-file hg.pid --config web.view=served.hidden + $ cat hg.pid >> $DAEMON_PIDS + +changesets in secret and higher phases are not visible through hgweb + + $ hg -R repo-with-hidden log --template "revision: {rev}\\n" --rev "reverse(not secret())" + revision: 2 + revision: 0 + $ hg -R repo-with-hidden log --template "revision: {rev}\\n" --rev "reverse(not secret())" --hidden + revision: 3 + revision: 2 + revision: 1 + revision: 0 + $ get-with-headers.py localhost:$HGPORT 'log?style=raw' | grep revision: + revision: 3 + revision: 2 + revision: 1 + revision: 0 + + $ killdaemons.py