Show More
@@ -7,7 +7,7 imerge - interactive merge | |||
|
7 | 7 | |
|
8 | 8 | from mercurial.i18n import _ |
|
9 | 9 | from mercurial.node import * |
|
10 | from mercurial import commands, cmdutil, fancyopts, hg, merge, util | |
|
10 | from mercurial import commands, cmdutil, dispatch, fancyopts, hg, merge, util | |
|
11 | 11 | import os, tarfile |
|
12 | 12 | |
|
13 | 13 | class InvalidStateFileException(Exception): pass |
@@ -109,12 +109,30 class Imerge(object): | |||
|
109 | 109 | def remaining(self): |
|
110 | 110 | return [f for f in self.conflicts if f not in self.resolved] |
|
111 | 111 | |
|
112 | def filemerge(self, fn): | |
|
112 | def filemerge(self, fn, interactive=True): | |
|
113 | 113 | wlock = self.repo.wlock() |
|
114 | 114 | |
|
115 | 115 | (fd, fo) = self.conflicts[fn] |
|
116 |
p2 = self.wctx.parents() |
|
|
117 | return merge.filemerge(self.repo, fn, fd, fo, self.wctx, p2) | |
|
116 | p1, p2 = self.wctx.parents() | |
|
117 | ||
|
118 | # this could be greatly improved | |
|
119 | realmerge = os.environ.get('HGMERGE') | |
|
120 | if not interactive: | |
|
121 | os.environ['HGMERGE'] = 'merge' | |
|
122 | ||
|
123 | # The filemerge ancestor algorithm does not work if self.wctx | |
|
124 | # already has two parents (in normal merge it doesn't yet). But | |
|
125 | # this is very dirty. | |
|
126 | self.wctx._parents.pop() | |
|
127 | try: | |
|
128 | # TODO: we should probably revert the file if merge fails | |
|
129 | return merge.filemerge(self.repo, fn, fd, fo, self.wctx, p2) | |
|
130 | finally: | |
|
131 | self.wctx._parents.append(p2) | |
|
132 | if realmerge: | |
|
133 | os.environ['HGMERGE'] = realmerge | |
|
134 | elif not interactive: | |
|
135 | del os.environ['HGMERGE'] | |
|
118 | 136 | |
|
119 | 137 | def start(self, rev=None): |
|
120 | 138 | _filemerge = merge.filemerge |
@@ -185,19 +203,32 def load(im, source): | |||
|
185 | 203 | status(im) |
|
186 | 204 | return rc |
|
187 | 205 | |
|
188 | def merge_(im, filename=None): | |
|
206 | def merge_(im, filename=None, auto=False): | |
|
207 | success = True | |
|
208 | if auto and not filename: | |
|
209 | for fn in im.remaining(): | |
|
210 | rc = im.filemerge(fn, interactive=False) | |
|
211 | if rc: | |
|
212 | success = False | |
|
213 | else: | |
|
214 | im.resolve([fn]) | |
|
215 | if success: | |
|
216 | im.ui.write('all conflicts resolved\n') | |
|
217 | else: | |
|
218 | status(im) | |
|
219 | return 0 | |
|
220 | ||
|
189 | 221 | if not filename: |
|
190 | 222 | filename = im.next() |
|
191 | 223 | if not filename: |
|
192 | 224 | im.ui.write('all conflicts resolved\n') |
|
193 | 225 | return 0 |
|
194 | 226 | |
|
195 | rc = im.filemerge(filename) | |
|
227 | rc = im.filemerge(filename, interactive=not auto) | |
|
196 | 228 | if not rc: |
|
197 | 229 | im.resolve([filename]) |
|
198 | 230 | if not im.next(): |
|
199 | 231 | im.ui.write('all conflicts resolved\n') |
|
200 | return 0 | |
|
201 | 232 | return rc |
|
202 | 233 | |
|
203 | 234 | def next(im): |
@@ -258,18 +289,21 def unresolve(im, *files): | |||
|
258 | 289 | |
|
259 | 290 | subcmdtable = { |
|
260 | 291 | 'load': (load, []), |
|
261 |
'merge': |
|
|
292 | 'merge': | |
|
293 | (merge_, | |
|
294 | [('a', 'auto', None, _('automatically resolve if possible'))]), | |
|
262 | 295 | 'next': (next, []), |
|
263 | 296 | 'resolve': (resolve, []), |
|
264 | 297 | 'save': (save, []), |
|
265 |
'status': |
|
|
266 | [('n', 'no-status', None, _('hide status prefix')), | |
|
267 | ('', 'resolved', None, _('only show resolved conflicts')), | |
|
268 |
|
|
|
298 | 'status': | |
|
299 | (status, | |
|
300 | [('n', 'no-status', None, _('hide status prefix')), | |
|
301 | ('', 'resolved', None, _('only show resolved conflicts')), | |
|
302 | ('', 'unresolved', None, _('only show unresolved conflicts'))]), | |
|
269 | 303 | 'unresolve': (unresolve, []) |
|
270 | 304 | } |
|
271 | 305 | |
|
272 | def dispatch(im, args, opts): | |
|
306 | def dispatch_(im, args, opts): | |
|
273 | 307 | def complete(s, choices): |
|
274 | 308 | candidates = [] |
|
275 | 309 | for choice in choices: |
@@ -292,9 +326,9 def dispatch(im, args, opts): | |||
|
292 | 326 | args = fancyopts.fancyopts(args, optlist, opts) |
|
293 | 327 | return func(im, *args, **opts) |
|
294 | 328 | except fancyopts.getopt.GetoptError, inst: |
|
295 |
raise |
|
|
329 | raise dispatch.ParseError('imerge', '%s: %s' % (cmd, inst)) | |
|
296 | 330 | except TypeError: |
|
297 |
raise |
|
|
331 | raise dispatch.ParseError('imerge', _('%s: invalid arguments') % cmd) | |
|
298 | 332 | |
|
299 | 333 | def imerge(ui, repo, *args, **opts): |
|
300 | 334 | '''interactive merge |
@@ -317,6 +351,10 def imerge(ui, repo, *args, **opts): | |||
|
317 | 351 | |
|
318 | 352 | status: |
|
319 | 353 | show the current state of the merge |
|
354 | options: | |
|
355 | -n --no-status: do not print the status prefix | |
|
356 | --resolved: only print resolved conflicts | |
|
357 | --unresolved: only print unresolved conflicts | |
|
320 | 358 | next: |
|
321 | 359 | show the next unresolved file merge |
|
322 | 360 | merge [<file>]: |
@@ -348,15 +386,20 def imerge(ui, repo, *args, **opts): | |||
|
348 | 386 | if args: |
|
349 | 387 | rev = args[0] |
|
350 | 388 | im.start(rev=rev) |
|
351 | args = ['status'] | |
|
389 | if opts.get('auto'): | |
|
390 | args = ['merge', '--auto'] | |
|
391 | else: | |
|
392 | args = ['status'] | |
|
352 | 393 | |
|
353 | 394 | if not args: |
|
354 | 395 | args = ['merge'] |
|
355 | 396 | |
|
356 | return dispatch(im, args, opts) | |
|
397 | return dispatch_(im, args, opts) | |
|
357 | 398 | |
|
358 | 399 | cmdtable = { |
|
359 | 400 | '^imerge': |
|
360 | 401 | (imerge, |
|
361 |
[('r', 'rev', '', _('revision to merge')) |
|
|
402 | [('r', 'rev', '', _('revision to merge')), | |
|
403 | ('a', 'auto', None, _('automatically merge where possible'))], | |
|
404 | 'hg imerge [command]') | |
|
362 | 405 | } |
General Comments 0
You need to be logged in to leave comments.
Login now