tests/test-narrow-expanddirstate.t
changeset 36079 a2a6e724d61a
child 36160 9fd8c2a3db5a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-narrow-expanddirstate.t	Mon Jan 29 16:19:33 2018 -0500
@@ -0,0 +1,170 @@
+  $ . "$TESTDIR/narrow-library.sh"
+
+  $ hg init master
+  $ cd master
+
+  $ mkdir inside
+  $ echo inside > inside/f1
+  $ mkdir outside
+  $ echo outside > outside/f2
+  $ mkdir patchdir
+  $ echo patch_this > patchdir/f3
+  $ hg ci -Aqm 'initial'
+
+  $ cd ..
+
+  $ hg clone --narrow ssh://user@dummy/master narrow --include inside
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets dff6a2a6d433
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+  $ cd narrow
+
+  $ mkdir outside
+  $ echo other_contents > outside/f2
+  $ grep outside .hg/narrowspec
+  [1]
+  $ grep outside .hg/dirstate
+  [1]
+  $ hg status
+
+`hg status` did not add outside.
+  $ grep outside .hg/narrowspec
+  [1]
+  $ grep outside .hg/dirstate
+  [1]
+
+Unfortunately this is not really a candidate for adding to narrowhg proper,
+since it depends on some other source for providing the manifests (when using
+treemanifests) and file contents. Something like a virtual filesystem and/or
+remotefilelog. We want to be useful when not using those systems, so we do not
+have this method available in narrowhg proper at the moment.
+  $ cat > "$TESTTMP/expand_extension.py" <<EOF
+  > import os
+  > import sys
+  > 
+  > from mercurial import extensions
+  > from mercurial import localrepo
+  > from mercurial import match as matchmod
+  > from mercurial import patch
+  > from mercurial import util as hgutil
+  > 
+  > def expandnarrowspec(ui, repo, newincludes=None):
+  >   if not newincludes:
+  >     return
+  >   import sys
+  >   newincludes = set([newincludes])
+  >   narrowhg = extensions.find('narrow')
+  >   includes, excludes = repo.narrowpats
+  >   currentmatcher = narrowhg.narrowspec.match(repo.root, includes, excludes)
+  >   includes = includes | newincludes
+  >   if not repo.currenttransaction():
+  >     ui.develwarn('expandnarrowspec called outside of transaction!')
+  >   repo.setnarrowpats(includes, excludes)
+  >   newmatcher = narrowhg.narrowspec.match(repo.root, includes, excludes)
+  >   added = matchmod.differencematcher(newmatcher, currentmatcher)
+  >   for f in repo['.'].manifest().walk(added):
+  >     repo.dirstate.normallookup(f)
+  > 
+  > def makeds(ui, repo):
+  >   def wrapds(orig, self):
+  >     ds = orig(self)
+  >     class expandingdirstate(ds.__class__):
+  >       # Mercurial 4.4 uses this version.
+  >       @hgutil.propertycache
+  >       def _map(self):
+  >         ret = super(expandingdirstate, self)._map
+  >         with repo.wlock(), repo.lock(), repo.transaction(
+  >             'expandnarrowspec'):
+  >           expandnarrowspec(ui, repo, os.environ.get('DIRSTATEINCLUDES'))
+  >         return ret
+  >       # Mercurial 4.3.3 and earlier uses this version. It seems that
+  >       # narrowhg does not currently support this version, but we include
+  >       # it just in case backwards compatibility is restored.
+  >       def _read(self):
+  >         ret = super(expandingdirstate, self)._read()
+  >         with repo.wlock(), repo.lock(), repo.transaction(
+  >             'expandnarrowspec'):
+  >           expandnarrowspec(ui, repo, os.environ.get('DIRSTATEINCLUDES'))
+  >         return ret
+  >     ds.__class__ = expandingdirstate
+  >     return ds
+  >   return wrapds
+  > 
+  > def reposetup(ui, repo):
+  >   extensions.wrapfilecache(localrepo.localrepository, 'dirstate',
+  >                            makeds(ui, repo))
+  >   def overridepatch(orig, *args, **kwargs):
+  >     with repo.wlock():
+  >       expandnarrowspec(ui, repo, os.environ.get('PATCHINCLUDES'))
+  >       return orig(*args, **kwargs)
+  > 
+  >   extensions.wrapfunction(patch, 'patch', overridepatch)
+  > EOF
+  $ cat >> ".hg/hgrc" <<EOF
+  > [extensions]
+  > expand_extension = $TESTTMP/expand_extension.py
+  > EOF
+
+Since we do not have the ability to rely on a virtual filesystem or
+remotefilelog in the test, we just fake it by copying the data from the 'master'
+repo.
+  $ cp -a ../master/.hg/store/data/* .hg/store/data
+Do that for patchdir as well.
+  $ cp -a ../master/patchdir .
+
+`hg status` will now add outside, but not patchdir.
+  $ DIRSTATEINCLUDES=path:outside hg status
+  M outside/f2
+  $ grep outside .hg/narrowspec
+  path:outside
+  $ grep outside .hg/dirstate > /dev/null
+  $ grep patchdir .hg/narrowspec
+  [1]
+  $ grep patchdir .hg/dirstate
+  [1]
+
+Get rid of the modification to outside/f2.
+  $ hg update -C .
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+This patch will not apply cleanly at the moment, so `hg import` will break
+  $ cat > "$TESTTMP/foo.patch" <<EOF
+  > --- patchdir/f3
+  > +++ patchdir/f3
+  > @@ -1,1 +1,1 @@
+  > -this should be "patch_this", but its not, so patch fails
+  > +this text is irrelevant
+  > EOF
+  $ PATCHINCLUDES=path:patchdir hg import -p0 -e "$TESTTMP/foo.patch" -m ignored
+  applying $TESTTMP/foo.patch
+  patching file patchdir/f3
+  Hunk #1 FAILED at 0
+  1 out of 1 hunks FAILED -- saving rejects to file patchdir/f3.rej
+  abort: patch failed to apply
+  [255]
+  $ grep patchdir .hg/narrowspec
+  [1]
+  $ grep patchdir .hg/dirstate > /dev/null
+  [1]
+
+Let's make it apply cleanly and see that it *did* expand properly
+  $ cat > "$TESTTMP/foo.patch" <<EOF
+  > --- patchdir/f3
+  > +++ patchdir/f3
+  > @@ -1,1 +1,1 @@
+  > -patch_this
+  > +patched_this
+  > EOF
+  $ PATCHINCLUDES=path:patchdir hg import -p0 -e "$TESTTMP/foo.patch" -m message
+  applying $TESTTMP/foo.patch
+  $ cat patchdir/f3
+  patched_this
+  $ grep patchdir .hg/narrowspec
+  path:patchdir
+  $ grep patchdir .hg/dirstate > /dev/null