diff --git a/eden/scm/edenscm/hgext/hggit/__init__.py b/eden/scm/edenscm/hgext/hggit/__init__.py index eb7871b8b0..8722be5d12 100644 --- a/eden/scm/edenscm/hgext/hggit/__init__.py +++ b/eden/scm/edenscm/hgext/hggit/__init__.py @@ -20,6 +20,7 @@ For more information and instructions, see :hg:`help git` # global modules import os import shutil +import sys import warnings from bisect import insort @@ -223,7 +224,11 @@ def getversion(): # defend against tracebacks if we specify -r in 'hg pull' def safebranchrevs(orig, lrepo, repo, branches, revs): revs, co = orig(lrepo, repo, branches, revs) - if hgutil.safehasattr(lrepo, "changelog") and co not in lrepo.changelog: + if ( + isinstance(co, int) + and hgutil.safehasattr(lrepo, "changelog") + and co not in lrepo.changelog + ): co = None return revs, co @@ -333,7 +338,7 @@ def git_cleanup(ui, repo): new_map = [] for gitsha, hgsha in items: if hgsha in repo: - new_map.append("%s %s\n" % (hex(gitsha), hex(hgsha))) + new_map.append(pycompat.encodeutf8("%s %s\n" % (hex(gitsha), hex(hgsha)))) wlock = repo.wlock() try: f = repo.sharedvfs(GitHandler.map_file, "wb") @@ -369,7 +374,7 @@ def gitupdatemeta(ui, repo): commitdata = clrevision(node) if ( commitdata._rawextra is not None - and "convert_revision" in commitdata._rawextra + and b"convert_revision" in commitdata._rawextra ): gitsha = commitdata.extra.get("convert_revision") @@ -416,8 +421,12 @@ def getremotechanges(orig, ui, repo, other, *args, **opts): revs = opts.get("onlyheads", opts.get("revs")) r, c, cleanup = repo.githandler.getremotechanges(other, revs) # ugh. This is ugly even by mercurial API compatibility standards - if "onlyheads" not in orig.func_code.co_varnames: - cleanup = None + if sys.version_info[0] >= 3: + if "onlyheads" not in orig.__code__.co_varnames: + cleanup = None + else: + if "onlyheads" not in orig.func_code.co_varnames: + cleanup = None return r, c, cleanup return orig(ui, repo, other, *args, **opts) diff --git a/eden/scm/edenscm/hgext/hggit/_ssh.py b/eden/scm/edenscm/hgext/hggit/_ssh.py index 1e050f5bca..d25e357087 100644 --- a/eden/scm/edenscm/hgext/hggit/_ssh.py +++ b/eden/scm/edenscm/hgext/hggit/_ssh.py @@ -1,7 +1,7 @@ import subprocess from dulwich.client import SubprocessWrapper -from edenscm.mercurial import util +from edenscm.mercurial import pycompat, util class SSHVendor(object): @@ -16,7 +16,7 @@ def generate_ssh_vendor(ui): class _Vendor(SSHVendor): def run_command(self, host, command, username=None, port=None): - if isinstance(command, (str, bytes, unicode)): + if isinstance(command, (str, bytes, pycompat.unicode)): # 0.12.x dulwich sends the raw string command = [command] elif len(command) > 1: diff --git a/eden/scm/edenscm/hgext/hggit/git2hg.py b/eden/scm/edenscm/hgext/hggit/git2hg.py index 618b33d256..d9247e744f 100644 --- a/eden/scm/edenscm/hgext/hggit/git2hg.py +++ b/eden/scm/edenscm/hgext/hggit/git2hg.py @@ -27,17 +27,23 @@ def find_incoming(git_object_store, git_map, refs): for ref, sha in pycompat.iteritems(refs): # refs could contain refs on the server that we haven't pulled down # the objects for; also make sure it's a sha and not a symref - if ref != "HEAD" and sha in git_object_store: + assert isinstance(sha, bytes), "expected bytes, actual %s %s" % ( + sha.__class__, + sha, + ) + if ref != "HEAD" and len(sha) == 40 and sha in git_object_store: obj = git_object_store[sha] while isinstance(obj, Tag): obj_type, sha = obj.object obj = git_object_store[sha] if isinstance(obj, Commit) and sha not in seenheads: seenheads.add(sha) - todo.append(pycompat.decodeutf8(sha)) + todo.append(sha) todo.sort(key=commitdate, reverse=True) - return todo + + # We convert to utf8 after the sort, since commitdate expects byte shas + return [pycompat.decodeutf8(s) for s in todo] def get_unseen_commits(todo): """get all unseen commits reachable from todo in topological order @@ -50,14 +56,14 @@ def find_incoming(git_object_store, git_map, refs): if sha in done or git_map.lookupbyfirst(bin(sha)) is not None: todo.pop() continue - assert isinstance(sha, str) if sha in commit_cache: obj = commit_cache[sha] else: - obj = git_object_store[sha] + obj = git_object_store[pycompat.encodeutf8(sha)] commit_cache[sha] = obj assert isinstance(obj, Commit) for p in obj.parents: + p = pycompat.decodeutf8(p) if p not in done and git_map.lookupbyfirst(bin(p)) is None: todo.append(p) # process parents of a commit before processing the @@ -128,6 +134,7 @@ def extract_hg_metadata(message, git_extra): git_fn = 0 for field, data in git_extra: field = pycompat.decodeutf8(field) + data = pycompat.decodeutf8(data) if field.startswith("HG:"): if renames is None: renames = {} diff --git a/eden/scm/edenscm/hgext/hggit/git_handler.py b/eden/scm/edenscm/hgext/hggit/git_handler.py index 6cd700c878..0bf45d8fc9 100644 --- a/eden/scm/edenscm/hgext/hggit/git_handler.py +++ b/eden/scm/edenscm/hgext/hggit/git_handler.py @@ -418,6 +418,8 @@ class GitHandler(object): if remote_name and new_refs: for ref, new_sha in sorted(pycompat.iteritems(new_refs)): old_sha = old_refs.get(ref) + + ref = pycompat.decodeutf8(ref) if old_sha is None: if self.ui.verbose: self.ui.note( @@ -969,9 +971,11 @@ class GitHandler(object): m = RE_GIT_AUTHOR_EXTRA.match(commit.author) if m: name = m.group(1) - ex = hgutil.urlreq.unquote(m.group(2)) + ex = pycompat.encodeutf8( + hgutil.urlreq.unquote(pycompat.decodeutf8(m.group(2))) + ) email = m.group(3) - author = name + " <" + email + ">" + ex + author = name + b" <" + email + b">" + ex if b" " in commit.author: author = commit.author[:-12] @@ -1281,14 +1285,17 @@ class GitHandler(object): if rctx.ancestor(ctx) == rctx or force: new_refs[ref] = pycompat.encodeutf8(self.map_git_get(ctx.hex())) else: - raise error.Abort("pushing %s overwrites %s" % (ref, ctx)) + raise error.Abort( + "pushing %s overwrites %s" % (pycompat.decodeutf8(ref), ctx) + ) elif ref in uptodate_annotated_tags: # we already have the annotated tag. pass else: raise error.Abort( "branch '%s' changed on the server, " - "please pull and merge before pushing" % ref + "please pull and merge before pushing" + % pycompat.decodeutf8(ref) ) return new_refs @@ -1349,6 +1356,7 @@ class GitHandler(object): # if ref is just '', then we get ('foo', 'foo') stripped_refs = [(r, r[r.find(b"/", r.find(b"/") + 1) + 1 :]) for r in refs] for h in heads: + h = pycompat.encodeutf8(h) if h.endswith(b"/*"): prefix = h[:-1] # include the / but not the * r = [ diff --git a/eden/scm/edenscm/hgext/hggit/gitrepo.py b/eden/scm/edenscm/hgext/hggit/gitrepo.py index 9bfe5871eb..6e6ed1b05b 100644 --- a/eden/scm/edenscm/hgext/hggit/gitrepo.py +++ b/eden/scm/edenscm/hgext/hggit/gitrepo.py @@ -1,4 +1,4 @@ -from edenscm.mercurial import error, util +from edenscm.mercurial import error, pycompat, util from edenscm.mercurial.error import RepoError from .util import isgitsshuri @@ -57,9 +57,12 @@ class gitrepo(peerrepository): # map any git shas that exist in hg to hg shas stripped_refs = dict( [ - (ref[11:], handler.map_hg_get(refs[ref]) or refs[ref]) + ( + pycompat.decodeutf8(ref[11:]), + handler.map_hg_get(refs[ref]) or refs[ref], + ) for ref in refs.keys() - if ref.startswith("refs/heads/") + if ref.startswith(b"refs/heads/") ] ) return stripped_refs diff --git a/eden/scm/edenscm/hgext/hggit/hg2git.py b/eden/scm/edenscm/hgext/hggit/hg2git.py index 03b81f908c..59a57eccb7 100644 --- a/eden/scm/edenscm/hgext/hggit/hg2git.py +++ b/eden/scm/edenscm/hgext/hggit/hg2git.py @@ -280,7 +280,7 @@ class IncrementalChangesetExporter(object): d = os.path.dirname(path) tree = self._dirs.get(d, dulobjs.Tree()) - del tree[os.path.basename(path)] + del tree[pycompat.encodeutf8(os.path.basename(path))] dirty_trees.add(d) # If removing this file made the tree empty, we should delete this @@ -316,7 +316,7 @@ class IncrementalChangesetExporter(object): return try: - del tree[basename] + del tree[pycompat.encodeutf8(basename)] except KeyError: return diff --git a/eden/scm/edenscm/hgext/hggit/overlay.py b/eden/scm/edenscm/hgext/hggit/overlay.py index ed94d51ebd..65b29fe82e 100644 --- a/eden/scm/edenscm/hgext/hggit/overlay.py +++ b/eden/scm/edenscm/hgext/hggit/overlay.py @@ -67,9 +67,9 @@ class overlaymanifest(object): if entry.mode & 0o40000: # expand directory subtree = self.repo.handler.git.get_object(entry.sha) - addtree(subtree, dirname + entry.path + "/") + addtree(subtree, dirname + pycompat.decodeutf8(entry.path) + "/") else: - path = dirname + entry.path + path = dirname + pycompat.decodeutf8(entry.path) self._map[path] = bin(entry.sha) self._flags[path] = hgflag(entry.mode) @@ -535,10 +535,10 @@ class overlayrepo(object): self.refmap = {} self.tagmap = {} for ref in refs: - if ref.startswith("refs/heads/"): + if ref.startswith(b"refs/heads/"): refname = ref[11:] self.refmap.setdefault(bin(refs[ref]), []).append(refname) - elif ref.startswith("refs/tags/"): + elif ref.startswith(b"refs/tags/"): tagname = ref[10:] self.tagmap.setdefault(bin(refs[ref]), []).append(tagname) diff --git a/eden/scm/edenscm/hgext/hggit/verify.py b/eden/scm/edenscm/hgext/hggit/verify.py index 83b1db1db4..6819b223f9 100644 --- a/eden/scm/edenscm/hgext/hggit/verify.py +++ b/eden/scm/edenscm/hgext/hggit/verify.py @@ -9,7 +9,7 @@ import stat from dulwich import diff_tree from dulwich.objects import S_IFGITLINK, Commit -from edenscm.mercurial import error, progress, util as hgutil +from edenscm.mercurial import error, progress, pycompat, util as hgutil from edenscm.mercurial.i18n import _ @@ -32,7 +32,7 @@ def verify(ui, repo, hgctx): ) try: - gitcommit = handler.git.get_object(gitsha) + gitcommit = handler.git.get_object(pycompat.encodeutf8(gitsha)) except KeyError: raise hgutil.Abort( _("git equivalent %s for rev %s not found!") % (gitsha, hgctx) @@ -64,10 +64,11 @@ def verify(ui, repo, hgctx): continue prog.value = i i += 1 - gitfiles.add(gitfile.path) + gitfilepath = pycompat.decodeutf8(gitfile.path) + gitfiles.add(gitfilepath) try: - fctx = hgctx[gitfile.path] + fctx = hgctx[gitfilepath] except error.LookupError: # we'll deal with this at the end continue @@ -77,11 +78,11 @@ def verify(ui, repo, hgctx): if hgflags != gitflags: ui.write( _("file has different flags: %s (hg '%s', git '%s')\n") - % (gitfile.path, hgflags, gitflags) + % (gitfilepath, hgflags, gitflags) ) failed = True if fctx.data() != handler.git[gitfile.sha].data: - ui.write(_("difference in: %s\n") % gitfile.path) + ui.write(_("difference in: %s\n") % gitfilepath) failed = True if hgfiles != gitfiles: diff --git a/eden/scm/edenscm/mercurial/changelog.py b/eden/scm/edenscm/mercurial/changelog.py index 070f1d8213..6b410771d5 100644 --- a/eden/scm/edenscm/mercurial/changelog.py +++ b/eden/scm/edenscm/mercurial/changelog.py @@ -358,7 +358,7 @@ class changelog(revlog.revlog): def __contains__(self, rev): """filtered version of revlog.__contains__""" - return 0 <= rev < len(self) and rev not in self.filteredrevs + return rev is not None and 0 <= rev < len(self) and rev not in self.filteredrevs def __iter__(self): """filtered version of revlog.__iter__""" diff --git a/eden/scm/edenscm/mercurial/commands/__init__.py b/eden/scm/edenscm/mercurial/commands/__init__.py index d9eeb01619..a9b3e96d74 100644 --- a/eden/scm/edenscm/mercurial/commands/__init__.py +++ b/eden/scm/edenscm/mercurial/commands/__init__.py @@ -4791,7 +4791,7 @@ def pull(ui, repo, source="default", **opts): # Run 'update' in another transaction. if checkout and checkout in repo: - checkout = str(repo.changelog.rev(checkout)) + checkout = str(repo[checkout].rev()) # order below depends on implementation of # hg.addbranchrevs(). opts['bookmark'] is ignored, diff --git a/eden/scm/tests/test-hggit-clone.t b/eden/scm/tests/test-hggit-clone.t index 3a75809243..7932614a12 100644 --- a/eden/scm/tests/test-hggit-clone.t +++ b/eden/scm/tests/test-hggit-clone.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-conflict-1.t b/eden/scm/tests/test-hggit-conflict-1.t index 3f8311110f..7d04f1865a 100644 --- a/eden/scm/tests/test-hggit-conflict-1.t +++ b/eden/scm/tests/test-hggit-conflict-1.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-conflict-2.t b/eden/scm/tests/test-hggit-conflict-2.t index 8c8c74a93d..407868e46f 100644 --- a/eden/scm/tests/test-hggit-conflict-2.t +++ b/eden/scm/tests/test-hggit-conflict-2.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-convergedmerge.t b/eden/scm/tests/test-hggit-convergedmerge.t index 48af641e3c..3d300109cd 100644 --- a/eden/scm/tests/test-hggit-convergedmerge.t +++ b/eden/scm/tests/test-hggit-convergedmerge.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-empty-working-tree.t b/eden/scm/tests/test-hggit-empty-working-tree.t index 78c6158b52..72bc9ae48d 100644 --- a/eden/scm/tests/test-hggit-empty-working-tree.t +++ b/eden/scm/tests/test-hggit-empty-working-tree.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-external-sync.t b/eden/scm/tests/test-hggit-external-sync.t index 8930ec0dd4..9c9cc1663d 100644 --- a/eden/scm/tests/test-hggit-external-sync.t +++ b/eden/scm/tests/test-hggit-external-sync.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" $ setconfig hggit.mapsavefrequency=1 diff --git a/eden/scm/tests/test-hggit-file-removal.t b/eden/scm/tests/test-hggit-file-removal.t index c973646b47..9cdcc7cd61 100644 --- a/eden/scm/tests/test-hggit-file-removal.t +++ b/eden/scm/tests/test-hggit-file-removal.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-git-clone.t b/eden/scm/tests/test-hggit-git-clone.t index e4db825b27..fbd3b01ead 100644 --- a/eden/scm/tests/test-hggit-git-clone.t +++ b/eden/scm/tests/test-hggit-git-clone.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-hg-author.t b/eden/scm/tests/test-hggit-hg-author.t index d692d4d208..e99d06c5c7 100644 --- a/eden/scm/tests/test-hggit-hg-author.t +++ b/eden/scm/tests/test-hggit-hg-author.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-keywords.t b/eden/scm/tests/test-hggit-keywords.t index 57d1ea3a8e..ecaa129fd1 100644 --- a/eden/scm/tests/test-hggit-keywords.t +++ b/eden/scm/tests/test-hggit-keywords.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-merge.t b/eden/scm/tests/test-hggit-merge.t index 6c259ce70f..ed1c64c3a1 100644 --- a/eden/scm/tests/test-hggit-merge.t +++ b/eden/scm/tests/test-hggit-merge.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-nodemap.t b/eden/scm/tests/test-hggit-nodemap.t index 78557482d2..e0ab3123b3 100644 --- a/eden/scm/tests/test-hggit-nodemap.t +++ b/eden/scm/tests/test-hggit-nodemap.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-octopus.t b/eden/scm/tests/test-hggit-octopus.t index 026dab3036..f75dbc8643 100644 --- a/eden/scm/tests/test-hggit-octopus.t +++ b/eden/scm/tests/test-hggit-octopus.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-outgoing.t b/eden/scm/tests/test-hggit-outgoing.t index 85e5c2c9f6..dba57a8da0 100644 --- a/eden/scm/tests/test-hggit-outgoing.t +++ b/eden/scm/tests/test-hggit-outgoing.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-pull-after-strip.t b/eden/scm/tests/test-hggit-pull-after-strip.t index 99efcf5fe0..d4ef403d33 100644 --- a/eden/scm/tests/test-hggit-pull-after-strip.t +++ b/eden/scm/tests/test-hggit-pull-after-strip.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-push-r.t b/eden/scm/tests/test-hggit-push-r.t index 332a2a839d..f7fa48e67f 100644 --- a/eden/scm/tests/test-hggit-push-r.t +++ b/eden/scm/tests/test-hggit-push-r.t @@ -1,4 +1,3 @@ -#require py2 $ disable treemanifest Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-renames.t b/eden/scm/tests/test-hggit-renames.t index 2e82e07563..d6071e42b0 100644 --- a/eden/scm/tests/test-hggit-renames.t +++ b/eden/scm/tests/test-hggit-renames.t @@ -1,4 +1,3 @@ -#require py2 Test that rename detection works $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-tree-decomposition.t b/eden/scm/tests/test-hggit-tree-decomposition.t index 9b0eb4efee..49f28161fb 100644 --- a/eden/scm/tests/test-hggit-tree-decomposition.t +++ b/eden/scm/tests/test-hggit-tree-decomposition.t @@ -1,4 +1,3 @@ -#require py2 Load commonly used test logic $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-updatemeta.t b/eden/scm/tests/test-hggit-updatemeta.t index a576719c79..e2a84400ec 100644 --- a/eden/scm/tests/test-hggit-updatemeta.t +++ b/eden/scm/tests/test-hggit-updatemeta.t @@ -1,4 +1,3 @@ -#require py2 $ disable treemanifest $ . "$TESTDIR/hggit/testutil" diff --git a/eden/scm/tests/test-hggit-verify-fail.t b/eden/scm/tests/test-hggit-verify-fail.t index d4f3606337..098dab9932 100644 --- a/eden/scm/tests/test-hggit-verify-fail.t +++ b/eden/scm/tests/test-hggit-verify-fail.t @@ -1,4 +1,3 @@ -#require py2 Other tests make sure that gverify passes. This makes sure that gverify detects inconsistencies. Since hg-git is ostensibly correct, we artificially create inconsistencies by placing different Mercurial and Git repos in the right spots.