hgext/git/manifest.py
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Mon, 01 Jun 2020 09:49:47 -0400
changeset 44971 47ce28a78f4a
parent 44970 3679c88b7f4e
child 44972 f294b4e14fd0
permissions -rw-r--r--
git: properly visit child tree objects when resolving a path
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
44489
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     1
from __future__ import absolute_import
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     2
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     3
from mercurial import (
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     4
    match as matchmod,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     5
    pathutil,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     6
    pycompat,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     7
    util,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     8
)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
     9
from mercurial.interfaces import (
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    10
    repository,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    11
    util as interfaceutil,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    12
)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    13
from . import gitutil
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    14
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    15
44496
ec54b3d2af0b git: don't fail import when pygit2 is not install
Martin von Zweigbergk <martinvonz@google.com>
parents: 44491
diff changeset
    16
pygit2 = gitutil.get_pygit2()
ec54b3d2af0b git: don't fail import when pygit2 is not install
Martin von Zweigbergk <martinvonz@google.com>
parents: 44491
diff changeset
    17
ec54b3d2af0b git: don't fail import when pygit2 is not install
Martin von Zweigbergk <martinvonz@google.com>
parents: 44491
diff changeset
    18
44489
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    19
@interfaceutil.implementer(repository.imanifestdict)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    20
class gittreemanifest(object):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    21
    """Expose git trees (and optionally a builder's overlay) as a manifestdict.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    22
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    23
    Very similar to mercurial.manifest.treemanifest.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    24
    """
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    25
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    26
    def __init__(self, git_repo, root_tree, pending_changes):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    27
        """Initializer.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    28
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    29
        Args:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    30
          git_repo: The git_repo we're walking (required to look up child
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    31
              trees).
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    32
          root_tree: The root Git tree object for this manifest.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    33
          pending_changes: A dict in which pending changes will be
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    34
              tracked. The enclosing memgittreemanifestctx will use this to
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    35
              construct any required Tree objects in Git during it's
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    36
              `write()` method.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    37
        """
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    38
        self._git_repo = git_repo
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    39
        self._tree = root_tree
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    40
        if pending_changes is None:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    41
            pending_changes = {}
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    42
        # dict of path: Optional[Tuple(node, flags)]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    43
        self._pending_changes = pending_changes
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    44
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    45
    def _resolve_entry(self, path):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    46
        """Given a path, load its node and flags, or raise KeyError if missing.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    47
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    48
        This takes into account any pending writes in the builder.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    49
        """
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    50
        upath = pycompat.fsdecode(path)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    51
        ent = None
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    52
        if path in self._pending_changes:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    53
            val = self._pending_changes[path]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    54
            if val is None:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    55
                raise KeyError
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    56
            return val
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    57
        t = self._tree
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    58
        comps = upath.split('/')
44971
47ce28a78f4a git: properly visit child tree objects when resolving a path
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44970
diff changeset
    59
        te = self._tree
44489
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    60
        for comp in comps[:-1]:
44971
47ce28a78f4a git: properly visit child tree objects when resolving a path
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44970
diff changeset
    61
            te = te[comp]
