hgext/convert/hg.py
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
Thu, 04 Oct 2007 23:21:37 -0300
changeset 5377 756a43a30e34
parent 5356 b98c377b3c16
child 5378 8a2915f57dfc
permissions -rw-r--r--
convert: readd --filemap To handle merges correctly, this revision adds a filemap_source class that wraps a converter_source and does the work necessary to calculate the subgraph we're interested in. The wrapped converter_source must provide a new getchangedfiles method that, given a revision rev, and an index N, returns the list of files that are different in rev and its Nth parent. The implementation depends on the ability to skip some revisions and to change the parents field of the commit objects that we returned earlier. To make the conversion restartable, we assume the revisons in the revmapfile are topologically sorted.
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
# hg backend for convert extension
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
     2
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
     3
# Note for hg->hg conversion: Old versions of Mercurial didn't trim
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
     4
# the whitespace from the ends of commit messages, but new versions
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
     5
# do.  Changesets created by those older versions, then converted, may
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
     6
# thus have different hashes for changesets that are otherwise
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
     7
# identical.
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
     8
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
     9
4534
cc9b79216a76 Split convert extension into common and repository type modules
Brendan Cully <brendan@kublai.com>
parents: 4532
diff changeset
    10
import os, time
5014
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    11
from mercurial.i18n import _
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
    12
from mercurial.node import *
5014
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    13
from mercurial import hg, lock, revlog, util
3954
fad134931327 convert-repo: add basic CVS import support
Matt Mackall <mpm@selenic.com>
parents: 3948
diff changeset
    14
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
    15
from common import NoRepo, commit, converter_source, converter_sink
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
    16
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
    17
class mercurial_sink(converter_sink):
4756
8e9d3faec270 convert: split converter into convertsource and convertsink
Brendan Cully <brendan@kublai.com>
parents: 4753
diff changeset
    18
    def __init__(self, ui, path):
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    19
        self.path = path
4513
ac2fe196ac9b Turns convert.py into a real extension
Edouard Gomez <ed.gomez@free.fr>
parents: 4512
diff changeset
    20
        self.ui = ui
5172
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    21
        self.branchnames = ui.configbool('convert', 'hg.usebranchnames', True)
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    22
        self.clonebranches = ui.configbool('convert', 'hg.clonebranches', False)
5256
be4835ad9a85 convert: new config variable hg.tagsbranch controls which branch tags are committed to
Brendan Cully <brendan@kublai.com>
parents: 5192
diff changeset
    23
        self.tagsbranch = ui.config('convert', 'hg.tagsbranch', 'default')
5172
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    24
        self.lastbranch = None
3947
0fab73b3f453 convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents: 3916
diff changeset
    25
        try:
4513
ac2fe196ac9b Turns convert.py into a real extension
Edouard Gomez <ed.gomez@free.fr>
parents: 4512
diff changeset
    26
            self.repo = hg.repository(self.ui, path)
3947
0fab73b3f453 convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents: 3916
diff changeset
    27
        except:
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
    28
            raise NoRepo("could not open hg repo %s as sink" % path)
5014
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    29
        self.lock = None
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    30
        self.wlock = None
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    31
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    32
    def before(self):
5052
a11e8a181bd5 convert: fix locking order
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5038
diff changeset
    33
        self.wlock = self.repo.wlock()
5014
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    34
        self.lock = self.repo.lock()
5279
2dbd750b3ddd convert: clear the dirstate before a conversion, invalidate it afterwards
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5278
diff changeset
    35
        self.repo.dirstate.clear()
5014
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    36
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    37
    def after(self):
5279
2dbd750b3ddd convert: clear the dirstate before a conversion, invalidate it afterwards
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5278
diff changeset
    38
        self.repo.dirstate.invalidate()
5014
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    39
        self.lock = None
914054ca532e convert: acquire/release locks periodically
Bryan O'Sullivan <bos@serpentine.com>
parents: 5013
diff changeset
    40
        self.wlock = None
3947
0fab73b3f453 convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents: 3916
diff changeset
    41
5011
89fbb0a5e8e3 convert: rename mapfile to revmapfile, so we can map more than just revs
Bryan O'Sullivan <bos@serpentine.com>
parents: 4965
diff changeset
    42
    def revmapfile(self):
3947
0fab73b3f453 convert-repo: add some smarts
Matt Mackall <mpm@selenic.com>
parents: 3916
diff changeset
    43
        return os.path.join(self.path, ".hg", "shamap")
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    44
4589
451e91ed535e convert extension: Add support for username mapping
Edouard Gomez <ed.gomez@free.fr>
parents: 4534
diff changeset
    45
    def authorfile(self):
