diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -408,7 +408,6 @@ coreconfigitem( # TODO before getting `persistent-nodemap` out of experimental # # * code/tests around aborted transaction -# * code/tests around pending data for hooks # * regenerate a new nodemap when the unused/total ration is to high # * decide for a "status" of the persistent nodemap and associated location # - part of the store next the revlog itself (new requirements) diff --git a/mercurial/revlog.py b/mercurial/revlog.py --- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -436,7 +436,14 @@ class revlog(object): self.datafile = datafile or (indexfile[:-2] + b".d") self.nodemap_file = None if persistentnodemap: - self.nodemap_file = indexfile[:-2] + b".n" + if indexfile.endswith(b'.a'): + pending_path = indexfile[:-4] + b".n.a" + if opener.exists(pending_path): + self.nodemap_file = pending_path + else: + self.nodemap_file = indexfile[:-4] + b".n" + else: + self.nodemap_file = indexfile[:-2] + b".n" self.opener = opener # When True, indexfile is opened with checkambig=True at writing, to diff --git a/mercurial/revlogutils/nodemap.py b/mercurial/revlogutils/nodemap.py --- a/mercurial/revlogutils/nodemap.py +++ b/mercurial/revlogutils/nodemap.py @@ -75,6 +75,9 @@ def setup_persistent_nodemap(tr, revlog) callback_id = b"revlog-persistent-nodemap-%s" % revlog.nodemap_file if tr.hasfinalize(callback_id): return # no need to register again + tr.addpending( + callback_id, lambda tr: _persist_nodemap(tr, revlog, pending=True) + ) tr.addfinalize(callback_id, lambda tr: _persist_nodemap(tr, revlog)) @@ -101,7 +104,7 @@ def update_persistent_nodemap(revlog): notr._postclose[k](None) -def _persist_nodemap(tr, revlog): +def _persist_nodemap(tr, revlog, pending=False): """Write nodemap data on disk for a given revlog """ if getattr(revlog, 'filteredrevs', ()): @@ -169,7 +172,10 @@ def _persist_nodemap(tr, revlog): target_docket.tip_node = revlog.node(target_docket.tip_rev) # EXP-TODO: if this is a cache, this should use a cache vfs, not a # store vfs - with revlog.opener(revlog.nodemap_file, b'w', atomictemp=True) as fp: + file_path = revlog.nodemap_file + if pending: + file_path += b'.a' + with revlog.opener(file_path, b'w', atomictemp=True) as fp: fp.write(target_docket.serialize()) revlog._nodemap_docket = target_docket if feed_data: @@ -304,7 +310,10 @@ class NodeMapDocket(object): def _rawdata_filepath(revlog, docket): """The (vfs relative) nodemap's rawdata file for a given uid""" - prefix = revlog.nodemap_file[:-2] + if revlog.nodemap_file.endswith(b'.n.a'): + prefix = revlog.nodemap_file[:-4] + else: + prefix = revlog.nodemap_file[:-2] return b"%s-%s.nd" % (prefix, docket.uid) diff --git a/tests/test-persistent-nodemap.t b/tests/test-persistent-nodemap.t --- a/tests/test-persistent-nodemap.t +++ b/tests/test-persistent-nodemap.t @@ -281,3 +281,39 @@ the nodemap should detect the changelog data-unused: 0 $ hg log -r "$OTHERNODE" -T '{rev}\n' 5002 + +Check transaction related property +================================== + +An up to date nodemap should be available to shell hooks, + + $ echo dsljfl > a + $ hg add a + $ hg ci -m a + $ hg debugnodemap --metadata + uid: ???????????????? (glob) + tip-rev: 5003 + tip-node: c91af76d172f1053cca41b83f7c2e4e514fe2bcf + data-length: 123008 + data-unused: 0 + $ echo babar2 > babar + $ hg ci -m 'babar2' --config "hooks.pretxnclose.nodemap-test=hg debugnodemap --metadata" + uid: ???????????????? (glob) + tip-rev: 5004 + tip-node: ba87cd9559559e4b91b28cb140d003985315e031 + data-length: 123328 (pure !) + data-length: 123328 (rust !) + data-length: 123136 (no-pure no-rust !) + data-unused: 192 (pure !) + data-unused: 192 (rust !) + data-unused: 0 (no-pure no-rust !) + $ hg debugnodemap --metadata + uid: ???????????????? (glob) + tip-rev: 5004 + tip-node: ba87cd9559559e4b91b28cb140d003985315e031 + data-length: 123328 (pure !) + data-length: 123328 (rust !) + data-length: 123136 (no-pure no-rust !) + data-unused: 192 (pure !) + data-unused: 192 (rust !) + data-unused: 0 (no-pure no-rust !)