152 ).fetchone() |
152 ).fetchone() |
153 if t is None: |
153 if t is None: |
154 raise error.LookupError(r, b'00changelog.i', _(b'no node')) |
154 raise error.LookupError(r, b'00changelog.i', _(b'no node')) |
155 return bin(t[0]) |
155 return bin(t[0]) |
156 |
156 |
|
157 def synthetic(self, n): |
|
158 """Map any node to a non-synthetic node. |
|
159 |
|
160 Indexing may have created synthetic nodes to handle octopus merges. |
|
161 Certain operations on these made up nodes need to actually happen on |
|
162 the real octopus merge commit. Given any node, this function |
|
163 returns the real commit hash. One can think of this as hg-to-git |
|
164 commit hash translation that always works.""" |
|
165 t = self._db.execute( |
|
166 'SELECT synthetic FROM changelog WHERE node = ?', |
|
167 (gitutil.togitnode(n),), |
|
168 ).fetchone() |
|
169 if t is None or t[0] is None: |
|
170 return n |
|
171 return bin(t[0]) |
|
172 |
157 def hasnode(self, n): |
173 def hasnode(self, n): |
158 t = self._db.execute( |
174 t = self._db.execute( |
159 'SELECT node FROM changelog WHERE node = ?', |
175 'SELECT node FROM changelog WHERE node = ?', |
160 (pycompat.sysstr(n),), |
176 (pycompat.sysstr(n),), |
161 ).fetchone() |
177 ).fetchone() |
319 # handle looking up nullid |
335 # handle looking up nullid |
320 if n == sha1nodeconstants.nullid: |
336 if n == sha1nodeconstants.nullid: |
321 return hgchangelog._changelogrevision( |
337 return hgchangelog._changelogrevision( |
322 extra=extra, manifest=sha1nodeconstants.nullid |
338 extra=extra, manifest=sha1nodeconstants.nullid |
323 ) |
339 ) |
|
340 n = self.synthetic(n) |
324 hn = gitutil.togitnode(n) |
341 hn = gitutil.togitnode(n) |
325 # We've got a real commit! |
342 # We've got a real commit! |
326 files = [ |
343 files = [ |
327 r[0] |
344 r[0] |
328 for r in self._db.execute( |
345 for r in self._db.execute( |
464 elif a > b: |
481 elif a > b: |
465 return False |
482 return False |
466 return bool(self.reachableroots(a, [b], [a], includepath=False)) |
483 return bool(self.reachableroots(a, [b], [a], includepath=False)) |
467 |
484 |
468 def parentrevs(self, rev): |
485 def parentrevs(self, rev): |
469 n = self.node(rev) |
486 assert rev >= 0, rev |
470 hn = gitutil.togitnode(n) |
487 t = self._db.execute( |
471 if hn != gitutil.nullgit: |
488 'SELECT p1, p2 FROM changelog WHERE rev = ?', (rev,) |
472 c = self.gitrepo[hn] |
489 ).fetchone() |
473 else: |
490 if t is None: |
474 return nullrev, nullrev |
491 raise error.LookupError(rev, b'00changelog.i', _(b'no rev')) |
475 p1 = p2 = nullrev |
492 return self.rev(bin(t[0])), self.rev(bin(t[1])) |
476 if c.parents: |
|
477 p1 = self.rev(c.parents[0].id.raw) |
|
478 if len(c.parents) > 2: |
|
479 raise error.Abort(b'TODO octopus merge handling') |
|
480 if len(c.parents) == 2: |
|
481 p2 = self.rev(c.parents[1].id.raw) |
|
482 return p1, p2 |
|
483 |
493 |
484 # Private method is used at least by the tags code. |
494 # Private method is used at least by the tags code. |
485 _uncheckedparentrevs = parentrevs |
495 _uncheckedparentrevs = parentrevs |
486 |
496 |
487 def commonancestorsheads(self, a, b): |
497 def commonancestorsheads(self, a, b): |
556 |
566 |
557 def get(self, relpath, node): |
567 def get(self, relpath, node): |
558 if node == sha1nodeconstants.nullid: |
568 if node == sha1nodeconstants.nullid: |
559 # TODO: this should almost certainly be a memgittreemanifestctx |
569 # TODO: this should almost certainly be a memgittreemanifestctx |
560 return manifest.memtreemanifestctx(self, relpath) |
570 return manifest.memtreemanifestctx(self, relpath) |
|
571 node = self.synthetic(node) |
561 commit = self.gitrepo[gitutil.togitnode(node)] |
572 commit = self.gitrepo[gitutil.togitnode(node)] |
562 t = commit.tree |
573 t = commit.tree |
563 if relpath: |
574 if relpath: |
564 parts = relpath.split(b'/') |
575 parts = relpath.split(b'/') |
565 for p in parts: |
576 for p in parts: |