44489
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    62
            t = self._git_repo[te.id]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    63
        ent = t[comps[-1]]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    64
        if ent.filemode == pygit2.GIT_FILEMODE_BLOB:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    65
            flags = b''
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    66
        elif ent.filemode == pygit2.GIT_FILEMODE_BLOB_EXECUTABLE:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    67
            flags = b'x'
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    68
        elif ent.filemode == pygit2.GIT_FILEMODE_LINK:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    69
            flags = b'l'
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    70
        else:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    71
            raise ValueError('unsupported mode %s' % oct(ent.filemode))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    72
        return ent.id.raw, flags
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    73
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    74
    def __getitem__(self, path):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    75
        return self._resolve_entry(path)[0]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    76
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    77
    def find(self, path):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    78
        return self._resolve_entry(path)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    79
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    80
    def __len__(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    81
        return len(list(self.walk(matchmod.always())))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    82
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    83
    def __nonzero__(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    84
        try:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    85
            next(iter(self))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    86
            return True
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    87
        except StopIteration:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    88
            return False
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    89
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    90
    __bool__ = __nonzero__
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    91
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    92
    def __contains__(self, path):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    93
        try:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    94
            self._resolve_entry(path)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    95
            return True
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    96
        except KeyError:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    97
            return False
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    98
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
    99
    def iterkeys(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   100
        return self.walk(matchmod.always())
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   101
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   102
    def keys(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   103
        return list(self.iterkeys())
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   104
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   105
    def __iter__(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   106
        return self.iterkeys()
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   107
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   108
    def __setitem__(self, path, node):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   109
        self._pending_changes[path] = node, self.flags(path)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   110
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   111
    def __delitem__(self, path):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   112
        # TODO: should probably KeyError for already-deleted  files?
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   113
        self._pending_changes[path] = None
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   114
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   115
    def filesnotin(self, other, match=None):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   116
        if match is not None:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   117
            match = matchmod.badmatch(match, lambda path, msg: None)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   118
            sm2 = set(other.walk(match))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   119
            return {f for f in self.walk(match) if f not in sm2}
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   120
        return {f for f in self if f not in other}
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   121
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   122
    @util.propertycache
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   123
    def _dirs(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   124
        return pathutil.dirs(self)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   125
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   126
    def hasdir(self, dir):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   127
        return dir in self._dirs
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   128
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   129
    def diff(self, other, match=None, clean=False):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   130
        # TODO
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   131
        assert False
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   132
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   133
    def setflag(self, path, flag):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   134
        node, unused_flag = self._resolve_entry(path)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   135
        self._pending_changes[path] = node, flag
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   136
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   137
    def get(self, path, default=None):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   138
        try:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   139
            return self._resolve_entry(path)[0]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   140
        except KeyError:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   141
            return default
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   142
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   143
    def flags(self, path):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   144
        try:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   145
            return self._resolve_entry(path)[1]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   146
        except KeyError:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   147
            return b''
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   148
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   149
    def copy(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   150
        pass
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   151
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   152
    def items(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   153
        for f in self:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   154
            # TODO: build a proper iterator version of this
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   155
            yield self[f]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   156
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   157
    def iteritems(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   158
        return self.items()
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   159
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   160
    def iterentries(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   161
        for f in self:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   162
            # TODO: build a proper iterator version of this
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   163
            yield self._resolve_entry(f)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   164
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   165
    def text(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   166
        assert False  # TODO can this method move out of the manifest iface?
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   167
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   168
    def _walkonetree(self, tree, match, subdir):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   169
        for te in tree:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   170
            # TODO: can we prune dir walks with the matcher?
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   171
            realname = subdir + pycompat.fsencode(te.name)
44969
935c9f347bdb git: correctly check for type of object when walking
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44902
diff changeset
   172
            if te.type == pygit2.GIT_OBJ_TREE:
44489
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   173
                for inner in self._walkonetree(
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   174
                    self._git_repo[te.id], match, realname + b'/'
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   175
                ):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   176
                    yield inner
44970
3679c88b7f4e git: don't yield paths for directories when walking
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44969
diff changeset
   177
            elif match(realname):
3679c88b7f4e git: don't yield paths for directories when walking
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44969
diff changeset
   178
                yield pycompat.fsencode(realname)
44489
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   179
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   180
    def walk(self, match):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   181
        # TODO: this is a very lazy way to merge in the pending
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   182
        # changes. There is absolutely room for optimization here by
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   183
        # being clever about walking over the sets...
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   184
        baseline = set(self._walkonetree(self._tree, match, b''))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   185
        deleted = {p for p, v in self._pending_changes.items() if v is None}
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   186
        pend = {p for p in self._pending_changes if match(p)}
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   187
        return iter(sorted((baseline | pend) - deleted))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   188
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   189
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   190
@interfaceutil.implementer(repository.imanifestrevisionstored)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   191
class gittreemanifestctx(object):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   192
    def __init__(self, repo, gittree):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   193
        self._repo = repo
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   194
        self._tree = gittree
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   195
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   196
    def read(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   197
        return gittreemanifest(self._repo, self._tree, None)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   198
44491
7518ea76eff4 git: add readfast() method to manifest
Augie Fackler <raf@durin42.com>
parents: 44489
diff changeset
   199
    def readfast(self, shallow=False):
7518ea76eff4 git: add readfast() method to manifest
Augie Fackler <raf@durin42.com>
parents: 44489
diff changeset
   200
        return self.read()
7518ea76eff4 git: add readfast() method to manifest
Augie Fackler <raf@durin42.com>
parents: 44489
diff changeset
   201
44489
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   202
    def copy(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   203
        # NB: it's important that we return a memgittreemanifestctx
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   204
        # because the caller expects a mutable manifest.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   205
        return memgittreemanifestctx(self._repo, self._tree)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   206
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   207
    def find(self, path):
44902
288328c6711b git: fix probable missing return
Romain DEP. <rom1dep@gmail.com>
parents: 44629
diff changeset
   208
        return self.read()[path]
44489
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   209
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   210
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   211
@interfaceutil.implementer(repository.imanifestrevisionwritable)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   212
class memgittreemanifestctx(object):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   213
    def __init__(self, repo, tree):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   214
        self._repo = repo
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   215
        self._tree = tree
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   216
        # dict of path: Optional[Tuple(node, flags)]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   217
        self._pending_changes = {}
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   218
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   219
    def read(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   220
        return gittreemanifest(self._repo, self._tree, self._pending_changes)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   221
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   222
    def copy(self):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   223
        # TODO: if we have a builder in play, what should happen here?
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   224
        # Maybe we can shuffle copy() into the immutable interface.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   225
        return memgittreemanifestctx(self._repo, self._tree)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   226
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   227
    def write(self, transaction, link, p1, p2, added, removed, match=None):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   228
        # We're not (for now, anyway) going to audit filenames, so we
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   229
        # can ignore added and removed.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   230
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   231
        # TODO what does this match argument get used for? hopefully
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   232
        # just narrow?
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   233
        assert not match or isinstance(match, matchmod.alwaysmatcher)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   234
44629
e9e7156a8d6c git: pass a list to pathutil.dirs to indicate that it is a manifest
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 44496
diff changeset
   235
        touched_dirs = pathutil.dirs(list(self._pending_changes))
44489
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   236
        trees = {
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   237
            b'': self._tree,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   238
        }
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   239
        # path: treebuilder
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   240
        builders = {
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   241
            b'': self._repo.TreeBuilder(self._tree),
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   242
        }
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   243
        # get a TreeBuilder for every tree in the touched_dirs set
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   244
        for d in sorted(touched_dirs, key=lambda x: (len(x), x)):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   245
            if d == b'':
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   246
                # loaded root tree above
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   247
                continue
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   248
            comps = d.split(b'/')
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   249
            full = b''
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   250
            for part in comps:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   251
                parent = trees[full]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   252
                try:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   253
                    new = self._repo[parent[pycompat.fsdecode(part)]]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   254
                except KeyError:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   255
                    # new directory
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   256
                    new = None
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   257
                full += b'/' + part
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   258
                if new is not None:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   259
                    # existing directory
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   260
                    trees[full] = new
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   261
                    builders[full] = self._repo.TreeBuilder(new)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   262
                else:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   263
                    # new directory, use an empty dict to easily
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   264
                    # generate KeyError as any nested new dirs get
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   265
                    # created.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   266
                    trees[full] = {}
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   267
                    builders[full] = self._repo.TreeBuilder()
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   268
        for f, info in self._pending_changes.items():
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   269
            if b'/' not in f:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   270
                dirname = b''
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   271
                basename = f
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   272
            else:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   273
                dirname, basename = f.rsplit(b'/', 1)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   274
                dirname = b'/' + dirname
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   275
            if info is None:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   276
                builders[dirname].remove(pycompat.fsdecode(basename))
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   277
            else:
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   278
                n, fl = info
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   279
                mode = {
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   280
                    b'': pygit2.GIT_FILEMODE_BLOB,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   281
                    b'x': pygit2.GIT_FILEMODE_BLOB_EXECUTABLE,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   282
                    b'l': pygit2.GIT_FILEMODE_LINK,
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   283
                }[fl]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   284
                builders[dirname].insert(
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   285
                    pycompat.fsdecode(basename), gitutil.togitnode(n), mode
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   286
                )
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   287
        # This visits the buffered TreeBuilders in deepest-first
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   288
        # order, bubbling up the edits.
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   289
        for b in sorted(builders, key=len, reverse=True):
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   290
            if b == b'':
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   291
                break
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   292
            cb = builders[b]
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   293
            dn, bn = b.rsplit(b'/', 1)
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   294
            builders[dn].insert(
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   295
                pycompat.fsdecode(bn), cb.write(), pygit2.GIT_FILEMODE_TREE
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   296
            )
ad718271a9eb git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff changeset
   297
        return builders[b''].write().raw