Mercurial > hg
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 |