annotate hgext/convert/darcs.py @ 5483:0c43f87baba3 default tip

Fix file-changed-to-dir and dir-to-file commits (issue660). Allow adding to dirstate files that clash with previously existing but marked for removal. Protect from reintroducing clashes by revert. This change doesn't address related issues with update. Current workaround is to do "clean" update by manually removing conflicting files/dirs from working directory.
author Maxim Dounin <mdounin@mdounin.ru>
date Sat, 27 Oct 2007 16:27:55 +0400
parents fbf40ad5a8c2
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5355
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1 # darcs support for the convert extension
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
2
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
3 from common import NoRepo, commit, converter_source
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
4 from mercurial.i18n import _
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
5 from mercurial import util
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
6 import os, shutil, tempfile
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
7
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
8 # The naming drift of ElementTree is fun!
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
9
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
10 try: from xml.etree.cElementTree import ElementTree
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
11 except ImportError:
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
12 try: from xml.etree.ElementTree import ElementTree
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
13 except ImportError:
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
14 try: from elementtree.cElementTree import ElementTree
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
15 except ImportError:
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
16 try: from elementtree.ElementTree import ElementTree
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
17 except ImportError: ElementTree = None
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
18
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
19
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
20 class darcs_source(converter_source):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
21 def __init__(self, ui, path, rev=None):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
22 super(darcs_source, self).__init__(ui, path, rev=rev)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
23
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
24 if not os.path.exists(os.path.join(path, '_darcs', 'inventory')):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
25 raise NoRepo("couldn't open darcs repo %s" % path)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
26
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
27 if ElementTree is None:
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
28 raise util.Abort(_("Python ElementTree module is not available"))
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
29
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
30 self.path = os.path.realpath(path)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
31
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
32 self.lastrev = None
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
33 self.changes = {}
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
34 self.parents = {}
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
35 self.tags = {}
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
36
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
37 def before(self):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
38 self.tmppath = tempfile.mkdtemp(
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
39 prefix='convert-' + os.path.basename(self.path) + '-')
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
40 output, status = self.run('init', repodir=self.tmppath)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
41 self.checkexit(status)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
42
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
43 tree = self.xml('changes', '--xml-output', '--summary')
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
44 tagname = None
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
45 child = None
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
46 for elt in tree.findall('patch'):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
47 node = elt.get('hash')
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
48 name = elt.findtext('name', '')
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
49 if name.startswith('TAG '):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 tagname = name[4:].strip()
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 elif tagname is not None:
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 self.tags[tagname] = node
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
53 tagname = None
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
54 self.changes[node] = elt
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
55 self.parents[child] = [node]
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
56 child = node
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
57 self.parents[child] = []
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
58
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
59 def after(self):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
60 self.ui.debug('cleaning up %s\n' % self.tmppath)
5357
4ad2a18aff42 convert: fix a few residual bugs in darcs importer
Bryan O'Sullivan <bos@serpentine.com>
parents: 5355
diff changeset
61 shutil.rmtree(self.tmppath, ignore_errors=True)
5355
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
62
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
63 def _run(self, cmd, *args, **kwargs):
5411
d5df426bd68a convert: fix darcs_source._run() under windows
Patrick Mezard <pmezard@gmail.com>
parents: 5357
diff changeset
64 cmdline = ['darcs', cmd, '--repodir', kwargs.get('repodir', self.path)]
d5df426bd68a convert: fix darcs_source._run() under windows
Patrick Mezard <pmezard@gmail.com>
parents: 5357
diff changeset
65 cmdline += args
d5df426bd68a convert: fix darcs_source._run() under windows
Patrick Mezard <pmezard@gmail.com>
parents: 5357
diff changeset
66 cmdline = [util.shellquote(arg) for arg in cmdline]
d5df426bd68a convert: fix darcs_source._run() under windows
Patrick Mezard <pmezard@gmail.com>
parents: 5357
diff changeset
67 cmdline += ['<', util.nulldev]
d5df426bd68a convert: fix darcs_source._run() under windows
Patrick Mezard <pmezard@gmail.com>
parents: 5357
diff changeset
68 cmdline = util.quotecommand(' '.join(cmdline))
5355
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
69 self.ui.debug(cmdline, '\n')
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
70 return os.popen(cmdline, 'r')
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
71
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
72 def run(self, cmd, *args, **kwargs):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
73 fp = self._run(cmd, *args, **kwargs)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
74 output = fp.read()
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
75 return output, fp.close()
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
76
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
77 def checkexit(self, status, output=''):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
78 if status:
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
79 if output:
5357
4ad2a18aff42 convert: fix a few residual bugs in darcs importer
Bryan O'Sullivan <bos@serpentine.com>
parents: 5355
diff changeset
80 self.ui.warn(_('darcs error:\n'))
4ad2a18aff42 convert: fix a few residual bugs in darcs importer
Bryan O'Sullivan <bos@serpentine.com>
parents: 5355
diff changeset
81 self.ui.warn(output)
5355
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
82 msg = util.explain_exit(status)[0]
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
83 raise util.Abort(_('darcs %s') % msg)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
84
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
85 def xml(self, cmd, *opts):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
86 etree = ElementTree()
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
87 fp = self._run(cmd, *opts)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
88 etree.parse(fp)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
89 self.checkexit(fp.close())
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
90 return etree.getroot()
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
91
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
92 def getheads(self):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
93 return self.parents[None]
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
94
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
95 def getcommit(self, rev):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
96 elt = self.changes[rev]
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
97 date = util.strdate(elt.get('local_date'), '%a %b %d %H:%M:%S %Z %Y')
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
98 desc = elt.findtext('name') + '\n' + elt.findtext('comment', '')
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
99 return commit(author=elt.get('author'), date=util.datestr(date),
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
100 desc=desc.strip(), parents=self.parents[rev])
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
101
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
102 def pull(self, rev):
5412
fbf40ad5a8c2 convert: fix darcs_source.pull() under windows
Patrick Mezard <pmezard@gmail.com>
parents: 5411
diff changeset
103 output, status = self.run('pull', self.path, '--all',
fbf40ad5a8c2 convert: fix darcs_source.pull() under windows
Patrick Mezard <pmezard@gmail.com>
parents: 5411
diff changeset
104 '--match', 'hash %s' % rev,
5355
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
105 '--no-test', '--no-posthook',
5412
fbf40ad5a8c2 convert: fix darcs_source.pull() under windows
Patrick Mezard <pmezard@gmail.com>
parents: 5411
diff changeset
106 '--external-merge', '/bin/false',
5355
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
107 repodir=self.tmppath)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
108 if status:
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
109 if output.find('We have conflicts in') == -1:
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
110 self.checkexit(status, output)
5412
fbf40ad5a8c2 convert: fix darcs_source.pull() under windows
Patrick Mezard <pmezard@gmail.com>
parents: 5411
diff changeset
111 output, status = self.run('revert', '--all', repodir=self.tmppath)
5355
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
112 self.checkexit(status, output)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
113
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
114 def getchanges(self, rev):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
115 self.pull(rev)
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
116 copies = {}
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
117 changes = []
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
118 for elt in self.changes[rev].find('summary').getchildren():
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
119 if elt.tag in ('add_directory', 'remove_directory'):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
120 continue
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
121 if elt.tag == 'move':
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
122 changes.append((elt.get('from'), rev))
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
123 copies[elt.get('from')] = elt.get('to')
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
124 else:
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
125 changes.append((elt.text.strip(), rev))
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
126 changes.sort()
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
127 self.lastrev = rev
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
128 return changes, copies
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
129
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
130 def getfile(self, name, rev):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
131 if rev != self.lastrev:
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
132 raise util.Abort(_('internal calling inconsistency'))
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
133 return open(os.path.join(self.tmppath, name), 'rb').read()
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
134
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
135 def getmode(self, name, rev):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
136 mode = os.lstat(os.path.join(self.tmppath, name)).st_mode
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
137 return (mode & 0111) and 'x' or ''
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
138
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
139 def gettags(self):
6b6104430964 convert: support darcs as a source repo
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
140 return self.tags