[PATCH] convert: use pygit2 if available, to improve performance
Patrick Mézard
patrick at mezard.eu
Fri Apr 6 12:51:16 UTC 2012
Le 05/04/12 23:53, Bryan O'Sullivan a écrit :
> # HG changeset patch
> # User Bryan O'Sullivan <bryano at fb.com>
> # Date 1333662769 25200
> # Branch stable
> # Node ID d6a14f098965261ca2e1722d711bf9f7789ae3c2
> # Parent 4d875bb546dc03db33630f5388d7e04939c386a0
> convert: use pygit2 if available, to improve performance
>
> When converting a git repository, the main bottleneck is shelling out to
> git to retrieve data. This patch uses the pygit2 bindings to libgit2,
> if available, to avoid most callouts to git. Since the pygit2 bindings
> are currently incomplete, we still need to use git for some tasks.
>
> This patch requires version 0.16.1 or newer of pygit2. If pygit2
> is not available or too old, we transparently fall back to invoking
> git directly.
>
> diff -r 4d875bb546dc -r d6a14f098965 hgext/convert/git.py
> --- a/hgext/convert/git.py Tue Apr 03 22:01:28 2012 +0200
> +++ b/hgext/convert/git.py Thu Apr 05 14:52:49 2012 -0700
> @@ -12,7 +12,22 @@
>
> from common import NoRepo, commit, converter_source, checktool
>
> -class convert_git(converter_source):
> +class convert_git_base(converter_source):
FWIW, we are trying to move away from names with underscores.
[...]
> +
> +def hexoid(obj):
> + # pygit2's "hex" property is unicode, but "oid" is str
> + return obj.oid.encode('hex')
> +
> +class nopygit2(Exception):
> + pass
Maybe s/nopygit2/NoPyGit2/
> +class convert_git_pygit2(convert_git_base):
> + def __init__(self, ui, path, rev):
> + super(convert_git_pygit2, self).__init__(ui, path, rev=rev)
> + try:
> + # check for pygit2 0.16.1 or newer
> + import pygit2
> + pygit2.Commit._message
> + except (AttributeError, ImportError):
> + raise nopygit2
> + self.repo = pygit2.init_repository(path, True)
> +
> + def getheads(self):
> + if not self.rev:
> + return [hexoid(self.repo.lookup_reference(r).resolve())
> + for r in self.repo.listall_references()
> + if (r.startswith('refs/heads/') or
> + r.startswith('refs/remotes/'))]
> + else:
> + try:
> + return [hexoid(repo.lookup_reference(self.rev).resolve())]
> + except KeyError:
> + return [hexoid(repo[self.rev])]
> +
> + def getcommit(self, rev):
> + def prettyname(sig):
> + if sig._name:
> + return '%s <%s>' % (sig._name, sig._email)
> + return sig._email
> +
> + c = self.repo[rev.decode('hex')]
> + message = c._message
> + author = prettyname(c.author)
> + committer = prettyname(c.committer)
> + if author != committer:
> + message += '\ncommitter: %s\n' % committer
> + return commit(parents=[hexoid(p) for p in c.parents],
> + date='%s %s' % (c.commit_time, c.commit_time_offset),
Looks like c.commit_time_offset is in minutes and we want it backward:
date='%s %s' % (c.commit_time, -c.commit_time_offset*60),
> + author=author, desc=self.recode(message), rev=rev)
> +
[...]
> -
> def getbookmarks(self):
> bookmarks = {}
>
> @@ -205,3 +268,9 @@
> pass
>
> return bookmarks
The bookmarks stuff was not implemented in convert_git_pygit2, should it be left in convert_git_base?
> +
> +def convert_git(ui, path, rev=None):
> + try:
> + return convert_git_pygit2(ui, path, rev)
> + except nopygit2:
> + return convert_git_plain(ui, path, rev)
--
Patrick Mézard
More information about the Mercurial-devel
mailing list