Mercurial > hg
annotate hgext/git/manifest.py @ 45516:73a5aa5e1857
git: pass `id` attribute of `pygit2.Tree` object
`pygit2`'s Repository object expects an instance of `Oid`
to return the corresponding object, instead of the object
itself.
After this change and D9062, `hg commit -i` seems to work,
unless it hits a case folding assertion (ie trying to add
a file like `README.md`).
Differential Revision: https://phab.mercurial-scm.org/D9068
author | Connor Sheehan <sheehan@mozilla.com> |
---|---|
date | Tue, 22 Sep 2020 09:06:09 -0400 |
parents | c8695439d7e3 |
children | 89a2afe31e82 |
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): |
45417
c8695439d7e3
git: actually copy treemanifest instances in .copy() (issue6398)
Augie Fackler <raf@durin42.com>
parents:
44931
diff
changeset
|
220 return gittreemanifest( |
c8695439d7e3
git: actually copy treemanifest instances in .copy() (issue6398)
Augie Fackler <raf@durin42.com>
parents:
44931
diff
changeset
|
221 self._git_repo, self._tree, dict(self._pending_changes) |
c8695439d7e3
git: actually copy treemanifest instances in .copy() (issue6398)
Augie Fackler <raf@durin42.com>
parents:
44931
diff
changeset
|
222 ) |
44477
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
223 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
224 def items(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
225 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
|
226 # 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
|
227 yield self[f] |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
228 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
229 def iteritems(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
230 return self.items() |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
231 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
232 def iterentries(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
233 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
|
234 # 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
|
235 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
|
236 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
237 def text(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
238 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
|
239 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
240 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
|
241 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
|
242 # 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
|
243 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
|
244 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
|
245 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
|
246 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
|
247 ): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
248 yield inner |
44929
3679c88b7f4e
git: don't yield paths for directories when walking
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44928
diff
changeset
|
249 elif match(realname): |
3679c88b7f4e
git: don't yield paths for directories when walking
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
44928
diff
changeset
|
250 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
|
251 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
252 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
|
253 # 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
|
254 # 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
|
255 # 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
|
256 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
|
257 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
|
258 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
|
259 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
|
260 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
261 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
262 @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
|
263 class gittreemanifestctx(object): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
264 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
|
265 self._repo = repo |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
266 self._tree = gittree |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
267 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
268 def read(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
269 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
|
270 |
44479
7518ea76eff4
git: add readfast() method to manifest
Augie Fackler <raf@durin42.com>
parents:
44477
diff
changeset
|
271 def readfast(self, shallow=False): |
7518ea76eff4
git: add readfast() method to manifest
Augie Fackler <raf@durin42.com>
parents:
44477
diff
changeset
|
272 return self.read() |
7518ea76eff4
git: add readfast() method to manifest
Augie Fackler <raf@durin42.com>
parents:
44477
diff
changeset
|
273 |
44477
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
274 def copy(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
275 # 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
|
276 # 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
|
277 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
|
278 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
279 def find(self, path): |
44843
288328c6711b
git: fix probable missing return
Romain DEP. <rom1dep@gmail.com>
parents:
44625
diff
changeset
|
280 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
|
281 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
282 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
283 @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
|
284 class memgittreemanifestctx(object): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
285 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
|
286 self._repo = repo |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
287 self._tree = tree |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
288 # 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
|
289 self._pending_changes = {} |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
290 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
291 def read(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
292 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
|
293 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
294 def copy(self): |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
295 # 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
|
296 # 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
|
297 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
|
298 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
299 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
|
300 # 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
|
301 # 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
|
302 |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
303 # 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
|
304 # just narrow? |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
305 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
|
306 |
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
|
307 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
|
308 trees = { |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
309 b'': self._tree, |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
310 } |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
311 # path: treebuilder |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
312 builders = { |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
313 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
|
314 } |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
315 # 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
|
316 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
|
317 if d == b'': |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
318 # 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
|
319 continue |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
320 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
|
321 full = b'' |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
322 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
|
323 parent = trees[full] |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
324 try: |
45516
73a5aa5e1857
git: pass `id` attribute of `pygit2.Tree` object
Connor Sheehan <sheehan@mozilla.com>
parents:
45417
diff
changeset
|
325 parent_tree_id = parent[pycompat.fsdecode(part)].id |
73a5aa5e1857
git: pass `id` attribute of `pygit2.Tree` object
Connor Sheehan <sheehan@mozilla.com>
parents:
45417
diff
changeset
|
326 new = self._repo[parent_tree_id] |
44477
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
327 except KeyError: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
328 # new directory |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
329 new = None |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
330 full += b'/' + part |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
331 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
|
332 # existing directory |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
333 trees[full] = new |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
334 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
|
335 else: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
336 # 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
|
337 # 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
|
338 # created. |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
339 trees[full] = {} |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
340 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
|
341 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
|
342 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
|
343 dirname = b'' |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
344 basename = f |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
345 else: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
346 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
|
347 dirname = b'/' + dirname |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
348 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
|
349 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
|
350 else: |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
351 n, fl = info |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
352 mode = { |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
353 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
|
354 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
|
355 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
|
356 }[fl] |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
357 builders[dirname].insert( |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
358 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
|
359 ) |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
360 # 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
|
361 # 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
|
362 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
|
363 if b == b'': |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
364 break |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
365 cb = builders[b] |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
366 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
|
367 builders[dn].insert( |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
368 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
|
369 ) |
ad718271a9eb
git: skeleton of a new extension to _directly_ operate on git repos
Augie Fackler <augie@google.com>
parents:
diff
changeset
|
370 return builders[b''].write().raw |