# HG changeset patch # User Sean Farley # Date 1511826367 18000 # Node ID 8ed6c0cae9b846c4d9966943dfab5efa652a35f7 # Parent 6ef251fdbb30c5b3c8bed948a38aaba3528e7b3a cleanup: add some blank lines diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/__init__.py --- a/hggit/__init__.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/__init__.py Mon Nov 27 18:46:07 2017 -0500 @@ -112,6 +112,7 @@ def localpath(self): return self.p + def _isgitdir(path): """True if the given file path is a git repo.""" if os.path.exists(os.path.join(path, '.hg')): @@ -129,6 +130,7 @@ return False + def _local(path): p = urlcls(path).localpath() if _isgitdir(p): @@ -138,8 +140,10 @@ return gitrepo return _oldlocal(path) + hg.schemes['file'] = _local + # we need to wrap this so that git-like ssh paths are not prepended with a # local filesystem path. ugh. def _url(orig, path, **kwargs): @@ -157,6 +161,7 @@ return orig(gituri, **kwargs) return orig(path, **kwargs) + extensions.wrapfunction(hgutil, 'url', _url) @@ -172,10 +177,12 @@ return httpgitscheme + hg.schemes['https'] = _httpgitwrapper(hg.schemes['https']) hg.schemes['http'] = _httpgitwrapper(hg.schemes['http']) +hgdefaultdest = hg.defaultdest -hgdefaultdest = hg.defaultdest + def defaultdest(source): for scheme in util.gitschemes: if source.startswith('%s://' % scheme) and source.endswith('.git'): @@ -185,23 +192,30 @@ return hgdefaultdest(source[:-4]) return hgdefaultdest(source) + + hg.defaultdest = defaultdest + def getversion(): """return version with dependencies for hg --version -v""" import dulwich dulver = '.'.join(str(i) for i in dulwich.__version__) return __version__ + (" (dulwich %s)" % dulver) + # 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: co = None return revs, co + + if getattr(hg, 'addbranchrevs', False): extensions.wrapfunction(hg, 'addbranchrevs', safebranchrevs) + def extsetup(ui): templatekw.keywords.update({'gitnode': gitnodekw}) revset.symbols.update({ @@ -213,6 +227,7 @@ lambda *args: open(os.path.join(helpdir, 'git.rst')).read()) insort(help.helptable, entry) + def reposetup(ui, repo): if not isinstance(repo, gitrepo.gitrepo): @@ -231,21 +246,25 @@ klass = hgrepo.generate_repo_subclass(repo.__class__) repo.__class__ = klass + if hgutil.safehasattr(manifest, '_lazymanifest'): # Mercurial >= 3.4 extensions.wrapfunction(manifest.manifestdict, 'diff', overlay.wrapmanifestdictdiff) + @command('gimport') def gimport(ui, repo, remote_name=None): '''import commits from Git to Mercurial''' repo.githandler.import_commits(remote_name) + @command('gexport') def gexport(ui, repo): '''export commits from Mercurial to Git''' repo.githandler.export_commits() + @command('gclear') def gclear(ui, repo): '''clear out the Git cached data @@ -258,6 +277,7 @@ repo.ui.status(_("clearing out the git cache data\n")) repo.githandler.clear() + @command('gverify', [('r', 'rev', '', _('revision to verify'), _('REV'))], _('[-r REV]')) @@ -272,6 +292,7 @@ ctx = scmutil.revsingle(repo, opts.get('rev'), '.') return verify.verify(ui, repo, ctx) + @command('git-cleanup') def git_cleanup(ui, repo): '''clean up Git commit map after history editing''' @@ -289,6 +310,7 @@ wlock.release() ui.status(_('git commit map cleaned\n')) + def findcommonoutgoing(orig, repo, other, *args, **kwargs): if isinstance(other, gitrepo.gitrepo): heads = repo.githandler.get_refs(other.path)[0] @@ -305,8 +327,11 @@ kw['commoninc'] = commoninc return orig(repo, other, **kw) return orig(repo, other, *args, **kwargs) + + extensions.wrapfunction(discovery, 'findcommonoutgoing', findcommonoutgoing) + def getremotechanges(orig, ui, repo, other, *args, **opts): if isinstance(other, gitrepo.gitrepo): if args: @@ -319,22 +344,31 @@ cleanup = None return r, c, cleanup return orig(ui, repo, other, *args, **opts) + + extensions.wrapfunction(bundlerepo, 'getremotechanges', getremotechanges) + def peer(orig, uiorrepo, *args, **opts): newpeer = orig(uiorrepo, *args, **opts) if isinstance(newpeer, gitrepo.gitrepo): if isinstance(uiorrepo, localrepo.localrepository): newpeer.localrepo = uiorrepo return newpeer + + extensions.wrapfunction(hg, 'peer', peer) + def isvalidlocalpath(orig, self, path): return orig(self, path) or _isgitdir(path) + + if (hgutil.safehasattr(hgui, 'path') and hgutil.safehasattr(hgui.path, '_isvalidlocalpath')): extensions.wrapfunction(hgui.path, '_isvalidlocalpath', isvalidlocalpath) + @util.transform_notgit def exchangepull(orig, repo, remote, heads=None, force=False, bookmarks=(), **kwargs): @@ -366,10 +400,13 @@ wlock.release() else: return orig(repo, remote, heads, force, bookmarks=bookmarks, **kwargs) + + if not hgutil.safehasattr(localrepo.localrepository, 'pull'): # Mercurial >= 3.2 extensions.wrapfunction(exchange, 'pull', exchangepull) + # TODO figure out something useful to do with the newbranch param @util.transform_notgit def exchangepush(orig, repo, remote, force=False, revs=None, newbranch=False, @@ -386,10 +423,13 @@ else: return orig(repo, remote, force, revs, newbranch, bookmarks=bookmarks, **kwargs) + + if not hgutil.safehasattr(localrepo.localrepository, 'push'): # Mercurial >= 3.2 extensions.wrapfunction(exchange, 'push', exchangepush) + def revset_fromgit(repo, subset, x): '''``fromgit()`` Select changesets that originate from Git. @@ -400,6 +440,7 @@ return baseset(r for r in subset if git.map_git_get(hex(node(r))) is not None) + def revset_gitnode(repo, subset, x): '''``gitnode(hash)`` Select the changeset that originates in the given Git revision. The hash @@ -422,6 +463,7 @@ return result raise LookupError(rev, git.map_file, _('ambiguous identifier')) + def gitnodekw(**args): """:gitnode: String. The Git changeset identification hash, as a 40 hexadecimal digit string.""" node = args['ctx'] diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/_ssh.py --- a/hggit/_ssh.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/_ssh.py Mon Nov 27 18:46:07 2017 -0500 @@ -5,6 +5,7 @@ util, ) + class SSHVendor(object): """Parent class for ui-linked Vendor classes.""" diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/compat.py --- a/hggit/compat.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/compat.py Mon Nov 27 18:46:07 2017 -0500 @@ -37,6 +37,7 @@ from mercurial import scmutil hgvfs = scmutil.vfs + def gitvfs(repo): """return a vfs suitable to read git related data""" # Mercurial >= 3.3: repo.shared() @@ -45,6 +46,7 @@ else: return repo.vfs + def passwordmgr(ui): try: realm = hgutil.urlreq.httppasswordmgrwithdefaultrealm() @@ -139,6 +141,7 @@ hasconfigitems = False + def registerconfigs(configitem): global hasconfigitems hasconfigitems = True @@ -146,6 +149,7 @@ for item, default in items.iteritems(): configitem(section, item, default=default) + def config(ui, subtype, section, item): if subtype == 'string': subtype = '' diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/git2hg.py --- a/hggit/git2hg.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/git2hg.py Mon Nov 27 18:46:07 2017 -0500 @@ -3,6 +3,7 @@ import urllib from dulwich.objects import Commit, Tag + def find_incoming(git_object_store, git_map, refs): '''find what commits need to be imported @@ -73,12 +74,14 @@ return GitIncomingResult(commits, commit_cache) + class GitIncomingResult(object): '''struct to store result from find_incoming''' def __init__(self, commits, commit_cache): self.commits = commits self.commit_cache = commit_cache + def extract_hg_metadata(message, git_extra): split = message.split("\n--HG--\n", 1) # Renames are explicitly stored in Mercurial but inferred in Git. For diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/git_handler.py --- a/hggit/git_handler.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/git_handler.py Mon Nov 27 18:46:07 2017 -0500 @@ -56,6 +56,7 @@ CALLBACK_BUFFER = '' + class GitProgress(object): """convert git server progress strings into mercurial progress""" def __init__(self, ui): @@ -96,6 +97,7 @@ if msg: self.ui.note(msg + '\n') + class GitHandler(object): map_file = 'git-mapfile' remote_refs_file = 'git-remote-refs' diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/gitdirstate.py --- a/hggit/gitdirstate.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/gitdirstate.py Mon Nov 27 18:46:07 2017 -0500 @@ -25,6 +25,7 @@ pathutil = scmutil from mercurial.i18n import _ + def gignorepats(orig, lines, root=None): '''parse lines (iterable) of .gitignore text, returning a tuple of (patterns, parse errors). These patterns should be given to compile() @@ -70,6 +71,7 @@ return patterns, warnings + def gignore(root, files, warn, extrapatterns=None): allpats = [] pats = [] @@ -103,6 +105,7 @@ raise util.Abort('%s: %s' % ('extra patterns', inst[0])) return ignorefunc + class gitdirstate(dirstate.dirstate): @dirstate.rootcache('.hgignore') def _ignore(self): diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/gitrepo.py --- a/hggit/gitrepo.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/gitrepo.py Mon Nov 27 18:46:07 2017 -0500 @@ -9,6 +9,7 @@ except ImportError: from mercurial.peer import peerrepository + class gitrepo(peerrepository): def __init__(self, ui, path, create): if create: # pragma: no cover @@ -93,8 +94,10 @@ def unbundle(self): raise NotImplementedError + instance = gitrepo + def islocal(path): if isgitsshuri(path): return True diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/hg2git.py --- a/hggit/hg2git.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/hg2git.py Mon Nov 27 18:46:07 2017 -0500 @@ -13,6 +13,7 @@ import compat import util + def parse_subrepos(ctx): sub = util.OrderedDict() if '.hgsub' in ctx: diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/hgrepo.py --- a/hggit/hgrepo.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/hgrepo.py Mon Nov 27 18:46:07 2017 -0500 @@ -8,6 +8,7 @@ from gitrepo import gitrepo import util + def generate_repo_subclass(baseclass): class hgrepo(baseclass): if hgutil.safehasattr(localrepo.localrepository, 'pull'): diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/overlay.py --- a/hggit/overlay.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/overlay.py Mon Nov 27 18:46:07 2017 -0500 @@ -14,11 +14,13 @@ ) from mercurial.node import bin, hex, nullid + def _maybehex(n): if len(n) == 20: return hex(n) return n + class overlaymanifest(object): def __init__(self, repo, sha): self.repo = repo @@ -147,6 +149,7 @@ def __delitem__(self, path): del self._map[path] + def wrapmanifestdictdiff(orig, self, m2, match=None, clean=False): '''avoid calling into lazymanifest code if m2 is an overlaymanifest''' # Older mercurial clients used diff(m2, clean=False). If a caller failed @@ -172,6 +175,7 @@ else: return orig(self, m2, **kwargs) + class overlayfilectx(object): def __init__(self, repo, path, fileid=None): self._repo = repo @@ -204,6 +208,7 @@ def isbinary(self): return util.binary(self.data()) + class overlaychangectx(context.changectx): def __init__(self, repo, sha): # Can't store this in self._repo because the base class uses that field @@ -287,6 +292,7 @@ return (self.commit.tree, self.user(), self.date(), self.files(), self.description(), self.extra()) + class overlayrevlog(object): def __init__(self, repo, base): self.repo = repo @@ -345,6 +351,7 @@ def __len__(self): return len(self.repo.handler.repo) + len(self.repo.revmap) + class overlayoldmanifestlog(overlayrevlog): def read(self, sha): if sha == nullid: @@ -354,9 +361,11 @@ def __getitem__(self, sha): return overlaymanifestctx(self.repo, sha) + class overlaymanifestrevlog(overlayrevlog): pass + class overlaymanifestctx(object): def __init__(self, repo, node): self._repo = repo @@ -365,6 +374,7 @@ def read(self): return overlaymanifest(self._repo, self._node) + try: class overlaymanifestlog(manifest.manifestlog): def __init__(self, repo): @@ -385,6 +395,7 @@ # manifestlog did not exist prior to 4.0 pass + class overlaychangelog(overlayrevlog): def read(self, sha): if isinstance(sha, int): @@ -407,6 +418,7 @@ extra=values[5], ) + class overlayrepo(object): def __init__(self, handler, commits, refs): self.handler = handler diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/util.py --- a/hggit/util.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/util.py Mon Nov 27 18:46:07 2017 -0500 @@ -18,6 +18,7 @@ gitschemes = ('git', 'git+ssh', 'git+http', 'git+https') + def parse_hgsub(lines): """Fills OrderedDict with hgsub file content passed as list of lines""" rv = OrderedDict() @@ -29,10 +30,12 @@ rv[name.strip()] = value.strip() return rv + def serialize_hgsub(data): """Produces a string from OrderedDict hgsub content""" return ''.join(['%s = %s\n' % (n, v) for n, v in data.iteritems()]) + def parse_hgsubstate(lines): """Fills OrderedDict with hgsubtate file content passed as list of lines""" rv = OrderedDict() @@ -44,10 +47,12 @@ rv[name.strip()] = value.strip() return rv + def serialize_hgsubstate(data): """Produces a string from OrderedDict hgsubstate content""" return ''.join(['%s %s\n' % (data[n], n) for n in sorted(data)]) + def transform_notgit(f): '''use as a decorator around functions that call into dulwich''' def inner(*args, **kwargs): @@ -57,6 +62,7 @@ raise hgutil.Abort('not a git repository') return inner + def isgitsshuri(uri): """Method that returns True if a uri looks like git-style uri @@ -97,6 +103,7 @@ return True return False + def updatebookmarks(repo, changes, name='git_handler'): """abstract writing bookmarks for backwards compatibility""" bms = repo._bookmarks @@ -123,6 +130,7 @@ finally: lockmod.release(tr, lock, wlock) + def checksafessh(host): """check if a hostname is a potentially unsafe ssh exploit (SEC) diff -r 6ef251fdbb30 -r 8ed6c0cae9b8 hggit/verify.py --- a/hggit/verify.py Mon Nov 27 18:34:24 2017 -0500 +++ b/hggit/verify.py Mon Nov 27 18:46:07 2017 -0500 @@ -14,6 +14,7 @@ from dulwich import diff_tree from dulwich.objects import Commit, S_IFGITLINK + def verify(ui, repo, hgctx): '''verify that a Mercurial rev matches the corresponding Git rev