##// END OF EJS Templates
git: skeleton of a new extension to _directly_ operate on git repos...
git: skeleton of a new extension to _directly_ operate on git repos This is based in part of work I did years ago in hgit, but it's mostly new code since I'm using pygit2 instead of dulwich and the hg storage interfaces have improved. Some cleanup of old hgit code by Pulkit, which I greatly appreciate. test-git-interop.t does not cover a whole lot of cases, but it passes. It includes status, diff, making a new commit, and `hg annotate` working on the git repository. This is _not_ (yet) production quality code: this is an experiment. Known technical debt lurking in this implementation: * Writing bookmarks just totally ignores transactions. * The way progress is threaded down into the gitstore is awful. * Ideally we'd find a way to incrementally reindex DAGs. I'm not sure how to do that efficiently, so we might need a "known only fast-forwards" mode on the DAG indexer for use on `hg commit` and friends. * We don't even _try_ to do anything reasonable for `hg pull` or `hg push`. * Mercurial need an interface for the changelog type. Tests currently require git 2.24 as far as I'm aware: `git status` has some changed output that I didn't try and handle in a compatible way. This patch has produced some interesting cleanups, most recently on the manifest type. I expect continuing down this road will produce other meritorious cleanups throughout our code. Differential Revision: https://phab.mercurial-scm.org/D6734

File last commit:

r43387:8ff1ecfa default
r44961:ad718271 default
Show More
git.py
530 lines | 17.2 KiB | text/x-python | PythonLexer
Martin Geisler
convert: add copyright and license headers to back-ends
r8250 # git.py - git support for the convert extension
#
# Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
#
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
timeless
convert: git use absolute_import
r28365 from __future__ import absolute_import
Brendan Cully
Split convert extension into common and repository type modules
r4536
import os
Yuya Nishihara
py3: move up symbol imports to enforce import-checker rules...
r29205
from mercurial.i18n import _
timeless
convert: git use absolute_import
r28365 from mercurial import (
config,
error,
node as nodemod,
Augie Fackler
git: a little pycompat.bytestring() love to make this code work in py3...
r41619 pycompat,
timeless
convert: git use absolute_import
r28365 )
Brendan Cully
Split convert extension into common and repository type modules
r4536
Augie Fackler
formatting: blacken the codebase...
r43346 from . import common
Brendan Cully
Split convert extension into common and repository type modules
r4536
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929 class submodule(object):
def __init__(self, path, node, url):
self.path = path
self.node = node
self.url = url
def hgsub(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b"%s = [git]%s" % (self.path, self.url)
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929
def hgsubstate(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b"%s %s" % (self.node, self.path)
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
convert: add config option to copy extra keys from Git commits...
r30660 # Keys in extra fields that should not be copied if the user requests.
Martin von Zweigbergk
cleanup: use set literals...
r32291 bannedextrakeys = {
Gregory Szorc
convert: add config option to copy extra keys from Git commits...
r30660 # Git commit object built-ins.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'tree',
b'parent',
b'author',
b'committer',
Gregory Szorc
convert: add config option to copy extra keys from Git commits...
r30660 # Mercurial built-ins.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'branch',
b'close',
Martin von Zweigbergk
cleanup: use set literals...
r32291 }
Gregory Szorc
convert: add config option to copy extra keys from Git commits...
r30660
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
merge with stable
r28670 class convert_git(common.converter_source, common.commandline):
Patrick Mezard
convert: fix issue702 about GIT_DIR= construct unsupported under Windows.
r5217 # Windows does not support GIT_DIR= construct while other systems
# cannot remove environment variable. Just assume none have
# both issues.
David Schleimer
convert: drastically speed up git conversions...
r21630
Mateusz Kwapich
convert: add new, non-clowny interface for shelling out to git (SEC)...
r28659 def _gitcmd(self, cmd, *args, **kwargs):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return cmd(b'--git-dir=%s' % self.path, *args, **kwargs)
Mateusz Kwapich
convert: add new, non-clowny interface for shelling out to git (SEC)...
r28659
def gitrun0(self, *args, **kwargs):
return self._gitcmd(self.run0, *args, **kwargs)
def gitrun(self, *args, **kwargs):
return self._gitcmd(self.run, *args, **kwargs)
def gitrunlines0(self, *args, **kwargs):
return self._gitcmd(self.runlines0, *args, **kwargs)
def gitrunlines(self, *args, **kwargs):
return self._gitcmd(self.runlines, *args, **kwargs)
Mateusz Kwapich
convert: rewrite gitpipe to use common.commandline (SEC)...
r28662 def gitpipe(self, *args, **kwargs):
return self._gitcmd(self._run3, *args, **kwargs)
Matt Harbison
convert: save an indicator of the repo type for sources and sinks...
r35168 def __init__(self, ui, repotype, path, revs=None):
super(convert_git, self).__init__(ui, repotype, path, revs=revs)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 common.commandline.__init__(self, ui, b'git')
Durham Goode
convert: add support for specifying multiple revs...
r25748
Blake Burkhart
convert: pass absolute paths to git (SEC)...
r29051 # Pass an absolute path to git to prevent from ever being interpreted
# as a URL
path = os.path.abspath(path)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if os.path.isdir(path + b"/.git"):
path += b"/.git"
if not os.path.exists(path + b"/objects"):
Augie Fackler
formatting: blacken the codebase...
r43346 raise common.NoRepo(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"%s does not look like a Git repository") % path
Augie Fackler
formatting: blacken the codebase...
r43346 )
Patrick Mezard
convert: fail if an external required tool is not found
r5497
Siddharth Agarwal
convert: change default for git rename detection to 50%...
r22512 # The default value (50) is based on the default for 'git diff'.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 similarity = ui.configint(b'convert', b'git.similarity')
Siddharth Agarwal
convert: add support to detect git renames and copies...
r22470 if similarity < 0 or similarity > 100:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'similarity must be between 0 and 100'))
Siddharth Agarwal
convert: add support to detect git renames and copies...
r22470 if similarity > 0:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.simopt = [b'-C%d%%' % similarity]
findcopiesharder = ui.configbool(
b'convert', b'git.findcopiesharder'
)
Siddharth Agarwal
convert: add support to find git copies from all files in the working copy...
r22471 if findcopiesharder:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.simopt.append(b'--find-copies-harder')
Gregory Szorc
convert: config option for git rename limit...
r30646
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 renamelimit = ui.configint(b'convert', b'git.renamelimit')
self.simopt.append(b'-l%d' % renamelimit)
Siddharth Agarwal
convert: add support to detect git renames and copies...
r22470 else:
Mateusz Kwapich
convert: rewrite calls to Git to use the new shelling mechanism (SEC)...
r28660 self.simopt = []
Siddharth Agarwal
convert: add support to detect git renames and copies...
r22470
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 common.checktool(b'git', b'git')
Patrick Mezard
convert: fail if an external required tool is not found
r5497
Brendan Cully
Split convert extension into common and repository type modules
r4536 self.path = path
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929 self.submodules = []
Brendan Cully
Split convert extension into common and repository type modules
r4536
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.catfilepipe = self.gitpipe(b'cat-file', b'--batch')
David Schleimer
convert: drastically speed up git conversions...
r21630
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.copyextrakeys = self.ui.configlist(b'convert', b'git.extrakeys')
Gregory Szorc
convert: add config option to copy extra keys from Git commits...
r30660 banned = set(self.copyextrakeys) & bannedextrakeys
if banned:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'copying of extra key is forbidden: %s')
% _(b', ').join(sorted(banned))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
convert: add config option to copy extra keys from Git commits...
r30660
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 committeractions = self.ui.configlist(
b'convert', b'git.committeractions'
)
Gregory Szorc
convert: config option to control Git committer actions...
r30813
messagedifferent = None
messagealways = None
for a in committeractions:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if a.startswith((b'messagedifferent', b'messagealways')):
Gregory Szorc
convert: config option to control Git committer actions...
r30813 k = a
v = None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'=' in a:
k, v = a.split(b'=', 1)
Gregory Szorc
convert: config option to control Git committer actions...
r30813
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if k == b'messagedifferent':
messagedifferent = v or b'committer:'
elif k == b'messagealways':
messagealways = v or b'committer:'
Gregory Szorc
convert: config option to control Git committer actions...
r30813
if messagedifferent and messagealways:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'committeractions cannot define both '
b'messagedifferent and messagealways'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Gregory Szorc
convert: config option to control Git committer actions...
r30813
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 dropcommitter = b'dropcommitter' in committeractions
replaceauthor = b'replaceauthor' in committeractions
Gregory Szorc
convert: config option to control Git committer actions...
r30813
Gregory Szorc
convert: remove "replacecommitter" action...
r30815 if dropcommitter and replaceauthor:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'committeractions cannot define both '
b'dropcommitter and replaceauthor'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Gregory Szorc
convert: config option to control Git committer actions...
r30813
if dropcommitter and messagealways:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'committeractions cannot define both '
b'dropcommitter and messagealways'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Gregory Szorc
convert: config option to control Git committer actions...
r30813
if not messagedifferent and not messagealways:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 messagedifferent = b'committer:'
Gregory Szorc
convert: config option to control Git committer actions...
r30813
self.committeractions = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'dropcommitter': dropcommitter,
b'replaceauthor': replaceauthor,
b'messagedifferent': messagedifferent,
b'messagealways': messagealways,
Gregory Szorc
convert: config option to control Git committer actions...
r30813 }
David Schleimer
convert: drastically speed up git conversions...
r21630 def after(self):
for f in self.catfilepipe:
f.close()
Brendan Cully
Split convert extension into common and repository type modules
r4536 def getheads(self):
Durham Goode
convert: add support for specifying multiple revs...
r25748 if not self.revs:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output, status = self.gitrun(
b'rev-parse', b'--branches', b'--remotes'
)
Mateusz Kwapich
convert: rewrite calls to Git to use the new shelling mechanism (SEC)...
r28660 heads = output.splitlines()
if status:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot retrieve git heads'))
Brendan Cully
convert: import all branches from git repositories
r4768 else:
Durham Goode
convert: support multiple specifed revs in git source...
r25749 heads = []
for rev in self.revs:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rawhead, ret = self.gitrun(b'rev-parse', b'--verify', rev)
Durham Goode
convert: support multiple specifed revs in git source...
r25749 heads.append(rawhead[:-1])
if ret:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot retrieve git head "%s"') % rev)
Patrick Mezard
convert/git: check status when reading the whole output
r10986 return heads
Brendan Cully
Split convert extension into common and repository type modules
r4536
Pulkit Goyal
convert: don't use type as a variable name...
r36350 def catfile(self, rev, ftype):
timeless
convert: git use absolute_import
r28365 if rev == nodemod.nullhex:
Brodie Rao
cleanup: "raise SomeException()" -> "raise SomeException"
r16687 raise IOError
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.catfilepipe[0].write(rev + b'\n')
David Schleimer
convert: drastically speed up git conversions...
r21630 self.catfilepipe[0].flush()
info = self.catfilepipe[1].readline().split()
Pulkit Goyal
convert: don't use type as a variable name...
r36350 if info[1] != ftype:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'cannot read %r object at %s')
Augie Fackler
formatting: blacken the codebase...
r43346 % (pycompat.bytestr(ftype), rev)
)
David Schleimer
convert: drastically speed up git conversions...
r21630 size = int(info[2])
data = self.catfilepipe[1].read(size)
if len(data) < size:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'cannot read %r object at %s: unexpected size')
% (ftype, rev)
Augie Fackler
formatting: blacken the codebase...
r43346 )
David Schleimer
convert: drastically speed up git conversions...
r21630 # read the trailing newline
self.catfilepipe[1].read(1)
Patrick Mezard
convert/git: check status when reading the whole output
r10986 return data
Brendan Cully
Split convert extension into common and repository type modules
r4536
def getfile(self, name, rev):
timeless
convert: git use absolute_import
r28365 if rev == nodemod.nullhex:
Mads Kiilerich
convert: use None value for missing files instead of overloading IOError...
r22296 return None, None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if name == b'.hgsub':
data = b'\n'.join([m.hgsub() for m in self.submoditer()])
mode = b''
elif name == b'.hgsubstate':
data = b'\n'.join([m.hgsubstate() for m in self.submoditer()])
mode = b''
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 data = self.catfile(rev, b"blob")
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929 mode = self.modecache[(name, rev)]
Patrick Mezard
convert: merge sources getmode() into getfile()
r11134 return data, mode
Brendan Cully
Split convert extension into common and repository type modules
r4536
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929 def submoditer(self):
timeless
convert: git use absolute_import
r28365 null = nodemod.nullhex
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929 for m in sorted(self.submodules, key=lambda p: p.path):
if m.node != null:
yield m
def parsegitmodules(self, content):
"""Parse the formatted .gitmodules file, example file format:
[submodule "sub"]\n
\tpath = sub\n
\turl = git://giturl\n
"""
self.submodules = []
c = config.config()
Durham Goode
convert: handle .gitmodules with non-tab whitespaces...
r25698 # Each item in .gitmodules starts with whitespace that cant be parsed
Augie Fackler
formatting: blacken the codebase...
r43346 c.parse(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'.gitmodules',
b'\n'.join(line.strip() for line in content.split(b'\n')),
Augie Fackler
formatting: blacken the codebase...
r43346 )
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929 for sec in c.sections():
s = c[sec]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'url' in s and b'path' in s:
self.submodules.append(submodule(s[b'path'], b'', s[b'url']))
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929
def retrievegitmodules(self, version):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 modules, ret = self.gitrun(
b'show', b'%s:%s' % (version, b'.gitmodules')
)
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929 if ret:
Durham Goode
convert: improve support for unusual .gitmodules...
r25699 # This can happen if a file is in the repo that has permissions
# 160000, but there is no .gitmodules file.
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b"warning: cannot read submodules config file in %s\n")
Augie Fackler
formatting: blacken the codebase...
r43346 % version
)
Durham Goode
convert: improve support for unusual .gitmodules...
r25699 return
try:
self.parsegitmodules(modules)
except error.ParseError:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"warning: unable to parse .gitmodules in %s\n") % version
Augie Fackler
formatting: blacken the codebase...
r43346 )
Durham Goode
convert: improve support for unusual .gitmodules...
r25699 return
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929 for m in self.submodules:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 node, ret = self.gitrun(b'rev-parse', b'%s:%s' % (version, m.path))
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929 if ret:
continue
m.node = node.strip()
Mads Kiilerich
convert: introduce --full for converting all files...
r22300 def getchanges(self, version, full):
if full:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"convert from git does not support --full"))
Brendan Cully
Split convert extension into common and repository type modules
r4536 self.modecache = {}
Augie Fackler
formatting: blacken the codebase...
r43346 cmd = (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 [b'diff-tree', b'-z', b'--root', b'-m', b'-r']
+ self.simopt
+ [version]
Augie Fackler
formatting: blacken the codebase...
r43346 )
Mateusz Kwapich
convert: rewrite calls to Git to use the new shelling mechanism (SEC)...
r28660 output, status = self.gitrun(*cmd)
if status:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot read changes in %s') % version)
Brendan Cully
Split convert extension into common and repository type modules
r4536 changes = []
Siddharth Agarwal
convert: add support to detect git renames and copies...
r22470 copies = {}
Benoit Boissinot
convert: use set instead of dict
r8456 seen = set()
Patrick Mezard
convert: fix non-ASCII filenames retrieval from git sources (issue 1360)
r7242 entry = None
Siddharth Agarwal
convert: for git, factor out code to add entries to a separate function...
r22469 subexists = [False]
subdeleted = [False]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 difftree = output.split(b'\x00')
Siddharth Agarwal
convert: for git's getchanges, use explicit index for iteration...
r22467 lcount = len(difftree)
i = 0
Siddharth Agarwal
convert: for git, factor out code to add entries to a separate function...
r22469
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 skipsubmodules = self.ui.configbool(b'convert', b'git.skipsubmodules')
Augie Fackler
formatting: blacken the codebase...
r43346
Siddharth Agarwal
convert: add support to detect git renames and copies...
r22470 def add(entry, f, isdest):
Siddharth Agarwal
convert: for git, factor out code to add entries to a separate function...
r22469 seen.add(f)
h = entry[3]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 p = entry[1] == b"100755"
s = entry[1] == b"120000"
renamesource = not isdest and entry[4][0] == b'R'
Siddharth Agarwal
convert: for git, factor out code to add entries to a separate function...
r22469
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if f == b'.gitmodules':
Durham Goode
convert: add convert.git.skipsubmodules option...
r26077 if skipsubmodules:
return
Siddharth Agarwal
convert: for git, factor out code to add entries to a separate function...
r22469 subexists[0] = True
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if entry[4] == b'D' or renamesource:
Siddharth Agarwal
convert: for git, factor out code to add entries to a separate function...
r22469 subdeleted[0] = True
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 changes.append((b'.hgsub', nodemod.nullhex))
Siddharth Agarwal
convert: for git, factor out code to add entries to a separate function...
r22469 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 changes.append((b'.hgsub', b''))
elif entry[1] == b'160000' or entry[0] == b':160000':
Durham Goode
convert: add convert.git.skipsubmodules option...
r26077 if not skipsubmodules:
subexists[0] = True
Siddharth Agarwal
convert: for git, factor out code to add entries to a separate function...
r22469 else:
Siddharth Agarwal
convert: add support to detect git renames and copies...
r22470 if renamesource:
timeless
convert: git use absolute_import
r28365 h = nodemod.nullhex
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.modecache[(f, h)] = (p and b"x") or (s and b"l") or b""
Siddharth Agarwal
convert: for git, factor out code to add entries to a separate function...
r22469 changes.append((f, h))
Siddharth Agarwal
convert: for git's getchanges, use explicit index for iteration...
r22467 while i < lcount:
l = difftree[i]
i += 1
Patrick Mezard
convert: fix non-ASCII filenames retrieval from git sources (issue 1360)
r7242 if not entry:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not l.startswith(b':'):
Patrick Mezard
convert: fix non-ASCII filenames retrieval from git sources (issue 1360)
r7242 continue
Augie Fackler
git: a little pycompat.bytestring() love to make this code work in py3...
r41619 entry = tuple(pycompat.bytestr(p) for p in l.split())
Alexis S. L. Carvalho
convert_git: avoid returning two entries for the same file in getchanges...
r5335 continue
Patrick Mezard
convert: fix non-ASCII filenames retrieval from git sources (issue 1360)
r7242 f = l
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if entry[4][0] == b'C':
Durham Goode
convert: fix git copy file content conversions...
r25997 copysrc = f
copydest = difftree[i]
i += 1
f = copydest
copies[copydest] = copysrc
Patrick Mezard
convert: fix non-ASCII filenames retrieval from git sources (issue 1360)
r7242 if f not in seen:
Siddharth Agarwal
convert: add support to detect git renames and copies...
r22470 add(entry, f, False)
# A file can be copied multiple times, or modified and copied
# simultaneously. So f can be repeated even if fdest isn't.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if entry[4][0] == b'R':
Durham Goode
convert: fix git copy file content conversions...
r25997 # rename: next line is the destination
Siddharth Agarwal
convert: add support to detect git renames and copies...
r22470 fdest = difftree[i]
i += 1
if fdest not in seen:
add(entry, fdest, True)
# .gitmodules isn't imported at all, so it being copied to
# and fro doesn't really make sense
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if f != b'.gitmodules' and fdest != b'.gitmodules':
Siddharth Agarwal
convert: add support to detect git renames and copies...
r22470 copies[fdest] = f
Patrick Mezard
convert: fix non-ASCII filenames retrieval from git sources (issue 1360)
r7242 entry = None
YaNan Xu
convert: add support for converting git submodule (issue3528)...
r17929
Siddharth Agarwal
convert: for git, factor out code to add entries to a separate function...
r22469 if subexists[0]:
if subdeleted[0]:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 changes.append((b'.hgsubstate', nodemod.nullhex))
FUJIWARA Katsunori
convert: detect removal of ".gitmodules" at git source revisions correctly...
r21868 else:
self.retrievegitmodules(version)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 changes.append((b'.hgsubstate', b''))
Mads Kiilerich
convert: optimize convert of files that are unmodified from p2 in merges...
r24395 return (changes, copies, set())
Brendan Cully
Split convert extension into common and repository type modules
r4536
def getcommit(self, version):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 c = self.catfile(version, b"commit") # read the commit hash
end = c.find(b"\n\n")
Augie Fackler
formatting: blacken the codebase...
r43346 message = c[end + 2 :]
Brendan Cully
convert: ove recode method into converter_source
r4759 message = self.recode(message)
Brendan Cully
Split convert extension into common and repository type modules
r4536 l = c[:end].splitlines()
parents = []
Richard Quirk
Add committer tag only when needed in git conversion...
r8271 author = committer = None
Gregory Szorc
convert: add config option to copy extra keys from Git commits...
r30660 extra = {}
Brendan Cully
Split convert extension into common and repository type modules
r4536 for e in l[1:]:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 n, v = e.split(b" ", 1)
if n == b"author":
Brendan Cully
Split convert extension into common and repository type modules
r4536 p = v.split()
tm, tz = p[-2:]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 author = b" ".join(p[:-2])
if author[0] == b"<":
Boris Feld
style: remove multiple statement on a single line...
r35646 author = author[1:-1]
Brendan Cully
convert: ove recode method into converter_source
r4759 author = self.recode(author)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if n == b"committer":
Brendan Cully
Split convert extension into common and repository type modules
r4536 p = v.split()
tm, tz = p[-2:]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 committer = b" ".join(p[:-2])
if committer[0] == b"<":
Boris Feld
style: remove multiple statement on a single line...
r35646 committer = committer[1:-1]
Brendan Cully
convert: ove recode method into converter_source
r4759 committer = self.recode(committer)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if n == b"parent":
Matt Mackall
many, many trivial check-code fixups
r10282 parents.append(v)
Gregory Szorc
convert: add config option to copy extra keys from Git commits...
r30660 if n in self.copyextrakeys:
extra[n] = v
Brendan Cully
Split convert extension into common and repository type modules
r4536
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if self.committeractions[b'dropcommitter']:
Gregory Szorc
convert: config option to control Git committer actions...
r30813 committer = None
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif self.committeractions[b'replaceauthor']:
Gregory Szorc
convert: config option to control Git committer actions...
r30813 author = committer
if committer:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 messagealways = self.committeractions[b'messagealways']
messagedifferent = self.committeractions[b'messagedifferent']
Gregory Szorc
convert: config option to control Git committer actions...
r30813 if messagealways:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 message += b'\n%s %s\n' % (messagealways, committer)
Gregory Szorc
convert: config option to control Git committer actions...
r30813 elif messagedifferent and author != committer:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 message += b'\n%s %s\n' % (messagedifferent, committer)
Gregory Szorc
convert: config option to control Git committer actions...
r30813
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tzs, tzh, tzm = tz[-5:-4] + b"1", tz[-4:-2], tz[-2:]
Brendan Cully
Split convert extension into common and repository type modules
r4536 tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 date = tm + b" " + (b"%d" % tz)
saverev = self.ui.configbool(b'convert', b'git.saverev')
Brendan Cully
Split convert extension into common and repository type modules
r4536
Augie Fackler
formatting: blacken the codebase...
r43346 c = common.commit(
parents=parents,
date=date,
author=author,
desc=message,
rev=version,
extra=extra,
saverev=saverev,
)
Brendan Cully
Split convert extension into common and repository type modules
r4536 return c
Augie Fackler
convert: enable deterministic conversion progress bar for git
r22413 def numcommits(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output, ret = self.gitrunlines(b'rev-list', b'--all')
Mateusz Kwapich
convert: rewrite calls to Git to use the new shelling mechanism (SEC)...
r28660 if ret:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'cannot retrieve number of commits in %s') % self.path
Augie Fackler
formatting: blacken the codebase...
r43346 )
Mateusz Kwapich
convert: rewrite calls to Git to use the new shelling mechanism (SEC)...
r28660 return len(output)
Augie Fackler
convert: enable deterministic conversion progress bar for git
r22413
Brendan Cully
Split convert extension into common and repository type modules
r4536 def gettags(self):
tags = {}
Edouard Gomez
convert: support non annotated tags in git backend...
r16259 alltags = {}
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output, status = self.gitrunlines(b'ls-remote', b'--tags', self.path)
Mateusz Kwapich
convert: rewrite calls to Git to use the new shelling mechanism (SEC)...
r28660
if status:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot read tags from %s') % self.path)
prefix = b'refs/tags/'
Edouard Gomez
convert: support non annotated tags in git backend...
r16259
# Build complete list of tags, both annotated and bare ones
Mateusz Kwapich
convert: rewrite calls to Git to use the new shelling mechanism (SEC)...
r28660 for line in output:
Brendan Cully
Split convert extension into common and repository type modules
r4536 line = line.strip()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if line.startswith(b"error:") or line.startswith(b"fatal:"):
raise error.Abort(_(b'cannot read tags from %s') % self.path)
Brendan Cully
Split convert extension into common and repository type modules
r4536 node, tag = line.split(None, 1)
if not tag.startswith(prefix):
continue
Augie Fackler
formatting: blacken the codebase...
r43346 alltags[tag[len(prefix) :]] = node
Brendan Cully
Split convert extension into common and repository type modules
r4536
Edouard Gomez
convert: support non annotated tags in git backend...
r16259 # Filter out tag objects for annotated tag refs
for tag in alltags:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if tag.endswith(b'^{}'):
Edouard Gomez
convert: support non annotated tags in git backend...
r16259 tags[tag[:-3]] = alltags[tag]
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if tag + b'^{}' in alltags:
Edouard Gomez
convert: support non annotated tags in git backend...
r16259 continue
else:
tags[tag] = alltags[tag]
Brendan Cully
Split convert extension into common and repository type modules
r4536 return tags
Alexis S. L. Carvalho
convert_git: add --filemap support
r5380
def getchangedfiles(self, version, i):
changes = []
if i is None:
Augie Fackler
formatting: blacken the codebase...
r43346 output, status = self.gitrunlines(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'diff-tree', b'--root', b'-m', b'-r', version
Augie Fackler
formatting: blacken the codebase...
r43346 )
Mateusz Kwapich
convert: rewrite calls to Git to use the new shelling mechanism (SEC)...
r28660 if status:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot read changes in %s') % version)
Mateusz Kwapich
convert: rewrite calls to Git to use the new shelling mechanism (SEC)...
r28660 for l in output:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b"\t" not in l:
Alexis S. L. Carvalho
convert_git: add --filemap support
r5380 continue
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 m, f = l[:-1].split(b"\t")
Alexis S. L. Carvalho
convert_git: add --filemap support
r5380 changes.append(f)
else:
Augie Fackler
formatting: blacken the codebase...
r43346 output, status = self.gitrunlines(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'diff-tree',
b'--name-only',
b'--root',
b'-r',
Augie Fackler
formatting: blacken the codebase...
r43346 version,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'%s^%d' % (version, i + 1),
b'--',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Julien Cristau
convert: don't ignore errors from git diff-tree
r28816 if status:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'cannot read changes in %s') % version)
changes = [f.rstrip(b'\n') for f in output]
Alexis S. L. Carvalho
convert_git: add --filemap support
r5380
return changes
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756
def getbookmarks(self):
bookmarks = {}
Durham Goode
convert: fix git convert using servers branches...
r25905 # Handle local and remote branches
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 remoteprefix = self.ui.config(b'convert', b'git.remoteprefix')
Durham Goode
convert: fix git convert using servers branches...
r25905 reftypes = [
# (git prefix, hg prefix)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'refs/remotes/origin/', remoteprefix + b'/'),
(b'refs/heads/', b''),
Durham Goode
convert: fix git convert using servers branches...
r25905 ]
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756
Martin von Zweigbergk
cleanup: use set literals...
r32291 exclude = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'refs/remotes/origin/HEAD',
Martin von Zweigbergk
cleanup: use set literals...
r32291 }
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756
Durham Goode
convert: fix git convert using servers branches...
r25905 try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 output, status = self.gitrunlines(b'show-ref')
Mateusz Kwapich
convert: rewrite calls to Git to use the new shelling mechanism (SEC)...
r28660 for line in output:
Durham Goode
convert: fix git convert using servers branches...
r25905 line = line.strip()
rev, name = line.split(None, 1)
# Process each type of branch
for gitprefix, hgprefix in reftypes:
if not name.startswith(gitprefix) or name in exclude:
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756 continue
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 name = b'%s%s' % (hgprefix, name[len(gitprefix) :])
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756 bookmarks[name] = rev
Durham Goode
convert: fix git convert using servers branches...
r25905 except Exception:
pass
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756
return bookmarks
Ben Goswami
splicemap: improve error handling when source is git (issue2084)...
r19121
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 def checkrevformat(self, revstr, mapname=b'splicemap'):
Ben Goswami
splicemap: improve error handling when source is git (issue2084)...
r19121 """ git revision string is a 40 byte hex """
Sean Farley
convert: add mapname parameter to checkrevformat...
r20373 self.checkhexformat(revstr, mapname)