Mercurial > hg
annotate hgext/git/manifest.py @ 45051:93e8e6e0b5fb
heptapod-ci: build rhg before tests run
Differential Revision: https://phab.mercurial-scm.org/D8682
author | Antoine Cezar <antoine.cezar@octobus.net> |
---|---|
date | Mon, 06 Jul 2020 09:30:26 +0200 |
parents | f294b4e14fd0 |
children | c8695439d7e3 |
rev | line source |
---|---|
44477
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 |
44484
ec54b3d2af0b
git: don't fail import when pygit2 is not install
Martin von Zweigbergk <martinvonz@google.com>
parents:
44479
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:
44479
diff
changeset
|
17 |
ec54b3d2af0b
git: don't fail import when pygit2 is not install
Martin von Zweigbergk <martinvonz@google.com>
parents:
44479
diff
changeset
|
18 |
44477
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('/') |
44930
47ce28a78f4a
git: properly visit child tree objects when resolving a path
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44929
diff
changeset
|
59 te = self._tree |
44477
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]: |
44930
47ce28a78f4a
git: properly visit child tree objects when resolving a path
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44929
diff
changeset
|
61 te = te[comp] |
44477
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 |
44931
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
129 def diff(self, other, match=lambda x: True, clean=False): |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
130 '''Finds changes between the current manifest and m2. |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
131 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
132 The result is returned as a dict with filename as key and |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
133 values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
134 nodeid in the current/other manifest and fl1/fl2 is the flag |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
135 in the current/other manifest. Where the file does not exist, |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
136 the nodeid will be None and the flags will be the empty |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
137 string. |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
138 ''' |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
139 result = {} |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
140 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
141 def _iterativediff(t1, t2, subdir): |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
142 """compares two trees and appends new tree nodes to examine to |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
143 the stack""" |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
144 if t1 is None: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
145 t1 = {} |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
146 if t2 is None: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
147 t2 = {} |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
148 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
149 for e1 in t1: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
150 realname = subdir + pycompat.fsencode(e1.name) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
151 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
152 if e1.type == pygit2.GIT_OBJ_TREE: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
153 try: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
154 e2 = t2[e1.name] |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
155 if e2.type != pygit2.GIT_OBJ_TREE: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
156 e2 = None |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
157 except KeyError: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
158 e2 = None |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
159 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
160 stack.append((realname + b'/', e1, e2)) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
161 else: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
162 n1, fl1 = self.find(realname) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
163 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
164 try: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
165 e2 = t2[e1.name] |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
166 n2, fl2 = other.find(realname) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
167 except KeyError: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
168 e2 = None |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
169 n2, fl2 = (None, b'') |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
170 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
171 if e2 is not None and e2.type == pygit2.GIT_OBJ_TREE: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
172 stack.append((realname + b'/', None, e2)) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
173 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
174 if not match(realname): |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
175 continue |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
176 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
177 if n1 != n2 or fl1 != fl2: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
178 result[realname] = ((n1, fl1), (n2, fl2)) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
179 elif clean: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
180 result[realname] = None |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
181 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
182 for e2 in t2: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
183 if e2.name in t1: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
184 continue |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
185 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
186 realname = subdir + pycompat.fsencode(e2.name) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
187 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
188 if e2.type == pygit2.GIT_OBJ_TREE: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
189 stack.append((realname + b'/', None, e2)) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
190 elif match(realname): |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
191 n2, fl2 = other.find(realname) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
192 result[realname] = ((None, b''), (n2, fl2)) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
193 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
194 stack = [] |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
195 _iterativediff(self._tree, other._tree, b'') |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
196 while stack: |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
197 subdir, t1, t2 = stack.pop() |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
198 # stack is populated in the function call |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
199 _iterativediff(t1, t2, subdir) |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
200 |
f294b4e14fd0
git: implement diff manifest method
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44930
diff
changeset
|
201 return result |
44477
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
202 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
203 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
|
204 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
|
205 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
|
206 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
207 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
|
208 try: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
209 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
|
210 except KeyError: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
211 return default |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
212 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
213 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
|
214 try: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
215 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
|
216 except KeyError: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
217 return b'' |
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 copy(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
220 pass |
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 items(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
223 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
|
224 # 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
|
225 yield self[f] |
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 iteritems(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
228 return self.items() |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
229 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
230 def iterentries(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
231 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
|
232 # 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
|
233 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
|
234 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
235 def text(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
236 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
|
237 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
238 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
|
239 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
|
240 # 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
|
241 realname = subdir + pycompat.fsencode(te.name) |
44928
935c9f347bdb
git: correctly check for type of object when walking
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44843
diff
changeset
|
242 if te.type == pygit2.GIT_OBJ_TREE: |
44477
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
243 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
|
244 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
|
245 ): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
246 yield inner |
44929
3679c88b7f4e
git: don't yield paths for directories when walking
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44928
diff
changeset
|
247 elif match(realname): |
3679c88b7f4e
git: don't yield paths for directories when walking
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44928
diff
changeset
|
248 yield pycompat.fsencode(realname) |
44477
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
249 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
250 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
|
251 # 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
|
252 # 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
|
253 # 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
|
254 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
|
255 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
|
256 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
|
257 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
|
258 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
259 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
260 @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
|
261 class gittreemanifestctx(object): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
262 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
|
263 self._repo = repo |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
264 self._tree = gittree |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
265 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
266 def read(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
267 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
|
268 |
44479
7518ea76eff4
git: add readfast() method to manifest
Augie Fackler <raf@durin42.com>
parents:
44477
diff
changeset
|
269 def readfast(self, shallow=False): |
7518ea76eff4
git: add readfast() method to manifest
Augie Fackler <raf@durin42.com>
parents:
44477
diff
changeset
|
270 return self.read() |
7518ea76eff4
git: add readfast() method to manifest
Augie Fackler <raf@durin42.com>
parents:
44477
diff
changeset
|
271 |
44477
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
272 def copy(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
273 # 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
|
274 # 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
|
275 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
|
276 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
277 def find(self, path): |
44843
288328c6711b
git: fix probable missing return
Romain DEP. <rom1dep@gmail.com>
parents:
44625
diff
changeset
|
278 return self.read()[path] |
44477
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
279 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
280 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
281 @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
|
282 class memgittreemanifestctx(object): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
283 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
|
284 self._repo = repo |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
285 self._tree = tree |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
286 # 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
|
287 self._pending_changes = {} |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
288 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
289 def read(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
290 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
|
291 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
292 def copy(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
293 # 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
|
294 # 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
|
295 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
|
296 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
297 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
|
298 # 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
|
299 # 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
|
300 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
301 # 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
|
302 # just narrow? |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
303 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
|
304 |
44625
e9e7156a8d6c
git: pass a list to pathutil.dirs to indicate that it is a manifest
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44484
diff
changeset
|
305 touched_dirs = pathutil.dirs(list(self._pending_changes)) |
44477
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
306 trees = { |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
307 b'': self._tree, |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
308 } |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
309 # path: treebuilder |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
310 builders = { |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
311 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
|
312 } |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
313 # 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
|
314 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
|
315 if d == b'': |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
316 # 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
|
317 continue |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
318 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
|
319 full = b'' |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
320 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
|
321 parent = trees[full] |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
322 try: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
323 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
|
324 except KeyError: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
325 # new directory |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
326 new = None |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
327 full += b'/' + part |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
328 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
|
329 # existing directory |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
330 trees[full] = new |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
331 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
|
332 else: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
333 # 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
|
334 # 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
|
335 # created. |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
336 trees[full] = {} |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
337 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
|
338 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
|
339 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
|
340 dirname = b'' |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
341 basename = f |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
342 else: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
343 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
|
344 dirname = b'/' + dirname |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
345 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
|
346 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
|
347 else: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
348 n, fl = info |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
349 mode = { |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
350 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
|
351 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
|
352 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
|
353 }[fl] |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
354 builders[dirname].insert( |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
355 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
|
356 ) |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
357 # 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
|
358 # 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
|
359 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
|
360 if b == b'': |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
361 break |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
362 cb = builders[b] |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
363 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
|
364 builders[dn].insert( |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
365 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
|
366 ) |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
367 return builders[b''].write().raw |