Mercurial > hg
annotate hgext/imerge.py @ 5239:8860f29447c1
imerge: fix ancestor calculation
If wctx already has two parents, ancestor calculation is wrong.
Normally merge is called before wctx gets the second parent, so
we simulate this in imerge by temporarily popping the second parent
before calling filemerge. Highly dirty.
This patch also handles the ParseError move from cmdutil to dispatch.
author | Brendan Cully <brendan@kublai.com> |
---|---|
date | Thu, 23 Aug 2007 19:51:59 -0700 |
parents | ec24bfd852ab |
children | 3786ef8877d5 |
rev | line source |
---|---|
5044 | 1 # Copyright (C) 2007 Brendan Cully <brendan@kublai.com> |
2 # Published under the GNU GPL | |
3 | |
4 ''' | |
5 imerge - interactive merge | |
6 ''' | |
7 | |
8 from mercurial.i18n import _ | |
9 from mercurial.node import * | |
5239
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
10 from mercurial import commands, cmdutil, dispatch, fancyopts, hg, merge, util |
5044 | 11 import os, tarfile |
12 | |
13 class InvalidStateFileException(Exception): pass | |
14 | |
15 class ImergeStateFile(object): | |
16 def __init__(self, im): | |
17 self.im = im | |
18 | |
19 def save(self, dest): | |
20 tf = tarfile.open(dest, 'w:gz') | |
21 | |
22 st = os.path.join(self.im.path, 'status') | |
23 tf.add(st, os.path.join('.hg', 'imerge', 'status')) | |
24 | |
25 for f in self.im.resolved: | |
5109 | 26 (fd, fo) = self.im.conflicts[f] |
27 abssrc = self.im.repo.wjoin(fd) | |
28 tf.add(abssrc, fd) | |
5044 | 29 |
30 tf.close() | |
31 | |
32 def load(self, source): | |
33 wlock = self.im.repo.wlock() | |
34 lock = self.im.repo.lock() | |
35 | |
36 tf = tarfile.open(source, 'r') | |
37 contents = tf.getnames() | |
5164
1d5ebb0d366f
imerge: fix status file lookups
Patrick Mezard <pmezard@gmail.com>
parents:
5143
diff
changeset
|
38 # tarfile normalizes path separators to '/' |
5165
ec24bfd852ab
imerge: simplify 1d5ebb0d366f
Brendan Cully <brendan@kublai.com>
parents:
5164
diff
changeset
|
39 statusfile = '.hg/imerge/status' |
5044 | 40 if statusfile not in contents: |
41 raise InvalidStateFileException('no status file') | |
42 | |
43 tf.extract(statusfile, self.im.repo.root) | |
5109 | 44 p1, p2 = self.im.load() |
45 if self.im.repo.dirstate.parents()[0] != p1.node(): | |
46 hg.clean(self.im.repo, p1.node()) | |
47 self.im.start(p2.node()) | |
5055
56d48aed1f69
imerge: tarfile.extractall is only available in python2.5
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
5054
diff
changeset
|
48 for tarinfo in tf: |
56d48aed1f69
imerge: tarfile.extractall is only available in python2.5
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
5054
diff
changeset
|
49 tf.extract(tarinfo, self.im.repo.root) |
5044 | 50 self.im.load() |
51 | |
52 class Imerge(object): | |
53 def __init__(self, ui, repo): | |
54 self.ui = ui | |
55 self.repo = repo | |
56 | |
57 self.path = repo.join('imerge') | |
58 self.opener = util.opener(self.path) | |
59 | |
5109 | 60 self.wctx = self.repo.workingctx() |
5044 | 61 self.conflicts = {} |
62 self.resolved = [] | |
63 | |
64 def merging(self): | |
5109 | 65 return len(self.wctx.parents()) > 1 |
5044 | 66 |
67 def load(self): | |
68 # status format. \0-delimited file, fields are | |
69 # p1, p2, conflict count, conflict filenames, resolved filenames | |
5054
ec70fd08e16c
Update imerge for new filemerge interface
Brendan Cully <brendan@kublai.com>
parents:
5044
diff
changeset
|
70 # conflict filenames are tuples of localname, remoteorig, remotenew |
5044 | 71 |
72 statusfile = self.opener('status') | |
73 | |
74 status = statusfile.read().split('\0') | |
75 if len(status) < 3: | |
76 raise util.Abort('invalid imerge status file') | |
77 | |
78 try: | |
5109 | 79 parents = [self.repo.changectx(n) for n in status[:2]] |
5044 | 80 except LookupError: |
81 raise util.Abort('merge parent %s not in repository' % short(p)) | |
82 | |
83 status = status[2:] | |
5054
ec70fd08e16c
Update imerge for new filemerge interface
Brendan Cully <brendan@kublai.com>
parents:
5044
diff
changeset
|
84 conflicts = int(status.pop(0)) * 3 |
5044 | 85 self.resolved = status[conflicts:] |
5054
ec70fd08e16c
Update imerge for new filemerge interface
Brendan Cully <brendan@kublai.com>
parents:
5044
diff
changeset
|
86 for i in xrange(0, conflicts, 3): |
ec70fd08e16c
Update imerge for new filemerge interface
Brendan Cully <brendan@kublai.com>
parents:
5044
diff
changeset
|
87 self.conflicts[status[i]] = (status[i+1], status[i+2]) |
5044 | 88 |
5109 | 89 return parents |
90 | |
5044 | 91 def save(self): |
92 lock = self.repo.lock() | |
93 | |
94 if not os.path.isdir(self.path): | |
95 os.mkdir(self.path) | |
5056
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
96 statusfile = self.opener('status', 'wb') |
5044 | 97 |
5109 | 98 out = [hex(n.node()) for n in self.wctx.parents()] |
5044 | 99 out.append(str(len(self.conflicts))) |
5056
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
100 conflicts = self.conflicts.items() |
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
101 conflicts.sort() |
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
102 for fw, fd_fo in conflicts: |
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
103 out.append(fw) |
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
104 out.extend(fd_fo) |
5044 | 105 out.extend(self.resolved) |
106 | |
5056
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
107 statusfile.write('\0'.join(out)) |
5044 | 108 |
109 def remaining(self): | |
110 return [f for f in self.conflicts if f not in self.resolved] | |
111 | |
112 def filemerge(self, fn): | |
113 wlock = self.repo.wlock() | |
114 | |
5054
ec70fd08e16c
Update imerge for new filemerge interface
Brendan Cully <brendan@kublai.com>
parents:
5044
diff
changeset
|
115 (fd, fo) = self.conflicts[fn] |
5239
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
116 p1, p2 = self.wctx.parents() |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
117 # The filemerge ancestor algorithm does not work if self.wctx |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
118 # already has two parents (in normal merge it doesn't yet). But |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
119 # this is very dirty. |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
120 self.wctx._parents.pop() |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
121 try: |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
122 return merge.filemerge(self.repo, fn, fd, fo, self.wctx, p2) |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
123 finally: |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
124 self.wctx._parents.append(p2) |
5044 | 125 |
126 def start(self, rev=None): | |
127 _filemerge = merge.filemerge | |
5054
ec70fd08e16c
Update imerge for new filemerge interface
Brendan Cully <brendan@kublai.com>
parents:
5044
diff
changeset
|
128 def filemerge(repo, fw, fd, fo, wctx, mctx): |
ec70fd08e16c
Update imerge for new filemerge interface
Brendan Cully <brendan@kublai.com>
parents:
5044
diff
changeset
|
129 self.conflicts[fw] = (fd, fo) |
5044 | 130 |
131 merge.filemerge = filemerge | |
132 commands.merge(self.ui, self.repo, rev=rev) | |
133 merge.filemerge = _filemerge | |
134 | |
5109 | 135 self.wctx = self.repo.workingctx() |
5044 | 136 self.save() |
137 | |
138 def resume(self): | |
139 self.load() | |
140 | |
141 dp = self.repo.dirstate.parents() | |
5109 | 142 p1, p2 = self.wctx.parents() |
143 if p1.node() != dp[0] or p2.node() != dp[1]: | |
5044 | 144 raise util.Abort('imerge state does not match working directory') |
145 | |
146 def next(self): | |
147 remaining = self.remaining() | |
148 return remaining and remaining[0] | |
149 | |
150 def resolve(self, files): | |
151 resolved = dict.fromkeys(self.resolved) | |
152 for fn in files: | |
153 if fn not in self.conflicts: | |
154 raise util.Abort('%s is not in the merge set' % fn) | |
155 resolved[fn] = True | |
5056
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
156 self.resolved = resolved.keys() |
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
157 self.resolved.sort() |
5044 | 158 self.save() |
159 return 0 | |
160 | |
161 def unresolve(self, files): | |
162 resolved = dict.fromkeys(self.resolved) | |
163 for fn in files: | |
164 if fn not in resolved: | |
165 raise util.Abort('%s is not resolved' % fn) | |
166 del resolved[fn] | |
5056
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
167 self.resolved = resolved.keys() |
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
168 self.resolved.sort() |
5044 | 169 self.save() |
170 return 0 | |
171 | |
172 def pickle(self, dest): | |
173 '''write current merge state to file to be resumed elsewhere''' | |
174 state = ImergeStateFile(self) | |
175 return state.save(dest) | |
176 | |
177 def unpickle(self, source): | |
178 '''read merge state from file''' | |
179 state = ImergeStateFile(self) | |
180 return state.load(source) | |
181 | |
182 def load(im, source): | |
183 if im.merging(): | |
184 raise util.Abort('there is already a merge in progress ' | |
185 '(update -C <rev> to abort it)' ) | |
186 m, a, r, d = im.repo.status()[:4] | |
187 if m or a or r or d: | |
188 raise util.Abort('working directory has uncommitted changes') | |
189 | |
190 rc = im.unpickle(source) | |
191 if not rc: | |
5111
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
192 status(im) |
5044 | 193 return rc |
194 | |
195 def merge_(im, filename=None): | |
196 if not filename: | |
197 filename = im.next() | |
198 if not filename: | |
199 im.ui.write('all conflicts resolved\n') | |
200 return 0 | |
201 | |
202 rc = im.filemerge(filename) | |
203 if not rc: | |
204 im.resolve([filename]) | |
205 if not im.next(): | |
206 im.ui.write('all conflicts resolved\n') | |
207 return 0 | |
208 return rc | |
209 | |
210 def next(im): | |
211 n = im.next() | |
212 if n: | |
213 im.ui.write('%s\n' % n) | |
214 else: | |
215 im.ui.write('all conflicts resolved\n') | |
216 return 0 | |
217 | |
218 def resolve(im, *files): | |
219 if not files: | |
220 raise util.Abort('resolve requires at least one filename') | |
221 return im.resolve(files) | |
222 | |
223 def save(im, dest): | |
224 return im.pickle(dest) | |
225 | |
5111
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
226 def status(im, **opts): |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
227 if not opts.get('resolved') and not opts.get('unresolved'): |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
228 opts['resolved'] = True |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
229 opts['unresolved'] = True |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
230 |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
231 if im.ui.verbose: |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
232 p1, p2 = [short(p.node()) for p in im.wctx.parents()] |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
233 im.ui.note(_('merging %s and %s\n') % (p1, p2)) |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
234 |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
235 conflicts = im.conflicts.keys() |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
236 conflicts.sort() |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
237 remaining = dict.fromkeys(im.remaining()) |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
238 st = [] |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
239 for fn in conflicts: |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
240 if opts.get('no_status'): |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
241 mode = '' |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
242 elif fn in remaining: |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
243 mode = 'U ' |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
244 else: |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
245 mode = 'R ' |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
246 if ((opts.get('resolved') and fn not in remaining) |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
247 or (opts.get('unresolved') and fn in remaining)): |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
248 st.append((mode, fn)) |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
249 st.sort() |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
250 for (mode, fn) in st: |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
251 if im.ui.verbose: |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
252 fo, fd = im.conflicts[fn] |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
253 if fd != fn: |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
254 fn = '%s (%s)' % (fn, fd) |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
255 im.ui.write('%s%s\n' % (mode, fn)) |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
256 if opts.get('unresolved') and not remaining: |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
257 im.ui.write(_('all conflicts resolved\n')) |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
258 |
5044 | 259 return 0 |
260 | |
261 def unresolve(im, *files): | |
262 if not files: | |
263 raise util.Abort('unresolve requires at least one filename') | |
264 return im.unresolve(files) | |
265 | |
266 subcmdtable = { | |
5111
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
267 'load': (load, []), |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
268 'merge': (merge_, []), |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
269 'next': (next, []), |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
270 'resolve': (resolve, []), |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
271 'save': (save, []), |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
272 'status': (status, |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
273 [('n', 'no-status', None, _('hide status prefix')), |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
274 ('', 'resolved', None, _('only show resolved conflicts')), |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
275 ('', 'unresolved', None, _('only show unresolved conflicts'))]), |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
276 'unresolve': (unresolve, []) |
5044 | 277 } |
278 | |
5239
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
279 def dispatch_(im, args, opts): |
5044 | 280 def complete(s, choices): |
281 candidates = [] | |
282 for choice in choices: | |
283 if choice.startswith(s): | |
284 candidates.append(choice) | |
285 return candidates | |
286 | |
5111
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
287 c, args = args[0], list(args[1:]) |
5044 | 288 cmd = complete(c, subcmdtable.keys()) |
289 if not cmd: | |
290 raise cmdutil.UnknownCommand('imerge ' + c) | |
291 if len(cmd) > 1: | |
5056
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
292 cmd.sort() |
34a54cc5df1b
imerge: sorted() is only available in python2.4 and above
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5055
diff
changeset
|
293 raise cmdutil.AmbiguousCommand('imerge ' + c, cmd) |
5044 | 294 cmd = cmd[0] |
295 | |
5111
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
296 func, optlist = subcmdtable[cmd] |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
297 opts = {} |
5044 | 298 try: |
5111
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
299 args = fancyopts.fancyopts(args, optlist, opts) |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
300 return func(im, *args, **opts) |
12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Brendan Cully <brendan@kublai.com>
parents:
5110
diff
changeset
|
301 except fancyopts.getopt.GetoptError, inst: |
5239
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
302 raise dispatch.ParseError('imerge', '%s: %s' % (cmd, inst)) |
5044 | 303 except TypeError: |
5239
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
304 raise dispatch.ParseError('imerge', _('%s: invalid arguments') % cmd) |
5044 | 305 |
306 def imerge(ui, repo, *args, **opts): | |
307 '''interactive merge | |
308 | |
309 imerge lets you split a merge into pieces. When you start a merge | |
310 with imerge, the names of all files with conflicts are recorded. | |
311 You can then merge any of these files, and if the merge is | |
312 successful, they will be marked as resolved. When all files are | |
313 resolved, the merge is complete. | |
314 | |
315 If no merge is in progress, hg imerge [rev] will merge the working | |
316 directory with rev (defaulting to the other head if the repository | |
317 only has two heads). You may also resume a saved merge with | |
318 hg imerge load <file>. | |
319 | |
320 If a merge is in progress, hg imerge will default to merging the | |
321 next unresolved file. | |
322 | |
323 The following subcommands are available: | |
324 | |
325 status: | |
326 show the current state of the merge | |
5239
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
327 options: |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
328 -n --no-status: do not print the status prefix |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
329 --resolved: only print resolved conflicts |
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
330 --unresolved: only print unresolved conflicts |
5044 | 331 next: |
332 show the next unresolved file merge | |
333 merge [<file>]: | |
334 merge <file>. If the file merge is successful, the file will be | |
335 recorded as resolved. If no file is given, the next unresolved | |
336 file will be merged. | |
337 resolve <file>...: | |
338 mark files as successfully merged | |
339 unresolve <file>...: | |
340 mark files as requiring merging. | |
341 save <file>: | |
342 save the state of the merge to a file to be resumed elsewhere | |
343 load <file>: | |
344 load the state of the merge from a file created by save | |
345 ''' | |
346 | |
347 im = Imerge(ui, repo) | |
348 | |
349 if im.merging(): | |
350 im.resume() | |
351 else: | |
352 rev = opts.get('rev') | |
353 if rev and args: | |
354 raise util.Abort('please specify just one revision') | |
5143
d4fa6bafc43a
Remove trailing spaces, fix indentation
Thomas Arendsen Hein <thomas@intevation.de>
parents:
5111
diff
changeset
|
355 |
5044 | 356 if len(args) == 2 and args[0] == 'load': |
357 pass | |
358 else: | |
359 if args: | |
360 rev = args[0] | |
361 im.start(rev=rev) | |
362 args = ['status'] | |
363 | |
364 if not args: | |
365 args = ['merge'] | |
366 | |
5239
8860f29447c1
imerge: fix ancestor calculation
Brendan Cully <brendan@kublai.com>
parents:
5165
diff
changeset
|
367 return dispatch_(im, args, opts) |
5044 | 368 |
369 cmdtable = { | |
370 '^imerge': | |
371 (imerge, | |
372 [('r', 'rev', '', _('revision to merge'))], 'hg imerge [command]') | |
373 } |