2009-04-26 03:47:44 +04:00
|
|
|
# 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
|
2010-01-20 07:20:08 +03:00
|
|
|
# GNU General Public License version 2 or any later version.
|
2007-06-11 07:08:47 +04:00
|
|
|
|
|
|
|
import os
|
2013-02-08 18:02:57 +04:00
|
|
|
import subprocess
|
2015-06-30 03:19:58 +03:00
|
|
|
from mercurial import util, config, error
|
2010-09-02 14:08:13 +04:00
|
|
|
from mercurial.node import hex, nullid
|
2010-04-18 17:47:49 +04:00
|
|
|
from mercurial.i18n import _
|
2007-06-11 07:08:47 +04:00
|
|
|
|
2007-10-31 00:14:15 +03:00
|
|
|
from common import NoRepo, commit, converter_source, checktool
|
2007-06-11 07:08:47 +04:00
|
|
|
|
2012-10-30 04:40:13 +04:00
|
|
|
class submodule(object):
|
|
|
|
def __init__(self, path, node, url):
|
|
|
|
self.path = path
|
|
|
|
self.node = node
|
|
|
|
self.url = url
|
|
|
|
|
|
|
|
def hgsub(self):
|
|
|
|
return "%s = [git]%s" % (self.path, self.url)
|
|
|
|
|
|
|
|
def hgsubstate(self):
|
|
|
|
return "%s %s" % (self.node, self.path)
|
|
|
|
|
2007-06-11 07:08:47 +04:00
|
|
|
class convert_git(converter_source):
|
2007-08-26 16:51:27 +04:00
|
|
|
# Windows does not support GIT_DIR= construct while other systems
|
|
|
|
# cannot remove environment variable. Just assume none have
|
|
|
|
# both issues.
|
2011-07-26 05:37:12 +04:00
|
|
|
if util.safehasattr(os, 'unsetenv'):
|
2013-02-08 18:02:57 +04:00
|
|
|
def gitopen(self, s, err=None):
|
2007-08-26 16:51:27 +04:00
|
|
|
prevgitdir = os.environ.get('GIT_DIR')
|
|
|
|
os.environ['GIT_DIR'] = self.path
|
|
|
|
try:
|
2013-02-08 18:02:57 +04:00
|
|
|
if err == subprocess.PIPE:
|
2011-03-25 03:38:43 +03:00
|
|
|
(stdin, stdout, stderr) = util.popen3(s)
|
|
|
|
return stdout
|
2013-02-08 18:02:57 +04:00
|
|
|
elif err == subprocess.STDOUT:
|
|
|
|
return self.popen_with_stderr(s)
|
2011-03-25 03:38:43 +03:00
|
|
|
else:
|
|
|
|
return util.popen(s, 'rb')
|
2007-08-26 16:51:27 +04:00
|
|
|
finally:
|
|
|
|
if prevgitdir is None:
|
|
|
|
del os.environ['GIT_DIR']
|
|
|
|
else:
|
|
|
|
os.environ['GIT_DIR'] = prevgitdir
|
2014-05-28 08:12:24 +04:00
|
|
|
|
|
|
|
def gitpipe(self, s):
|
|
|
|
prevgitdir = os.environ.get('GIT_DIR')
|
|
|
|
os.environ['GIT_DIR'] = self.path
|
|
|
|
try:
|
|
|
|
return util.popen3(s)
|
|
|
|
finally:
|
|
|
|
if prevgitdir is None:
|
|
|
|
del os.environ['GIT_DIR']
|
|
|
|
else:
|
|
|
|
os.environ['GIT_DIR'] = prevgitdir
|
|
|
|
|
2007-08-26 16:51:27 +04:00
|
|
|
else:
|
2013-02-08 18:02:57 +04:00
|
|
|
def gitopen(self, s, err=None):
|
|
|
|
if err == subprocess.PIPE:
|
2011-03-25 03:38:43 +03:00
|
|
|
(sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s))
|
2011-05-01 20:57:11 +04:00
|
|
|
return so
|
2013-02-08 18:02:57 +04:00
|
|
|
elif err == subprocess.STDOUT:
|
|
|
|
return self.popen_with_stderr(s)
|
2011-03-25 03:38:43 +03:00
|
|
|
else:
|
2011-06-25 03:55:15 +04:00
|
|
|
return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
|
2007-07-02 08:09:08 +04:00
|
|
|
|
2014-05-28 08:12:24 +04:00
|
|
|
def gitpipe(self, s):
|
|
|
|
return util.popen3('GIT_DIR=%s %s' % (self.path, s))
|
|
|
|
|
2013-02-08 18:02:57 +04:00
|
|
|
def popen_with_stderr(self, s):
|
|
|
|
p = subprocess.Popen(s, shell=True, bufsize=-1,
|
|
|
|
close_fds=util.closefds,
|
|
|
|
stdin=subprocess.PIPE,
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.STDOUT,
|
|
|
|
universal_newlines=False,
|
|
|
|
env=None)
|
|
|
|
return p.stdout
|
|
|
|
|
2010-04-26 00:59:50 +04:00
|
|
|
def gitread(self, s):
|
|
|
|
fh = self.gitopen(s)
|
|
|
|
data = fh.read()
|
|
|
|
return data, fh.close()
|
|
|
|
|
2015-07-08 20:27:43 +03:00
|
|
|
def __init__(self, ui, path, revs=None):
|
|
|
|
super(convert_git, self).__init__(ui, path, revs=revs)
|
|
|
|
|
2007-06-11 07:08:47 +04:00
|
|
|
if os.path.isdir(path + "/.git"):
|
|
|
|
path += "/.git"
|
|
|
|
if not os.path.exists(path + "/objects"):
|
2010-04-18 17:47:49 +04:00
|
|
|
raise NoRepo(_("%s does not look like a Git repository") % path)
|
2007-10-31 00:14:15 +03:00
|
|
|
|
2014-09-24 01:45:23 +04:00
|
|
|
# The default value (50) is based on the default for 'git diff'.
|
|
|
|
similarity = ui.configint('convert', 'git.similarity', default=50)
|
2014-09-12 22:23:26 +04:00
|
|
|
if similarity < 0 or similarity > 100:
|
|
|
|
raise util.Abort(_('similarity must be between 0 and 100'))
|
|
|
|
if similarity > 0:
|
2014-11-06 11:36:39 +03:00
|
|
|
self.simopt = '-C%d%%' % similarity
|
2014-09-12 23:28:30 +04:00
|
|
|
findcopiesharder = ui.configbool('convert', 'git.findcopiesharder',
|
|
|
|
False)
|
|
|
|
if findcopiesharder:
|
|
|
|
self.simopt += ' --find-copies-harder'
|
2014-09-12 22:23:26 +04:00
|
|
|
else:
|
|
|
|
self.simopt = ''
|
|
|
|
|
2008-07-25 00:44:15 +04:00
|
|
|
checktool('git', 'git')
|
2007-10-31 00:14:15 +03:00
|
|
|
|
2007-07-01 23:58:08 +04:00
|
|
|
self.path = path
|
2012-10-30 04:40:13 +04:00
|
|
|
self.submodules = []
|
2007-07-01 23:58:08 +04:00
|
|
|
|
2014-05-28 08:12:24 +04:00
|
|
|
self.catfilepipe = self.gitpipe('git cat-file --batch')
|
|
|
|
|
|
|
|
def after(self):
|
|
|
|
for f in self.catfilepipe:
|
|
|
|
f.close()
|
|
|
|
|
2007-06-11 07:08:47 +04:00
|
|
|
def getheads(self):
|
2015-07-08 20:27:43 +03:00
|
|
|
if not self.revs:
|
2010-04-26 00:59:50 +04:00
|
|
|
heads, ret = self.gitread('git rev-parse --branches --remotes')
|
|
|
|
heads = heads.splitlines()
|
2015-07-08 20:29:11 +03:00
|
|
|
if ret:
|
|
|
|
raise util.Abort(_('cannot retrieve git heads'))
|
2007-07-02 09:00:25 +04:00
|
|
|
else:
|
2015-07-08 20:29:11 +03:00
|
|
|
heads = []
|
|
|
|
for rev in self.revs:
|
|
|
|
rawhead, ret = self.gitread("git rev-parse --verify %s" % rev)
|
|
|
|
heads.append(rawhead[:-1])
|
|
|
|
if ret:
|
|
|
|
raise util.Abort(_('cannot retrieve git head "%s"') % rev)
|
2010-04-26 00:59:50 +04:00
|
|
|
return heads
|
2007-06-11 07:08:47 +04:00
|
|
|
|
|
|
|
def catfile(self, rev, type):
|
2010-09-02 14:08:13 +04:00
|
|
|
if rev == hex(nullid):
|
2012-05-12 18:00:58 +04:00
|
|
|
raise IOError
|
2014-05-28 08:12:24 +04:00
|
|
|
self.catfilepipe[0].write(rev+'\n')
|
|
|
|
self.catfilepipe[0].flush()
|
|
|
|
info = self.catfilepipe[1].readline().split()
|
|
|
|
if info[1] != type:
|
2010-04-26 00:59:50 +04:00
|
|
|
raise util.Abort(_('cannot read %r object at %s') % (type, rev))
|
2014-05-28 08:12:24 +04:00
|
|
|
size = int(info[2])
|
|
|
|
data = self.catfilepipe[1].read(size)
|
|
|
|
if len(data) < size:
|
2014-07-31 21:14:24 +04:00
|
|
|
raise util.Abort(_('cannot read %r object at %s: unexpected size')
|
|
|
|
% (type, rev))
|
2014-05-28 08:12:24 +04:00
|
|
|
# read the trailing newline
|
|
|
|
self.catfilepipe[1].read(1)
|
2010-04-26 00:59:50 +04:00
|
|
|
return data
|
2007-06-11 07:08:47 +04:00
|
|
|
|
|
|
|
def getfile(self, name, rev):
|
2014-07-14 18:33:59 +04:00
|
|
|
if rev == hex(nullid):
|
2014-08-27 00:03:32 +04:00
|
|
|
return None, None
|
2012-10-30 04:40:13 +04:00
|
|
|
if name == '.hgsub':
|
|
|
|
data = '\n'.join([m.hgsub() for m in self.submoditer()])
|
|
|
|
mode = ''
|
|
|
|
elif name == '.hgsubstate':
|
|
|
|
data = '\n'.join([m.hgsubstate() for m in self.submoditer()])
|
|
|
|
mode = ''
|
|
|
|
else:
|
|
|
|
data = self.catfile(rev, "blob")
|
|
|
|
mode = self.modecache[(name, rev)]
|
2010-05-09 23:52:34 +04:00
|
|
|
return data, mode
|
2007-06-11 07:08:47 +04:00
|
|
|
|
2012-10-30 04:40:13 +04:00
|
|
|
def submoditer(self):
|
|
|
|
null = hex(nullid)
|
|
|
|
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()
|
2015-06-30 03:19:18 +03:00
|
|
|
# Each item in .gitmodules starts with whitespace that cant be parsed
|
|
|
|
c.parse('.gitmodules', '\n'.join(line.strip() for line in
|
|
|
|
content.split('\n')))
|
2012-10-30 04:40:13 +04:00
|
|
|
for sec in c.sections():
|
|
|
|
s = c[sec]
|
|
|
|
if 'url' in s and 'path' in s:
|
|
|
|
self.submodules.append(submodule(s['path'], '', s['url']))
|
|
|
|
|
|
|
|
def retrievegitmodules(self, version):
|
|
|
|
modules, ret = self.gitread("git show %s:%s" % (version, '.gitmodules'))
|
|
|
|
if ret:
|
2015-06-30 03:19:58 +03:00
|
|
|
# This can happen if a file is in the repo that has permissions
|
|
|
|
# 160000, but there is no .gitmodules file.
|
|
|
|
self.ui.warn(_("warning: cannot read submodules config file in "
|
|
|
|
"%s\n") % version)
|
|
|
|
return
|
|
|
|
|
|
|
|
try:
|
|
|
|
self.parsegitmodules(modules)
|
|
|
|
except error.ParseError:
|
|
|
|
self.ui.warn(_("warning: unable to parse .gitmodules in %s\n")
|
|
|
|
% version)
|
|
|
|
return
|
|
|
|
|
2012-10-30 04:40:13 +04:00
|
|
|
for m in self.submodules:
|
|
|
|
node, ret = self.gitread("git rev-parse %s:%s" % (version, m.path))
|
|
|
|
if ret:
|
|
|
|
continue
|
|
|
|
m.node = node.strip()
|
|
|
|
|
convert: introduce --full for converting all files
Convert will normally only process files that were changed in a source
revision, apply the filemap, and record it has a change in the target
repository. (If it ends up not really changing anything, nothing changes.)
That means that _if_ the filemap is changed before continuing an incremental
convert, the change will only kick in when the files it affects are modified in
a source revision and thus processed.
With --full, convert will make a full conversion every time and process
all files in the source repo and remove target repo files that shouldn't be
there. Filemap changes will thus kick in on the first converted revision, no
matter what is changed.
This flag should in most cases not make any difference but will make convert
significantly slower.
Other names has been considered for this feature, such as "resync", "sync",
"checkunmodified", "all" or "allfiles", but I found that they were less obvious
and required more explanation than "full" and were harder to describe
consistently.
2014-08-27 00:03:32 +04:00
|
|
|
def getchanges(self, version, full):
|
|
|
|
if full:
|
|
|
|
raise util.Abort(_("convert from git do not support --full"))
|
2007-06-11 07:08:47 +04:00
|
|
|
self.modecache = {}
|
2014-09-12 22:23:26 +04:00
|
|
|
fh = self.gitopen("git diff-tree -z --root -m -r %s %s" % (
|
|
|
|
self.simopt, version))
|
2007-06-11 07:08:47 +04:00
|
|
|
changes = []
|
2014-09-12 22:23:26 +04:00
|
|
|
copies = {}
|
2009-05-17 05:04:17 +04:00
|
|
|
seen = set()
|
2008-10-26 15:23:02 +03:00
|
|
|
entry = None
|
2014-09-12 10:57:49 +04:00
|
|
|
subexists = [False]
|
|
|
|
subdeleted = [False]
|
2014-09-12 10:35:19 +04:00
|
|
|
difftree = fh.read().split('\x00')
|
|
|
|
lcount = len(difftree)
|
|
|
|
i = 0
|
2014-09-12 10:57:49 +04:00
|
|
|
|
2015-08-25 08:16:01 +03:00
|
|
|
skipsubmodules = self.ui.configbool('convert', 'git.skipsubmodules',
|
|
|
|
False)
|
2014-09-12 22:23:26 +04:00
|
|
|
def add(entry, f, isdest):
|
2014-09-12 10:57:49 +04:00
|
|
|
seen.add(f)
|
|
|
|
h = entry[3]
|
|
|
|
p = (entry[1] == "100755")
|
|
|
|
s = (entry[1] == "120000")
|
2014-09-12 22:23:26 +04:00
|
|
|
renamesource = (not isdest and entry[4][0] == 'R')
|
2014-09-12 10:57:49 +04:00
|
|
|
|
|
|
|
if f == '.gitmodules':
|
2015-08-25 08:16:01 +03:00
|
|
|
if skipsubmodules:
|
|
|
|
return
|
|
|
|
|
2014-09-12 10:57:49 +04:00
|
|
|
subexists[0] = True
|
2014-09-12 22:23:26 +04:00
|
|
|
if entry[4] == 'D' or renamesource:
|
2014-09-12 10:57:49 +04:00
|
|
|
subdeleted[0] = True
|
|
|
|
changes.append(('.hgsub', hex(nullid)))
|
|
|
|
else:
|
|
|
|
changes.append(('.hgsub', ''))
|
|
|
|
elif entry[1] == '160000' or entry[0] == ':160000':
|
2015-08-25 08:16:01 +03:00
|
|
|
if not skipsubmodules:
|
|
|
|
subexists[0] = True
|
2014-09-12 10:57:49 +04:00
|
|
|
else:
|
2014-09-12 22:23:26 +04:00
|
|
|
if renamesource:
|
|
|
|
h = hex(nullid)
|
2014-09-12 10:57:49 +04:00
|
|
|
self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
|
|
|
|
changes.append((f, h))
|
|
|
|
|
2014-09-12 10:35:19 +04:00
|
|
|
while i < lcount:
|
|
|
|
l = difftree[i]
|
|
|
|
i += 1
|
2008-10-26 15:23:02 +03:00
|
|
|
if not entry:
|
|
|
|
if not l.startswith(':'):
|
|
|
|
continue
|
2014-09-12 10:37:47 +04:00
|
|
|
entry = l.split()
|
2007-09-25 02:00:11 +04:00
|
|
|
continue
|
2008-10-26 15:23:02 +03:00
|
|
|
f = l
|
2015-08-07 03:21:46 +03:00
|
|
|
if entry[4][0] == 'C':
|
|
|
|
copysrc = f
|
|
|
|
copydest = difftree[i]
|
|
|
|
i += 1
|
|
|
|
f = copydest
|
|
|
|
copies[copydest] = copysrc
|
2008-10-26 15:23:02 +03:00
|
|
|
if f not in seen:
|
2014-09-12 22:23:26 +04:00
|
|
|
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.
|
2015-08-07 03:21:46 +03:00
|
|
|
if entry[4][0] == 'R':
|
|
|
|
# rename: next line is the destination
|
2014-09-12 22:23:26 +04:00
|
|
|
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
|
|
|
|
if f != '.gitmodules' and fdest != '.gitmodules':
|
|
|
|
copies[fdest] = f
|
2008-10-26 15:23:02 +03:00
|
|
|
entry = None
|
2010-04-26 01:07:46 +04:00
|
|
|
if fh.close():
|
|
|
|
raise util.Abort(_('cannot read changes in %s') % version)
|
2012-10-30 04:40:13 +04:00
|
|
|
|
2014-09-12 10:57:49 +04:00
|
|
|
if subexists[0]:
|
|
|
|
if subdeleted[0]:
|
2014-07-14 18:33:59 +04:00
|
|
|
changes.append(('.hgsubstate', hex(nullid)))
|
|
|
|
else:
|
|
|
|
self.retrievegitmodules(version)
|
|
|
|
changes.append(('.hgsubstate', ''))
|
2015-03-19 19:40:19 +03:00
|
|
|
return (changes, copies, set())
|
2007-06-11 07:08:47 +04:00
|
|
|
|
|
|
|
def getcommit(self, version):
|
|
|
|
c = self.catfile(version, "commit") # read the commit hash
|
|
|
|
end = c.find("\n\n")
|
2010-01-25 09:05:27 +03:00
|
|
|
message = c[end + 2:]
|
2007-07-01 23:58:08 +04:00
|
|
|
message = self.recode(message)
|
2007-06-11 07:08:47 +04:00
|
|
|
l = c[:end].splitlines()
|
|
|
|
parents = []
|
2009-05-01 13:32:19 +04:00
|
|
|
author = committer = None
|
2007-06-11 07:08:47 +04:00
|
|
|
for e in l[1:]:
|
|
|
|
n, v = e.split(" ", 1)
|
|
|
|
if n == "author":
|
|
|
|
p = v.split()
|
|
|
|
tm, tz = p[-2:]
|
|
|
|
author = " ".join(p[:-2])
|
|
|
|
if author[0] == "<": author = author[1:-1]
|
2007-07-01 23:58:08 +04:00
|
|
|
author = self.recode(author)
|
2007-06-11 07:08:47 +04:00
|
|
|
if n == "committer":
|
|
|
|
p = v.split()
|
|
|
|
tm, tz = p[-2:]
|
|
|
|
committer = " ".join(p[:-2])
|
|
|
|
if committer[0] == "<": committer = committer[1:-1]
|
2007-07-01 23:58:08 +04:00
|
|
|
committer = self.recode(committer)
|
2010-01-25 09:05:27 +03:00
|
|
|
if n == "parent":
|
|
|
|
parents.append(v)
|
2007-06-11 07:08:47 +04:00
|
|
|
|
2009-05-01 13:32:19 +04:00
|
|
|
if committer and committer != author:
|
|
|
|
message += "\ncommitter: %s\n" % committer
|
2007-06-11 07:08:47 +04:00
|
|
|
tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
|
|
|
|
tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
|
|
|
|
date = tm + " " + str(tz)
|
|
|
|
|
2007-07-13 19:28:57 +04:00
|
|
|
c = commit(parents=parents, date=date, author=author, desc=message,
|
|
|
|
rev=version)
|
2007-06-11 07:08:47 +04:00
|
|
|
return c
|
|
|
|
|
2014-09-10 18:51:46 +04:00
|
|
|
def numcommits(self):
|
|
|
|
return len([None for _ in self.gitopen('git rev-list --all')])
|
|
|
|
|
2007-06-11 07:08:47 +04:00
|
|
|
def gettags(self):
|
|
|
|
tags = {}
|
2012-03-14 04:13:45 +04:00
|
|
|
alltags = {}
|
2013-02-08 18:02:57 +04:00
|
|
|
fh = self.gitopen('git ls-remote --tags "%s"' % self.path,
|
|
|
|
err=subprocess.STDOUT)
|
2007-06-11 07:08:47 +04:00
|
|
|
prefix = 'refs/tags/'
|
2012-03-14 04:13:45 +04:00
|
|
|
|
|
|
|
# Build complete list of tags, both annotated and bare ones
|
2007-06-11 07:08:47 +04:00
|
|
|
for line in fh:
|
|
|
|
line = line.strip()
|
2013-02-08 17:09:48 +04:00
|
|
|
if line.startswith("error:") or line.startswith("fatal:"):
|
2013-02-08 18:02:57 +04:00
|
|
|
raise util.Abort(_('cannot read tags from %s') % self.path)
|
2007-06-11 07:08:47 +04:00
|
|
|
node, tag = line.split(None, 1)
|
|
|
|
if not tag.startswith(prefix):
|
|
|
|
continue
|
2012-03-14 04:13:45 +04:00
|
|
|
alltags[tag[len(prefix):]] = node
|
2010-04-26 01:07:46 +04:00
|
|
|
if fh.close():
|
|
|
|
raise util.Abort(_('cannot read tags from %s') % self.path)
|
2007-06-11 07:08:47 +04:00
|
|
|
|
2012-03-14 04:13:45 +04:00
|
|
|
# Filter out tag objects for annotated tag refs
|
|
|
|
for tag in alltags:
|
|
|
|
if tag.endswith('^{}'):
|
|
|
|
tags[tag[:-3]] = alltags[tag]
|
|
|
|
else:
|
|
|
|
if tag + '^{}' in alltags:
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
tags[tag] = alltags[tag]
|
|
|
|
|
2007-06-11 07:08:47 +04:00
|
|
|
return tags
|
2007-10-05 06:21:37 +04:00
|
|
|
|
|
|
|
def getchangedfiles(self, version, i):
|
|
|
|
changes = []
|
|
|
|
if i is None:
|
2010-04-26 00:32:27 +04:00
|
|
|
fh = self.gitopen("git diff-tree --root -m -r %s" % version)
|
2007-10-05 06:21:37 +04:00
|
|
|
for l in fh:
|
|
|
|
if "\t" not in l:
|
|
|
|
continue
|
|
|
|
m, f = l[:-1].split("\t")
|
|
|
|
changes.append(f)
|
|
|
|
else:
|
2012-05-12 17:54:54 +04:00
|
|
|
fh = self.gitopen('git diff-tree --name-only --root -r %s '
|
|
|
|
'"%s^%s" --' % (version, version, i + 1))
|
2007-10-05 06:21:37 +04:00
|
|
|
changes = [f.rstrip('\n') for f in fh]
|
2010-04-26 01:07:46 +04:00
|
|
|
if fh.close():
|
|
|
|
raise util.Abort(_('cannot read changes in %s') % version)
|
2007-10-05 06:21:37 +04:00
|
|
|
|
|
|
|
return changes
|
2011-03-25 03:38:43 +03:00
|
|
|
|
|
|
|
def getbookmarks(self):
|
|
|
|
bookmarks = {}
|
|
|
|
|
2015-07-29 23:21:03 +03:00
|
|
|
# Handle local and remote branches
|
2015-07-14 07:37:46 +03:00
|
|
|
remoteprefix = self.ui.config('convert', 'git.remoteprefix', 'remote')
|
2015-07-29 23:21:03 +03:00
|
|
|
reftypes = [
|
|
|
|
# (git prefix, hg prefix)
|
|
|
|
('refs/remotes/origin/', remoteprefix + '/'),
|
|
|
|
('refs/heads/', '')
|
|
|
|
]
|
2011-03-25 03:38:43 +03:00
|
|
|
|
2015-07-29 23:21:03 +03:00
|
|
|
exclude = set([
|
|
|
|
'refs/remotes/origin/HEAD',
|
|
|
|
])
|
|
|
|
|
|
|
|
try:
|
|
|
|
fh = self.gitopen('git show-ref', err=subprocess.PIPE)
|
|
|
|
for line in fh:
|
|
|
|
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:
|
2011-03-25 03:38:43 +03:00
|
|
|
continue
|
2015-07-29 23:21:03 +03:00
|
|
|
name = '%s%s' % (hgprefix, name[len(gitprefix):])
|
2011-03-25 03:38:43 +03:00
|
|
|
bookmarks[name] = rev
|
2015-07-29 23:21:03 +03:00
|
|
|
except Exception:
|
|
|
|
pass
|
2011-03-25 03:38:43 +03:00
|
|
|
|
|
|
|
return bookmarks
|
2013-04-26 03:02:58 +04:00
|
|
|
|
2014-01-21 21:34:55 +04:00
|
|
|
def checkrevformat(self, revstr, mapname='splicemap'):
|
2013-04-26 03:02:58 +04:00
|
|
|
""" git revision string is a 40 byte hex """
|
2014-01-21 21:34:55 +04:00
|
|
|
self.checkhexformat(revstr, mapname)
|