mirror of
https://github.com/facebook/sapling.git
synced 2024-10-09 16:31:02 +03:00
treemanifest: write trees during local commits
Summary: This makes local commits get written to trees (as well as flat manifest) when a commit happens where the parent commit has a tree manifest already. During a transaction where multiple trees are written (like when rebasing multiple nodes), we reuse the same pack file for all the trees produced by tieing into the transaction abort and close hooks. Test Plan: Ran the tests. Ran hg commit with the extension enabled. A future patch will add an integration test for the treemanifest extension. Reviewers: #mercurial, quark Reviewed By: quark Subscribers: mjpieters Differential Revision: https://phabricator.intern.facebook.com/D4055851 Signature: t1:4055851:1477059659:91b1c2f93ef986e910cea752ebf2466cb20ac921
This commit is contained in:
parent
8bc51e248b
commit
e63b8ce924
@ -11,7 +11,7 @@ import os
|
||||
import time
|
||||
import heapq
|
||||
|
||||
from mercurial import manifest, mdiff, revlog, util
|
||||
from mercurial import manifest, mdiff, revlog, scmutil, util
|
||||
import cachemanager
|
||||
import cfastmanifest
|
||||
from metrics import metricscollector
|
||||
@ -19,6 +19,8 @@ from constants import *
|
||||
|
||||
try:
|
||||
import ctreemanifest
|
||||
import treemanifest
|
||||
from remotefilelog import datapack, shallowutil
|
||||
supportsctree = True
|
||||
except ImportError:
|
||||
supportsctree = False
|
||||
@ -812,10 +814,48 @@ class manifestfactory(object):
|
||||
fastcache.put_inmemory(hexnode, cachedmf)
|
||||
|
||||
self.ui.debug("[FM] wrote manifest %s\n" % (hexnode,))
|
||||
|
||||
return node
|
||||
else:
|
||||
return orig(*args, **kwargs)
|
||||
node = orig(*args, **kwargs)
|
||||
|
||||
if (supportsctree and
|
||||
self.ui.configbool("fastmanifest", "usetree", False)):
|
||||
tree = origself.read(p1)._treemanifest()
|
||||
if tree:
|
||||
newtree = tree.copy()
|
||||
for filename in removed:
|
||||
del newtree[filename]
|
||||
|
||||
for filename in added:
|
||||
fnode = m[filename]
|
||||
fflag = m.flags(filename)
|
||||
newtree.set(filename, fnode, fflag)
|
||||
|
||||
if not util.safehasattr(transaction, 'treepack'):
|
||||
packpath = shallowutil.getlocalpackpath(
|
||||
origself.opener.vfs.base,
|
||||
'manifests')
|
||||
opener = scmutil.vfs(packpath)
|
||||
transaction.treepack = datapack.mutabledatapack(
|
||||
self.ui,
|
||||
opener)
|
||||
def postclose(tr):
|
||||
tr.treepack.close()
|
||||
treemanifestcache.getinstance(origself.opener,
|
||||
self.ui).clear()
|
||||
origself.opener.manifestdatastore.markforrefresh()
|
||||
def abort(tr):
|
||||
tr.treepack.abort()
|
||||
transaction.addpostclose('treepack', postclose)
|
||||
transaction.addabort('treepack', abort)
|
||||
|
||||
pack = treemanifest.InterceptedMutablePack(
|
||||
transaction.treepack,
|
||||
node)
|
||||
newtree.write(pack, tree)
|
||||
|
||||
treemanifestcache.getinstance(opener, self.ui)[node] = newtree
|
||||
|
||||
return node
|
||||
|
||||
def _silent_debug(*args, **kwargs):
|
||||
"""Replacement for ui.debug that silently swallows the arguments.
|
||||
|
@ -71,6 +71,10 @@ def _unpackmanifests(orig, self, repo, *args, **kwargs):
|
||||
repo.svfs.manifestdatastore.markforrefresh()
|
||||
|
||||
class InterceptedMutablePack(object):
|
||||
"""This classes intercepts pack writes and replaces the node for the root
|
||||
with the provided node. This is useful for forcing a tree manifest to be
|
||||
referencable via its flat hash.
|
||||
"""
|
||||
def __init__(self, pack, node):
|
||||
self._pack = pack
|
||||
self._node = node
|
||||
|
Loading…
Reference in New Issue
Block a user