hgext/convert/git.py
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
Fri, 17 Aug 2007 17:33:27 -0300
changeset 5189 60acf1432ee0
parent 5076 ef338e34a906
child 5232 7d3dcdd92a1a
permissions -rw-r--r--
Move cmdtable and reposetup handling out of extensions.py A new function (extensions.extensions) allows the code that is interested in those attributes to handle them directly. This allows some cleanups of extensions.py. Notably, we can remove the extensions.commandtable hack. It also makes it easier to add standard extension attributes, like a "hgwebsetup" function or a "helptable" dict that augments the data in help.py, etc.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4534
cc9b79216a76 Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents: 4532
diff changeset
     1
# git support for the convert extension
3825
158fce02dc40 Teach convert-repo to deal with mixed charsets in git
Matt Mackall <mpm@selenic.com>
parents: 2649
diff changeset
     2
4534
cc9b79216a76 Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents: 4532
diff changeset
     3
import os
3947
0fab73b3f453 convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents: 3916
diff changeset
     4
4534
cc9b79216a76 Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents: 4532
diff changeset
     5
from common import NoRepo, commit, converter_source
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
     6
4447
af013ae3ca10 use documented convert-repo interface
Daniel Holth <dholth@fastmail.fm>
parents: 4446
diff changeset
     7
class convert_git(converter_source):
4760
2d0a823cbba5 convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents: 4753
diff changeset
     8
    def gitcmd(self, s):
2d0a823cbba5 convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents: 4753
diff changeset
     9
        return os.popen('GIT_DIR=%s %s' % (self.path, s))
2d0a823cbba5 convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents: 4753
diff changeset
    10
4753
07efcce17d28 convert: add -r argument specifying latest revision to convert
Brendan Cully <brendan@kublai.com>
parents: 4752
diff changeset
    11
    def __init__(self, ui, path, rev=None):
4806
15a3cbfc6568 convert: call superclass init from engine init functions
Brendan Cully <brendan@kublai.com>
parents: 4761
diff changeset
    12
        super(convert_git, self).__init__(ui, path, rev=rev)
15a3cbfc6568 convert: call superclass init from engine init functions
Brendan Cully <brendan@kublai.com>
parents: 4761
diff changeset
    13
3947
0fab73b3f453 convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents: 3916
diff changeset
    14
        if os.path.isdir(path + "/.git"):
0fab73b3f453 convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents: 3916
diff changeset
    15
            path += "/.git"
4752
20ec5cc02f18 convert: ove recode method into converter_source
Brendan Cully <brendan@kublai.com>
parents: 4721
diff changeset
    16
        if not os.path.exists(path + "/objects"):
20ec5cc02f18 convert: ove recode method into converter_source
Brendan Cully <brendan@kublai.com>
parents: 4721
diff changeset
    17
            raise NoRepo("couldn't open GIT repo %s" % path)
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    18
        self.path = path
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    19
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    20
    def getheads(self):
4761
f52bfe566583 convert: import all branches from git repositories
Brendan Cully <brendan@kublai.com>
parents: 4760
diff changeset
    21
        if not self.rev:
f52bfe566583 convert: import all branches from git repositories
Brendan Cully <brendan@kublai.com>
parents: 4760
diff changeset
    22
            return self.gitcmd('git-rev-parse --branches').read().splitlines()
f52bfe566583 convert: import all branches from git repositories
Brendan Cully <brendan@kublai.com>
parents: 4760
diff changeset
    23
        else:
f52bfe566583 convert: import all branches from git repositories
Brendan Cully <brendan@kublai.com>
parents: 4760
diff changeset
    24
            fh = self.gitcmd("git-rev-parse --verify %s" % self.rev)
f52bfe566583 convert: import all branches from git repositories
Brendan Cully <brendan@kublai.com>
parents: 4760
diff changeset
    25
            return [fh.read()[:-1]]
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    26
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
    27
    def catfile(self, rev, type):
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
    28
        if rev == "0" * 40: raise IOError()
4760
2d0a823cbba5 convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents: 4753
diff changeset
    29
        fh = self.gitcmd("git-cat-file %s %s 2>/dev/null" % (type, rev))
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
    30
        return fh.read()
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
    31
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    32
    def getfile(self, name, rev):
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
    33
        return self.catfile(rev, "blob")
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    34
3957
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
    35
    def getmode(self, name, rev):
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
    36
        return self.modecache[(name, rev)]
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
    37
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    38
    def getchanges(self, version):
3957
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
    39
        self.modecache = {}
