comparison hgext/git/manifest.py @ 44931:f294b4e14fd0

git: implement diff manifest method This makes 'hg diff' work.
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Mon, 01 Jun 2020 11:12:25 -0400
parents 47ce28a78f4a
children c8695439d7e3
comparison
equal deleted inserted replaced
44930:47ce28a78f4a 44931:f294b4e14fd0
124 return pathutil.dirs(self) 124 return pathutil.dirs(self)
125 125
126 def hasdir(self, dir): 126 def hasdir(self, dir):
127 return dir in self._dirs 127 return dir in self._dirs
128 128
129 def diff(self, other, match=None, clean=False): 129 def diff(self, other, match=lambda x: True, clean=False):
130 # TODO 130 '''Finds changes between the current manifest and m2.
131 assert False 131
132 The result is returned as a dict with filename as key and
133 values of the form ((n1,fl1),(n2,fl2)), where n1/n2 is the
134 nodeid in the current/other manifest and fl1/fl2 is the flag
135 in the current/other manifest. Where the file does not exist,
136 the nodeid will be None and the flags will be the empty
137 string.
138 '''
139 result = {}
140
141 def _iterativediff(t1, t2, subdir):
142 """compares two trees and appends new tree nodes to examine to
143 the stack"""
144 if t1 is None:
145 t1 = {}
146 if t2 is None:
147 t2 = {}
148
149 for e1 in t1:
150 realname = subdir + pycompat.fsencode(e1.name)
151
152 if e1.type == pygit2.GIT_OBJ_TREE:
153 try:
154 e2 = t2[e1.name]
155 if e2.type != pygit2.GIT_OBJ_TREE:
156 e2 = None
157 except KeyError:
158 e2 = None
159
160 stack.append((realname + b'/', e1, e2))
161 else:
162 n1, fl1 = self.find(realname)
163
164 try:
165 e2 = t2[e1.name]
166 n2, fl2 = other.find(realname)
167 except KeyError:
168 e2 = None
169 n2, fl2 = (None, b'')
170
171 if e2 is not None and e2.type == pygit2.GIT_OBJ_TREE:
172 stack.append((realname + b'/', None, e2))
173
174 if not match(realname):
175 continue
176
177 if n1 != n2 or fl1 != fl2:
178 result[realname] = ((n1, fl1), (n2, fl2))
179 elif clean:
180 result[realname] = None
181
182 for e2 in t2:
183 if e2.name in t1:
184 continue
185
186 realname = subdir + pycompat.fsencode(e2.name)
187
188 if e2.type == pygit2.GIT_OBJ_TREE:
189 stack.append((realname + b'/', None, e2))
190 elif match(realname):
191 n2, fl2 = other.find(realname)
192 result[realname] = ((None, b''), (n2, fl2))
193
194 stack = []
195 _iterativediff(self._tree, other._tree, b'')
196 while stack:
197 subdir, t1, t2 = stack.pop()
198 # stack is populated in the function call
199 _iterativediff(t1, t2, subdir)
200
201 return result
132 202
133 def setflag(self, path, flag): 203 def setflag(self, path, flag):
134 node, unused_flag = self._resolve_entry(path) 204 node, unused_flag = self._resolve_entry(path)
135 self._pending_changes[path] = node, flag 205 self._pending_changes[path] = node, flag
136 206