451e91ed535e convert extension: Add support for username mapping
Edouard Gomez <ed.gomez@free.fr>
parents: 4534
diff changeset
    46
        return os.path.join(self.path, ".hg", "authormap")
451e91ed535e convert extension: Add support for username mapping
Edouard Gomez <ed.gomez@free.fr>
parents: 4534
diff changeset
    47
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    48
    def getheads(self):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    49
        h = self.repo.changelog.heads()
5017
06329efa722d convert: get rid of "hg." prefix where not needed
Bryan O'Sullivan <bos@serpentine.com>
parents: 5016
diff changeset
    50
        return [ hex(x) for x in h ]
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
    51
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    52
    def putfile(self, f, e, data):
4082
6b2909e84203 convert-repo converts symlinks from git
Daniel Holth <dholth@fastmail.fm>
parents: 4062
diff changeset
    53
        self.repo.wwrite(f, data, e)
4950
30847b8af7ca dirstate: add __contains__ and make __getitem__ more useful
Matt Mackall <mpm@selenic.com>
parents: 4948
diff changeset
    54
        if f not in self.repo.dirstate:
5278
70e9a527cc61 convert: avoid dirstate checks; add a test
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5256
diff changeset
    55
            self.repo.dirstate.normallookup(f)
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
    56
4758
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents: 4756
diff changeset
    57
    def copyfile(self, source, dest):
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents: 4756
diff changeset
    58
        self.repo.copy(source, dest)
b6a1f2c46c6c convert extension: Add SVN converter
Daniel Holth <dholth@fastmail.fm>
parents: 4756
diff changeset
    59
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    60
    def delfile(self, f):
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    61
        try:
5343
26692d08c2f9 convert: delete empty directories if deleting a file (bug 754)
Bryan O'Sullivan <bos@serpentine.com>
parents: 4589
diff changeset
    62
            util.unlink(self.repo.wjoin(f))
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
    63
            #self.repo.remove([f])
5345
002fe2f364f5 convert: fix missing import
Patrick Mezard <pmezard@gmail.com>
parents: 5343
diff changeset
    64
        except OSError:
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    65
            pass
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    66
5172
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    67
    def setbranch(self, branch, pbranch, parents):
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    68
        if (not self.clonebranches) or (branch == self.lastbranch):
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    69
            return
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    70
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    71
        self.lastbranch = branch
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    72
        self.after()
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    73
        if not branch:
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    74
            branch = 'default'
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    75
        if not pbranch:
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    76
            pbranch = 'default'
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    77
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    78
        branchpath = os.path.join(self.path, branch)
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    79
        try:
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    80
            self.repo = hg.repository(self.ui, branchpath)
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    81
        except:
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    82
            if not parents:
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    83
                self.repo = hg.repository(self.ui, branchpath, create=True)
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    84
            else:
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    85
                self.ui.note(_('cloning branch %s to %s\n') % (pbranch, branch))
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    86
                hg.clone(self.ui, os.path.join(self.path, pbranch),
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    87
                         branchpath, rev=parents, update=False,
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    88
                         stream=True)
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    89
                self.repo = hg.repository(self.ui, branchpath)
6b4c332f241b convert: hg: optionally create branches as clones
Brendan Cully <brendan@kublai.com>
parents: 5117
diff changeset
    90
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
    91
    def putcommit(self, files, parents, commit):
5192
33015dac5df5 convert: fix mercurial_sink.putcommit
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5172
diff changeset
    92
        seen = {}
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
    93
        pl = []
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
    94
        for p in parents:
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
    95
            if p not in seen:
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
    96
                pl.append(p)
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
    97
                seen[p] = 1
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
    98
        parents = pl
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
    99
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
   100
        if len(parents) < 2: parents.append("0" * 40)
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
   101
        if len(parents) < 2: parents.append("0" * 40)
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
   102
        p2 = parents.pop(0)
692
695dd9a491da convert-repo: deal with packed git and other fixes
mpm@selenic.com
parents: 450
diff changeset
   103
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   104
        text = commit.desc
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   105
        extra = {}
5038
8f157190075e convert: add config option to turn off use of branch names
Bryan O'Sullivan <bos@serpentine.com>
parents: 5017
diff changeset
   106
        if self.branchnames and commit.branch:
4873
28b23b9073a8 convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents: 4758
diff changeset
   107
            extra['branch'] = commit.branch
28b23b9073a8 convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents: 4758
diff changeset
   108
        if commit.rev:
28b23b9073a8 convert: record the source revision in the changelog
Brendan Cully <brendan@kublai.com>
parents: 4758
diff changeset
   109
            extra['convert_revision'] = commit.rev
