D10319: tests: add test-remotefilelog-strip.t to demonstrate an issue with linknodes

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

D10319: tests: add test-remotefilelog-strip.t to demonstrate an issue with linknodes

marmoute (Pierre-Yves David)
spectral created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  Background
  ----------
 
  Every time a commit is modified, remotefilelog updates the metadata for the file
  object to point to the new commit (I believe that this is different from
  non-remotefilelog hg, which leaves the linkrevs pointing to the obsolete
  commits; doing otherwise would involve changing data in the middle of revlogs).
 
  With `hg strip` (or other things that use repair.strip()), when you strip a
  commit that's not the tip of the revlog, there may be commits after it in revnum
  order that aren't descended from it and don't need to be (and shouldn't be)
  stripped. These are "saved" by strip in a bundle, and that bundle is reapplied
  after truncating the relevant revlogs.
 
  The problem
  -----------
 
  Remotefilelog generally avoids being involved at all in strip. Currently, that
  includes even providing file contents to this backup bundle. This can cause the
  linknode to point to a changeset that is no longer in the repository.
 
  Example:
 
    @  3 df91f74b871e
    |
    | x  2 70494d7ec5ef
    |/
    | x  1 1e423846dde0
    |/
    o  0 b292c1e3311f
 
  Commits 1, 2, and 3 are related via obsolescence, and are description-only
  changes. The linknode for the file in these commits changed each time we updated
  the description, so it's currently df91f7. If I strip commits 1 and 3, however,
  the linknode *remains* df91f7, which no longer exists in the repository. Commit
  70494d was "saved", stripped, and then reapplied, so it is in the repository (as
  revision 1 instead of 2 now), and was unobsoleted since the obsmarker was
  stripped as well. The linknode for the file should point to 70494d, the most
  recent commit that is in the repository that modified the file.
 
  Remotefilelog has some logic to handle broken linknodes, but it can be slow. We
  have actually disabled it internally because it's too slow for our purposes.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10319

AFFECTED FILES
  tests/test-remotefilelog-strip.t

CHANGE DETAILS

diff --git a/tests/test-remotefilelog-strip.t b/tests/test-remotefilelog-strip.t
new file mode 100644
--- /dev/null
+++ b/tests/test-remotefilelog-strip.t
@@ -0,0 +1,67 @@
+#require no-windows
+
+  $ . "$TESTDIR/remotefilelog-library.sh"
+
+  $ hg init master
+  $ cd master
+  $ cat >> .hg/hgrc <<EOF
+  > [remotefilelog]
+  > server=True
+  > EOF
+  $ echo x > x
+  $ hg commit -qAm x
+
+  $ cd ..
+
+  $ hgcloneshallow ssh://user@dummy/master shallow -q
+  1 files fetched over 1 fetches - (1 misses, 0.00% hit ratio) over *s (glob)
+  $ cd shallow
+
+  $ cat >> $TESTTMP/get_file_linknode.py <<EOF
+  > from mercurial import node, registrar, scmutil
+  > cmdtable = {}
+  > command = registrar.command(cmdtable)
+  > @command(b'debug-file-linknode', [(b'r', b'rev', b'.', b'rev')], b'hg debug-file-linknode FILE')
+  > def debug_file_linknode(ui, repo, file, **opts):
+  >   rflctx = scmutil.revsingle(repo.unfiltered(), opts['rev']).filectx(file)
+  >   ui.status(b'%s\n' % node.hex(rflctx.ancestormap()[rflctx._filenode][2]))
+  > EOF
+
+  $ cat >> .hg/hgrc <<EOF
+  > [ui]
+  > interactive=1
+  > [extensions]
+  > strip=
+  > get_file_linknode=$TESTTMP/get_file_linknode.py
+  > [experimental]
+  > evolution=createmarkers,allowunstable
+  > EOF
+  $ echo a > a
+  $ hg commit -qAm msg1
+  $ hg commit --amend 're:^$' -m msg2
+  $ hg commit --amend 're:^$' -m msg3
+  $ hg --hidden log -G -T '{rev} {node|short}'
+  @  3 df91f74b871e
+  |
+  | x  2 70494d7ec5ef
+  |/
+  | x  1 1e423846dde0
+  |/
+  o  0 b292c1e3311f
+  
+  $ hg debug-file-linknode -r 70494d a
+  df91f74b871e064c89afa1fe9e2f66afa2c125df
+  $ hg --hidden strip -r 1 3
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  saved backup bundle to $TESTTMP/shallow/.hg/strip-backup/df91f74b871e-c94d67be-backup.hg
+
+  $ hg --hidden log -G -T '{rev} {node|short}'
+  o  1 70494d7ec5ef
+  |
+  @  0 b292c1e3311f
+  
+FIXME: This should point to a commit that actually exists in the repo. Otherwise
+remotefilelog has to search every commit in the repository looking for a valid
+linkrev every time it's queried, such as during push.
+  $ hg debug-file-linknode -r 70494d a
+  df91f74b871e064c89afa1fe9e2f66afa2c125df



To: spectral, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel