# HG changeset patch # User Idan Kamara # Date 1364038490 -7200 # Node ID 1c8e0d6ac3b0269a409caf40a23cc83569ce9474 # Parent 76d49dab6a0003c86cb1c0ac2ae1c137c8ae9660 localrepo: always write the filtered phasecache when nodes are destroyed (issue3827) When the strip command is run, it calls repo.destroyed, which in turn checks if we read _phasecache, and if we did calls filterunknown on it and flushes the changes immediately. But in some cases, nothing causes _phasecache to be read, so we miss out on this and the file remains the same on-disk. Then a call to invalidate comes, which should refresh _phasecache if it changed, but it didn't, so it keeps using the old one with the stripped revision which causes an IndexError. Test written by Yuya Nishihara. diff -r 76d49dab6a00 -r 1c8e0d6ac3b0 mercurial/localrepo.py --- a/mercurial/localrepo.py Tue Mar 19 16:19:20 2013 -0700 +++ b/mercurial/localrepo.py Sat Mar 23 13:34:50 2013 +0200 @@ -1416,9 +1416,8 @@ # removed. We can either remove phasecache from the filecache, # causing it to reload next time it is accessed, or simply filter # the removed nodes now and write the updated cache. - if '_phasecache' in self._filecache: - self._phasecache.filterunknown(self) - self._phasecache.write() + self._phasecache.filterunknown(self) + self._phasecache.write() # update the 'served' branch cache to help read only server process # Thanks to branchcach collaboration this is done from the nearest diff -r 76d49dab6a00 -r 1c8e0d6ac3b0 tests/test-commandserver.py --- a/tests/test-commandserver.py Tue Mar 19 16:19:20 2013 -0700 +++ b/tests/test-commandserver.py Sat Mar 23 13:34:50 2013 +0200 @@ -236,6 +236,27 @@ f.close() runcommand(server, ['status', '-i', '-u']) +def phasecacheafterstrip(server): + readchannel(server) + + # create new head, 5:731265503d86 + runcommand(server, ['update', '-C', '0']) + f = open('a', 'ab') + f.write('a\n') + f.close() + runcommand(server, ['commit', '-Am.', 'a']) + runcommand(server, ['log', '-Gq']) + + # make it public; draft marker moves to 4:7966c8e3734d + runcommand(server, ['phase', '-p', '.']) + runcommand(server, ['phase', '.']) # load _phasecache.phaseroots + + # strip 1::4 outside server + os.system('hg --config extensions.mq= strip 1') + + # shouldn't raise "7966c8e3734d: no node!" + runcommand(server, ['branches']) + if __name__ == '__main__': os.system('hg init') @@ -258,3 +279,4 @@ check(rollback) check(branch) check(hgignore) + check(phasecacheafterstrip) diff -r 76d49dab6a00 -r 1c8e0d6ac3b0 tests/test-commandserver.py.out --- a/tests/test-commandserver.py.out Tue Mar 19 16:19:20 2013 -0700 +++ b/tests/test-commandserver.py.out Sat Mar 23 13:34:50 2013 +0200 @@ -164,3 +164,29 @@ adding .hgignore runcommand status -i -u I ignored-file + +testing phasecacheafterstrip: + + runcommand update -C 0 +1 files updated, 0 files merged, 2 files removed, 0 files unresolved + runcommand commit -Am. a +created new head + runcommand log -Gq +@ 5:731265503d86 +| +| o 4:7966c8e3734d +| | +| o 3:b9b85890c400 +| | +| o 2:aef17e88f5f0 +| | +| o 1:d3a0a68be6de +|/ +o 0:eff892de26ec + + runcommand phase -p . + runcommand phase . +5: public +saved backup bundle to $TESTTMP/.hg/strip-backup/d3a0a68be6de-backup.hg + runcommand branches +default 1:731265503d86