comparison hgext/imerge.py @ 5223:3786ef8877d5

imerge: add automerge flag to attempt to batch merge all conflicts
author Brendan Cully <brendan@kublai.com>
date Thu, 23 Aug 2007 22:45:41 -0700
parents 8860f29447c1
children
comparison
equal deleted inserted replaced
5222:85ba6ab5bd3a 5223:3786ef8877d5
107 statusfile.write('\0'.join(out)) 107 statusfile.write('\0'.join(out))
108 108
109 def remaining(self): 109 def remaining(self):
110 return [f for f in self.conflicts if f not in self.resolved] 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 wlock = self.repo.wlock() 113 wlock = self.repo.wlock()
114 114
115 (fd, fo) = self.conflicts[fn] 115 (fd, fo) = self.conflicts[fn]
116 p1, p2 = self.wctx.parents() 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
117 # The filemerge ancestor algorithm does not work if self.wctx 123 # The filemerge ancestor algorithm does not work if self.wctx
118 # already has two parents (in normal merge it doesn't yet). But 124 # already has two parents (in normal merge it doesn't yet). But
119 # this is very dirty. 125 # this is very dirty.
120 self.wctx._parents.pop() 126 self.wctx._parents.pop()
121 try: 127 try:
128 # TODO: we should probably revert the file if merge fails
122 return merge.filemerge(self.repo, fn, fd, fo, self.wctx, p2) 129 return merge.filemerge(self.repo, fn, fd, fo, self.wctx, p2)
123 finally: 130 finally:
124 self.wctx._parents.append(p2) 131 self.wctx._parents.append(p2)
132 if realmerge:
133 os.environ['HGMERGE'] = realmerge
134 elif not interactive:
135 del os.environ['HGMERGE']
125 136
126 def start(self, rev=None): 137 def start(self, rev=None):
127 _filemerge = merge.filemerge 138 _filemerge = merge.filemerge
128 def filemerge(repo, fw, fd, fo, wctx, mctx): 139 def filemerge(repo, fw, fd, fo, wctx, mctx):
129 self.conflicts[fw] = (fd, fo) 140 self.conflicts[fw] = (fd, fo)
190 rc = im.unpickle(source) 201 rc = im.unpickle(source)
191 if not rc: 202 if not rc:
192 status(im) 203 status(im)
193 return rc 204 return rc
194 205
195 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
196 if not filename: 221 if not filename:
197 filename = im.next() 222 filename = im.next()
198 if not filename: 223 if not filename:
199 im.ui.write('all conflicts resolved\n') 224 im.ui.write('all conflicts resolved\n')
200 return 0 225 return 0
201 226
202 rc = im.filemerge(filename) 227 rc = im.filemerge(filename, interactive=not auto)
203 if not rc: 228 if not rc:
204 im.resolve([filename]) 229 im.resolve([filename])
205 if not im.next(): 230 if not im.next():
206 im.ui.write('all conflicts resolved\n') 231 im.ui.write('all conflicts resolved\n')
207 return 0
208 return rc 232 return rc
209 233
210 def next(im): 234 def next(im):
211 n = im.next() 235 n = im.next()
212 if n: 236 if n:
263 raise util.Abort('unresolve requires at least one filename') 287 raise util.Abort('unresolve requires at least one filename')
264 return im.unresolve(files) 288 return im.unresolve(files)
265 289
266 subcmdtable = { 290 subcmdtable = {
267 'load': (load, []), 291 'load': (load, []),
268 'merge': (merge_, []), 292 'merge':
293 (merge_,
294 [('a', 'auto', None, _('automatically resolve if possible'))]),
269 'next': (next, []), 295 'next': (next, []),
270 'resolve': (resolve, []), 296 'resolve': (resolve, []),
271 'save': (save, []), 297 'save': (save, []),
272 'status': (status, 298 'status':
273 [('n', 'no-status', None, _('hide status prefix')), 299 (status,
274 ('', 'resolved', None, _('only show resolved conflicts')), 300 [('n', 'no-status', None, _('hide status prefix')),
275 ('', 'unresolved', None, _('only show unresolved conflicts'))]), 301 ('', 'resolved', None, _('only show resolved conflicts')),
302 ('', 'unresolved', None, _('only show unresolved conflicts'))]),
276 'unresolve': (unresolve, []) 303 'unresolve': (unresolve, [])
277 } 304 }
278 305
279 def dispatch_(im, args, opts): 306 def dispatch_(im, args, opts):
280 def complete(s, choices): 307 def complete(s, choices):
357 pass 384 pass
358 else: 385 else:
359 if args: 386 if args:
360 rev = args[0] 387 rev = args[0]
361 im.start(rev=rev) 388 im.start(rev=rev)
362 args = ['status'] 389 if opts.get('auto'):
390 args = ['merge', '--auto']
391 else:
392 args = ['status']
363 393
364 if not args: 394 if not args:
365 args = ['merge'] 395 args = ['merge']
366 396
367 return dispatch_(im, args, opts) 397 return dispatch_(im, args, opts)
368 398
369 cmdtable = { 399 cmdtable = {
370 '^imerge': 400 '^imerge':
371 (imerge, 401 (imerge,
372 [('r', 'rev', '', _('revision to merge'))], 'hg imerge [command]') 402 [('r', 'rev', '', _('revision to merge')),
403 ('a', 'auto', None, _('automatically merge where possible'))],
404 'hg imerge [command]')
373 } 405 }