4760
2d0a823cbba5 convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents: 4753
diff changeset
    40
        fh = self.gitcmd("git-diff-tree --root -m -r %s" % version)
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    41
        changes = []
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    42
        for l in fh:
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    43
            if "\t" not in l: continue
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    44
            m, f = l[:-1].split("\t")
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    45
            m = m.split()
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    46
            h = m[3]
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    47
            p = (m[1] == "100755")
4082
6b2909e84203 convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents: 4062
diff changeset
    48
            s = (m[1] == "120000")
6b2909e84203 convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents: 4062
diff changeset
    49
            self.modecache[(f, h)] = (p and "x") or (s and "l") or ""
3957
558f52943cd2 convert-repo: add CVS exec bit support
Matt Mackall <mpm@selenic.com>
parents: 3955
diff changeset
    50
            changes.append((f, h))
5076
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 4873
diff changeset
    51
        return (changes, {})
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    52
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    53
    def getcommit(self, version):
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
    54
        c = self.catfile(version, "commit") # read the commit hash
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    55
        end = c.find("\n\n")
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    56
        message = c[end+2:]
4752
20ec5cc02f18 convert: ove recode method into converter_source
Brendan Cully <brendan@kublai.com>
parents: 4721
diff changeset
    57
        message = self.recode(message)
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    58
        l = c[:end].splitlines()
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    59
        manifest = l[0].split()[1]
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    60
        parents = []
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    61
        for e in l[1:]:
4532
c3a78a49d7f0 Some small cleanups for convert extension:
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4521
diff changeset
    62
            n, v = e.split(" ", 1)
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    63
            if n == "author":
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    64
                p = v.split()
1385
adb3de56635b convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents: 1335
diff changeset
    65
                tm, tz = p[-2:]
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    66
                author = " ".join(p[:-2])
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    67
                if author[0] == "<": author = author[1:-1]
4752
20ec5cc02f18 convert: ove recode method into converter_source
Brendan Cully <brendan@kublai.com>
parents: 4721
diff changeset
    68
                author = self.recode(author)
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
    69
            if n == "committer":
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
    70
                p = v.split()
1385
adb3de56635b convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents: 1335
diff changeset
    71
                tm, tz = p[-2:]
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
    72
                committer = " ".join(p[:-2])
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
    73
                if committer[0] == "<": committer = committer[1:-1]
4752
20ec5cc02f18 convert: ove recode method into converter_source
Brendan Cully <brendan@kublai.com>
parents: 4721
diff changeset
    74
                committer = self.recode(committer)
3910
4bc5a2405b12 convert-repo: fix recoding of committer
Matt Mackall <mpm@selenic.com>
parents: 3825
diff changeset
    75
                message += "\ncommitter: %s\n" % committer
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    76
            if n == "parent": parents.append(v)
1385
adb3de56635b convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents: 1335
diff changeset
    77
adb3de56635b convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents: 1335
diff changeset
    78
        tzs, tzh, tzm = tz[-5:-4] + "1", tz[-4:-2], tz[-2:]
2093
5cc414722587 convert-repo: fix reversed time zone offset
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1715
diff changeset
    79
        tz = -int(tzs) * (int(tzh) * 3600 + int(tzm))
1385
adb3de56635b convert-repo: Fix timezone handling
Matt Mackall <mpm@selenic.com>
parents: 1335
diff changeset
    80
        date = tm + " " + str(tz)
4721
96614af3c679 convert: "unknown" is a string
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4687
diff changeset
    81
        author = author or "unknown"
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    82
4873
28b23b9073a8 convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents: 4809
diff changeset
    83
        c = commit(parents=parents, date=date, author=author, desc=message,
28b23b9073a8 convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents: 4809
diff changeset
    84
                   rev=version)
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    85
        return c
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    86
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
    87
    def gettags(self):
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
    88
        tags = {}
4760
2d0a823cbba5 convert: gitcmd wrapper for os.popen
Brendan Cully <brendan@kublai.com>
parents: 4753
diff changeset
    89
        fh = self.gitcmd('git-ls-remote --tags "%s" 2>/dev/null' % self.path)
4062
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
    90
        prefix = 'refs/tags/'
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
    91
        for line in fh:
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
    92
            line = line.strip()
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
    93
            if not line.endswith("^{}"):
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
    94
                continue
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
    95
            node, tag = line.split(None, 1)
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
    96
            if not tag.startswith(prefix):
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
    97
                continue
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
    98
            tag = tag[len(prefix):-3]
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
    99
            tags[tag] = node
516f883e3d79 convert-repo: handle packed git tags
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4047
diff changeset
   100
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   101
        return tags