4939
cdd33a048289 removed trailing whitespace
Thomas Arendsen Hein <thomas@intevation.de>
parents: 4873
diff changeset
   110
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
   111
        while parents:
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
   112
            p1 = p2
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
   113
            p2 = parents.pop(0)
3955
9af4b853ed4d convert-repo: add CVS branch support
Matt Mackall <mpm@selenic.com>
parents: 3954
diff changeset
   114
            a = self.repo.rawcommit(files, text, commit.author, commit.date,
5017
06329efa722d convert: get rid of "hg." prefix where not needed
Bryan O'Sullivan <bos@serpentine.com>
parents: 5016
diff changeset
   115
                                    bin(p1), bin(p2), extra=extra)
5278
70e9a527cc61 convert: avoid dirstate checks; add a test
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5256
diff changeset
   116
            self.repo.dirstate.clear()
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
   117
            text = "(octopus merge fixup)\n"
1389
9b3ef6f3cef5 convert-repo: fix up octopus merge conversion
Matt Mackall <mpm@selenic.com>
parents: 1388
diff changeset
   118
            p2 = hg.hex(self.repo.changelog.tip())
431
dfc44f3f587c convert-repo fixups
mpm@selenic.com
parents: 316
diff changeset
   119
1389
9b3ef6f3cef5 convert-repo: fix up octopus merge conversion
Matt Mackall <mpm@selenic.com>
parents: 1388
diff changeset
   120
        return p2
316
c48d069163d6 Add new convert-repo script
mpm@selenic.com
parents:
diff changeset
   121
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   122
    def puttags(self, tags):
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   123
        try:
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   124
            old = self.repo.wfile(".hgtags").read()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   125
            oldlines = old.splitlines(1)
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   126
            oldlines.sort()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   127
        except:
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   128
            oldlines = []
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   129
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   130
        k = tags.keys()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   131
        k.sort()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   132
        newlines = []
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   133
        for tag in k:
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   134
            newlines.append("%s %s\n" % (tags[tag], tag))
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   135
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   136
        newlines.sort()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   137
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   138
        if newlines != oldlines:
4513
ac2fe196ac9b Turns convert.py into a real extension
Edouard Gomez <ed.gomez@free.fr>
parents: 4512
diff changeset
   139
            self.ui.status("updating tags\n")
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   140
            f = self.repo.wfile(".hgtags", "w")
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   141
            f.write("".join(newlines))
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   142
            f.close()
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   143
            if not oldlines: self.repo.add([".hgtags"])
1335
bea6356b8bca git -> hg conversion script
Florian La Roche <laroche@redhat.com>
parents: 1237
diff changeset
   144
            date = "%s 0" % int(time.mktime(time.gmtime()))
5256
be4835ad9a85 convert: new config variable hg.tagsbranch controls which branch tags are committed to
Brendan Cully <brendan@kublai.com>
parents: 5192
diff changeset
   145
            extra = {}
be4835ad9a85 convert: new config variable hg.tagsbranch controls which branch tags are committed to
Brendan Cully <brendan@kublai.com>
parents: 5192
diff changeset
   146
            if self.tagsbranch != 'default':
be4835ad9a85 convert: new config variable hg.tagsbranch controls which branch tags are committed to
Brendan Cully <brendan@kublai.com>
parents: 5192
diff changeset
   147
                extra['branch'] = self.tagsbranch
be4835ad9a85 convert: new config variable hg.tagsbranch controls which branch tags are committed to
Brendan Cully <brendan@kublai.com>
parents: 5192
diff changeset
   148
            try:
be4835ad9a85 convert: new config variable hg.tagsbranch controls which branch tags are committed to
Brendan Cully <brendan@kublai.com>
parents: 5192
diff changeset
   149
                tagparent = self.repo.changectx(self.tagsbranch).node()
be4835ad9a85 convert: new config variable hg.tagsbranch controls which branch tags are committed to
Brendan Cully <brendan@kublai.com>
parents: 5192
diff changeset
   150
            except hg.RepoError, inst:
be4835ad9a85 convert: new config variable hg.tagsbranch controls which branch tags are committed to
Brendan Cully <brendan@kublai.com>
parents: 5192
diff changeset
   151
                tagparent = nullid
694
51eb248d3348 Teach convert-repo about tags
mpm@selenic.com
parents: 692
diff changeset
   152
            self.repo.rawcommit([".hgtags"], "update tags", "convert-repo",
5256
be4835ad9a85 convert: new config variable hg.tagsbranch controls which branch tags are committed to
Brendan Cully <brendan@kublai.com>
parents: 5192
diff changeset
   153
                                date, tagparent, nullid)
