##// END OF EJS Templates
en-us: serialization
en-us: serialization

File last commit:

r16689:f366d4c2 default
r17535:63e302be default
Show More
git.py
217 lines | 7.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.
Brendan Cully
Split convert extension into common and repository type modules
r4536
import os
Patrick Mezard
convert: fix /dev/null redirections under Windows
r5220 from mercurial import util
Martin Geisler
clone, patch, convert: use hex(nullid) instead of '0'*40
r12144 from mercurial.node import hex, nullid
Martin Geisler
convert: mark strings for translation
r10939 from mercurial.i18n import _
Brendan Cully
Split convert extension into common and repository type modules
r4536
Patrick Mezard
convert: fail if an external required tool is not found
r5497 from common import NoRepo, commit, converter_source, checktool
Brendan Cully
Split convert extension into common and repository type modules
r4536
class convert_git(converter_source):
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.
Augie Fackler
hgext: replace uses of hasattr with util.safehasattr
r14945 if util.safehasattr(os, 'unsetenv'):
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756 def gitopen(self, s, noerr=False):
Patrick Mezard
convert: fix issue702 about GIT_DIR= construct unsupported under Windows.
r5217 prevgitdir = os.environ.get('GIT_DIR')
os.environ['GIT_DIR'] = self.path
try:
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756 if noerr:
(stdin, stdout, stderr) = util.popen3(s)
return stdout
else:
return util.popen(s, 'rb')
Patrick Mezard
convert: fix issue702 about GIT_DIR= construct unsupported under Windows.
r5217 finally:
if prevgitdir is None:
del os.environ['GIT_DIR']
else:
os.environ['GIT_DIR'] = prevgitdir
else:
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756 def gitopen(self, s, noerr=False):
if noerr:
(sin, so, se) = util.popen3('GIT_DIR=%s %s' % (self.path, s))
timeless
convert: fix error in git solaris code
r14177 return so
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756 else:
Mads Kiilerich
convert: fix git convert on solaris - it cannot remove environment variables
r14735 return util.popen('GIT_DIR=%s %s' % (self.path, s), 'rb')
Brendan Cully
convert: gitcmd wrapper for os.popen
r4767
Patrick Mezard
convert/git: check status when reading the whole output
r10986 def gitread(self, s):
fh = self.gitopen(s)
data = fh.read()
return data, fh.close()
Brendan Cully
convert: add -r argument specifying latest revision to convert
r4760 def __init__(self, ui, path, rev=None):
Brendan Cully
convert: call superclass init from engine init functions
r4807 super(convert_git, self).__init__(ui, path, rev=rev)
Brendan Cully
Split convert extension into common and repository type modules
r4536 if os.path.isdir(path + "/.git"):
path += "/.git"
if not os.path.exists(path + "/objects"):
Martin Geisler
convert: mark strings for translation
r10939 raise NoRepo(_("%s does not look like a Git repository") % path)
Patrick Mezard
convert: fail if an external required tool is not found
r5497
Dhruva Krishnamurthy
convert: use git executable only, with subcommands...
r6837 checktool('git', '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
def getheads(self):
Brendan Cully
convert: import all branches from git repositories
r4768 if not self.rev:
Patrick Mezard
convert/git: check status when reading the whole output
r10986 heads, ret = self.gitread('git rev-parse --branches --remotes')
heads = heads.splitlines()
Brendan Cully
convert: import all branches from git repositories
r4768 else:
Patrick Mezard
convert/git: check status when reading the whole output
r10986 heads, ret = self.gitread("git rev-parse --verify %s" % self.rev)
heads = [heads[:-1]]
if ret:
raise util.Abort(_('cannot retrieve git heads'))
return heads
Brendan Cully
Split convert extension into common and repository type modules
r4536
def catfile(self, rev, type):
Martin Geisler
clone, patch, convert: use hex(nullid) instead of '0'*40
r12144 if rev == hex(nullid):
Brodie Rao
cleanup: "raise SomeException()" -> "raise SomeException"
r16687 raise IOError
Patrick Mezard
convert/git: check status when reading the whole output
r10986 data, ret = self.gitread("git cat-file %s %s" % (type, rev))
if ret:
raise util.Abort(_('cannot read %r object at %s') % (type, rev))
return data
Brendan Cully
Split convert extension into common and repository type modules
r4536
def getfile(self, name, rev):
Patrick Mezard
convert: merge sources getmode() into getfile()
r11134 data = self.catfile(rev, "blob")
mode = self.modecache[(name, rev)]
return data, mode
Brendan Cully
Split convert extension into common and repository type modules
r4536
def getchanges(self, version):
self.modecache = {}
Patrick Mezard
convert/git: rename gitcmd() into gitopen() for readability
r10985 fh = self.gitopen("git diff-tree -z --root -m -r %s" % version)
Brendan Cully
Split convert extension into common and repository type modules
r4536 changes = []
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
for l in fh.read().split('\x00'):
if not entry:
if not l.startswith(':'):
continue
entry = l
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
if f not in seen:
Benoit Boissinot
convert: use set instead of dict
r8456 seen.add(f)
Patrick Mezard
convert: fix non-ASCII filenames retrieval from git sources (issue 1360)
r7242 entry = entry.split()
h = entry[3]
Augie Fackler
convert/git: abort if git submodules are detected (issue2150)...
r16292 if entry[1] == '160000':
raise util.Abort('git submodules are not supported!')
Patrick Mezard
convert: fix non-ASCII filenames retrieval from git sources (issue 1360)
r7242 p = (entry[1] == "100755")
s = (entry[1] == "120000")
self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
changes.append((f, h))
entry = None
Patrick Mezard
convert/git: check status when reading output stream
r10987 if fh.close():
raise util.Abort(_('cannot read changes in %s') % version)
Brendan Cully
convert: look up copies in getchanges instead of getcommit...
r5121 return (changes, {})
Brendan Cully
Split convert extension into common and repository type modules
r4536
def getcommit(self, version):
c = self.catfile(version, "commit") # read the commit hash
end = c.find("\n\n")
Matt Mackall
many, many trivial check-code fixups
r10282 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
Brendan Cully
Split convert extension into common and repository type modules
r4536 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]
Brendan Cully
convert: ove recode method into converter_source
r4759 author = self.recode(author)
Brendan Cully
Split convert extension into common and repository type modules
r4536 if n == "committer":
p = v.split()
tm, tz = p[-2:]
committer = " ".join(p[:-2])
if committer[0] == "<": committer = committer[1:-1]
Brendan Cully
convert: ove recode method into converter_source
r4759 committer = self.recode(committer)
Matt Mackall
many, many trivial check-code fixups
r10282 if n == "parent":
parents.append(v)
Brendan Cully
Split convert extension into common and repository type modules
r4536
Richard Quirk
Add committer tag only when needed in git conversion...
r8271 if committer and committer != author:
message += "\ncommitter: %s\n" % committer
Brendan Cully
Split convert extension into common and repository type modules
r4536 tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
date = tm + " " + str(tz)
Brendan Cully
convert: record the source revision in the changelog
r4873 c = commit(parents=parents, date=date, author=author, desc=message,
rev=version)
Brendan Cully
Split convert extension into common and repository type modules
r4536 return c
def gettags(self):
tags = {}
Edouard Gomez
convert: support non annotated tags in git backend...
r16259 alltags = {}
Patrick Mezard
convert/git: rename gitcmd() into gitopen() for readability
r10985 fh = self.gitopen('git ls-remote --tags "%s"' % self.path)
Brendan Cully
Split convert extension into common and repository type modules
r4536 prefix = 'refs/tags/'
Edouard Gomez
convert: support non annotated tags in git backend...
r16259
# Build complete list of tags, both annotated and bare ones
Brendan Cully
Split convert extension into common and repository type modules
r4536 for line in fh:
line = line.strip()
node, tag = line.split(None, 1)
if not tag.startswith(prefix):
continue
Edouard Gomez
convert: support non annotated tags in git backend...
r16259 alltags[tag[len(prefix):]] = node
Patrick Mezard
convert/git: check status when reading output stream
r10987 if fh.close():
raise util.Abort(_('cannot read tags from %s') % self.path)
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:
if tag.endswith('^{}'):
tags[tag[:-3]] = alltags[tag]
else:
if tag + '^{}' in alltags:
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:
Patrick Mezard
convert/git: rename gitcmd() into gitopen() for readability
r10985 fh = self.gitopen("git diff-tree --root -m -r %s" % version)
Alexis S. L. Carvalho
convert_git: add --filemap support
r5380 for l in fh:
if "\t" not in l:
continue
m, f = l[:-1].split("\t")
changes.append(f)
else:
Brodie Rao
cleanup: eradicate long lines
r16683 fh = self.gitopen('git diff-tree --name-only --root -r %s '
'"%s^%s" --' % (version, version, i + 1))
Alexis S. L. Carvalho
convert_git: add --filemap support
r5380 changes = [f.rstrip('\n') for f in fh]
Patrick Mezard
convert/git: check status when reading output stream
r10987 if fh.close():
raise util.Abort(_('cannot read changes in %s') % version)
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 = {}
# Interesting references in git are prefixed
prefix = 'refs/heads/'
prefixlen = len(prefix)
# factor two commands
gitcmd = { 'remote/': 'git ls-remote --heads origin',
'': 'git show-ref'}
# Origin heads
for reftype in gitcmd:
try:
fh = self.gitopen(gitcmd[reftype], noerr=True)
for line in fh:
line = line.strip()
rev, name = line.split(None, 1)
if not name.startswith(prefix):
continue
name = '%s%s' % (reftype, name[prefixlen:])
bookmarks[name] = rev
Brodie Rao
cleanup: replace naked excepts with except Exception: ...
r16689 except Exception:
Edouard Gomez
convert: add bookmarks reading support to git backend
r13756 pass
return bookmarks