view tests/test-remote-hidden.t @ 42377:0546ead39a7e stable

manifest: avoid corruption by dropping removed files with pure (issue5801) Previously, removed files would simply be marked by overwriting the first byte with NUL and dropping their entry in `self.position`. But no effort was made to ignore them when compacting the dictionary into text form. This allowed them to slip into the manifest revision, since the code seems to be trying to minimize the string operations by copying as large a chunk as possible. As part of this, compact() walks the existing text based on entries in the `positions` list, and consumed everything up to the next position entry. This typically resulted in a ValueError complaining about unsorted manifest entries. Sometimes it seems that files do get dropped in large repos- it seems to correspond to there being a new entry that would take the same slot. A much more trivial problem is that if the only changes were removals, `_compact()` didn't even run because `__delitem__` doesn't add anything to `self.extradata`. Now there's an explicit variable to flag this, both to allow `_compact()` to run, and to avoid searching the manifest in cases where there are no removals. In practice, this behavior was mostly obscured by the check in fastdelta() which takes a different path that explicitly drops removed files if there are fewer than 1000 changes. However, timeless has a repo where after rebasing tens of commits, a totally different path[1] is taken that bypasses the change count check and hits this problem. [1] https://www.mercurial-scm.org/repo/hg/file/2338bdea4474/mercurial/manifest.py#l1511
author Matt Harbison <matt_harbison@yahoo.com>
date Thu, 23 May 2019 21:54:24 -0400
parents 70b71421fd33
children 34a46d48d24e
line wrap: on
line source

========================================================
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 cache pre-warm
--------------------

  $ ls -1 repo-with-hidden/.hg/cache
  branch2
  branch2-base
  branch2-served
  branch2-served.hidden
  branch2-visible
  rbc-names-v1
  rbc-revs-v1
  tags2
  tags2-visible

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