5017
06329efa722d convert: get rid of "hg." prefix where not needed
Bryan O'Sullivan <bos@serpentine.com>
parents: 5016
diff changeset
   154
            return hex(self.repo.changelog.tip())
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   155
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   156
class mercurial_source(converter_source):
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   157
    def __init__(self, ui, path, rev=None):
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   158
        converter_source.__init__(self, ui, path, rev)
5354
4fbd27bf04b1 convert: fail properly if we can't read a source hg repository
Bryan O'Sullivan <bos@serpentine.com>
parents: 5344
diff changeset
   159
        try:
4fbd27bf04b1 convert: fail properly if we can't read a source hg repository
Bryan O'Sullivan <bos@serpentine.com>
parents: 5344
diff changeset
   160
            self.repo = hg.repository(self.ui, path)
4fbd27bf04b1 convert: fail properly if we can't read a source hg repository
Bryan O'Sullivan <bos@serpentine.com>
parents: 5344
diff changeset
   161
        except:
4fbd27bf04b1 convert: fail properly if we can't read a source hg repository
Bryan O'Sullivan <bos@serpentine.com>
parents: 5344
diff changeset
   162
            raise NoRepo("could not open hg repo %s as source" % path)
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   163
        self.lastrev = None
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   164
        self.lastctx = None
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   165
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   166
    def changectx(self, rev):
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   167
        if self.lastrev != rev:
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   168
            self.lastctx = self.repo.changectx(rev)
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   169
            self.lastrev = rev
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   170
        return self.lastctx
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   171
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   172
    def getheads(self):
5104
2f9edf6bae95 convert: only get history for requested revs when converting hg repo
Bryan O'Sullivan <bos@serpentine.com>
parents: 5076
diff changeset
   173
        if self.rev:
2f9edf6bae95 convert: only get history for requested revs when converting hg repo
Bryan O'Sullivan <bos@serpentine.com>
parents: 5076
diff changeset
   174
            return [hex(self.repo.changectx(self.rev).node())]
2f9edf6bae95 convert: only get history for requested revs when converting hg repo
Bryan O'Sullivan <bos@serpentine.com>
parents: 5076
diff changeset
   175
        else:
2f9edf6bae95 convert: only get history for requested revs when converting hg repo
Bryan O'Sullivan <bos@serpentine.com>
parents: 5076
diff changeset
   176
            return [hex(node) for node in self.repo.heads()]
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   177
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   178
    def getfile(self, name, rev):
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   179
        try:
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   180
            return self.changectx(rev).filectx(name).data()
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   181
        except revlog.LookupError, err:
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   182
            raise IOError(err)
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   183
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   184
    def getmode(self, name, rev):
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   185
        m = self.changectx(rev).manifest()
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   186
        return (m.execf(name) and 'x' or '') + (m.linkf(name) and 'l' or '')
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   187
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   188
    def getchanges(self, rev):
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   189
        ctx = self.changectx(rev)
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   190
        m, a, r = self.repo.status(ctx.parents()[0].node(), ctx.node())[:3]
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   191
        changes = [(name, rev) for name in m + a + r]
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   192
        changes.sort()
5280
11e1e574da02 convert: mercurial_source: also search for copies in modified files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5279
diff changeset
   193
        return (changes, self.getcopies(ctx, m + a))
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   194
5280
11e1e574da02 convert: mercurial_source: also search for copies in modified files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5279
diff changeset
   195
    def getcopies(self, ctx, files):
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   196
        copies = {}
5280
11e1e574da02 convert: mercurial_source: also search for copies in modified files
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5279
diff changeset
   197
        for name in files:
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   198
            try:
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   199
                copies[name] = ctx.filectx(name).renamed()[0]
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   200
            except TypeError:
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   201
                pass
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   202
        return copies
5117
d4fa6bafc43a Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5104
diff changeset
   203
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   204
    def getcommit(self, rev):
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   205
        ctx = self.changectx(rev)
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   206
        parents = [hex(p.node()) for p in ctx.parents() if p.node() != nullid]
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   207
        return commit(author=ctx.user(), date=util.datestr(ctx.date()),
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   208
                      desc=ctx.description(), parents=parents,
5076
ef338e34a906 convert: look up copies in getchanges instead of getcommit
Brendan Cully <brendan@kublai.com>
parents: 5052
diff changeset
   209
                      branch=ctx.branch())
5013
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   210
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   211
    def gettags(self):
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   212
        tags = [t for t in self.repo.tagslist() if t[0] != 'tip']
6c1029aacc9a convert: Support Mercurial as a source, as well as a sink
Bryan O'Sullivan <bos@serpentine.com>
parents: 5011
diff changeset
   213
        return dict([(name, hex(node)) for name, node in tags])