##// END OF EJS Templates
git: skeleton of a new extension to _directly_ operate on git repos...
git: skeleton of a new extension to _directly_ operate on git repos This is based in part of work I did years ago in hgit, but it's mostly new code since I'm using pygit2 instead of dulwich and the hg storage interfaces have improved. Some cleanup of old hgit code by Pulkit, which I greatly appreciate. test-git-interop.t does not cover a whole lot of cases, but it passes. It includes status, diff, making a new commit, and `hg annotate` working on the git repository. This is _not_ (yet) production quality code: this is an experiment. Known technical debt lurking in this implementation: * Writing bookmarks just totally ignores transactions. * The way progress is threaded down into the gitstore is awful. * Ideally we'd find a way to incrementally reindex DAGs. I'm not sure how to do that efficiently, so we might need a "known only fast-forwards" mode on the DAG indexer for use on `hg commit` and friends. * We don't even _try_ to do anything reasonable for `hg pull` or `hg push`. * Mercurial need an interface for the changelog type. Tests currently require git 2.24 as far as I'm aware: `git status` has some changed output that I didn't try and handle in a compatible way. This patch has produced some interesting cleanups, most recently on the manifest type. I expect continuing down this road will produce other meritorious cleanups throughout our code. Differential Revision: https://phab.mercurial-scm.org/D6734

File last commit:

r44441:de358da7 default
r44961:ad718271 default
Show More
support.py
137 lines | 4.1 KiB | text/x-python | PythonLexer
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 # Copyright 2016-present Facebook. All Rights Reserved.
#
# support: fastannotate support for hgweb, and filectx
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
Gregory Szorc
py3: manually import getattr where it is needed...
r43359 from mercurial.pycompat import getattr
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 from mercurial import (
context as hgcontext,
dagop,
extensions,
hgweb,
patch,
util,
)
from . import (
context,
revmap,
)
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 class _lazyfctx(object):
"""delegates to fctx but do not construct fctx when unnecessary"""
def __init__(self, repo, node, path):
self._node = node
self._path = path
self._repo = repo
def node(self):
return self._node
def path(self):
return self._path
@util.propertycache
def _fctx(self):
return context.resolvefctx(self._repo, self._node, self._path)
def __getattr__(self, name):
return getattr(self._fctx, name)
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 def _convertoutputs(repo, annotated, contents):
"""convert fastannotate outputs to vanilla annotate format"""
# fastannotate returns: [(nodeid, linenum, path)], [linecontent]
# convert to what fctx.annotate returns: [annotateline]
results = []
fctxmap = {}
annotateline = dagop.annotateline
for i, (hsh, linenum, path) in enumerate(annotated):
if (hsh, path) not in fctxmap:
fctxmap[(hsh, path)] = _lazyfctx(repo, hsh, path)
# linenum: the user wants 1-based, we have 0-based.
lineno = linenum + 1
fctx = fctxmap[(hsh, path)]
line = contents[i]
results.append(annotateline(fctx=fctx, lineno=lineno, text=line))
return results
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 def _getmaster(fctx):
"""(fctx) -> str"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return fctx._repo.ui.config(b'fastannotate', b'mainbranch') or b'default'
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 def _doannotate(fctx, follow=True, diffopts=None):
"""like the vanilla fctx.annotate, but do it via fastannotate, and make
the output format compatible with the vanilla fctx.annotate.
may raise Exception, and always return line numbers.
"""
master = _getmaster(fctx)
with context.fctxannotatecontext(fctx, follow, diffopts) as ac:
try:
Augie Fackler
formatting: blacken the codebase...
r43346 annotated, contents = ac.annotate(
fctx.rev(), master=master, showpath=True, showlines=True
)
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 except Exception:
Augie Fackler
formatting: blacken the codebase...
r43346 ac.rebuild() # try rebuild once
fctx._repo.ui.debug(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'fastannotate: %s: rebuilding broken cache\n' % fctx._path
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 try:
Augie Fackler
formatting: blacken the codebase...
r43346 annotated, contents = ac.annotate(
fctx.rev(), master=master, showpath=True, showlines=True
)
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 except Exception:
raise
assert annotated and contents
return _convertoutputs(fctx._repo, annotated, contents)
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 def _hgwebannotate(orig, fctx, ui):
Augie Fackler
formatting: blacken the codebase...
r43346 diffopts = patch.difffeatureopts(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui, untrusted=True, section=b'annotate', whitespace=True
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 return _doannotate(fctx, diffopts=diffopts)
Augie Fackler
formatting: blacken the codebase...
r43346
def _fctxannotate(
orig, self, follow=False, linenumber=False, skiprevs=None, diffopts=None
):
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 if skiprevs:
# skiprevs is not supported yet
Augie Fackler
formatting: blacken the codebase...
r43346 return orig(
self, follow, linenumber, skiprevs=skiprevs, diffopts=diffopts
)
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 try:
return _doannotate(self, follow, diffopts)
except Exception as ex:
Augie Fackler
formatting: blacken the codebase...
r43346 self._repo.ui.debug(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 b'fastannotate: falling back to the vanilla annotate: %r\n' % ex
Augie Fackler
formatting: blacken the codebase...
r43346 )
return orig(self, follow=follow, skiprevs=skiprevs, diffopts=diffopts)
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243
def _remotefctxannotate(orig, self, follow=False, skiprevs=None, diffopts=None):
# skipset: a set-like used to test if a fctx needs to be downloaded
with context.fctxannotatecontext(self, follow, diffopts) as ac:
skipset = revmap.revmap(ac.revmappath)
Augie Fackler
formatting: blacken the codebase...
r43346 return orig(
self, follow, skiprevs=skiprevs, diffopts=diffopts, prefetchskip=skipset
)
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243
def replacehgwebannotate():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extensions.wrapfunction(hgweb.webutil, b'annotate', _hgwebannotate)
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
fastannotate: initial import from Facebook's hg-experimental...
r39243 def replacefctxannotate():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extensions.wrapfunction(hgcontext.basefilectx, b'annotate', _fctxannotate)