Mercurial > hg > mercurial-crew-with-dirclash
comparison hgext/imerge.py @ 5065:12930b97a729
imerge: gussy up dispatcher to support subcommand opts.
Add -n, --resolved, --unresolved to status.
author | Brendan Cully <brendan@kublai.com> |
---|---|
date | Sat, 04 Aug 2007 12:26:48 -0700 |
parents | 420e1166a876 |
children | d4fa6bafc43a |
comparison
equal
deleted
inserted
replaced
5064:420e1166a876 | 5065:12930b97a729 |
---|---|
5 imerge - interactive merge | 5 imerge - interactive merge |
6 ''' | 6 ''' |
7 | 7 |
8 from mercurial.i18n import _ | 8 from mercurial.i18n import _ |
9 from mercurial.node import * | 9 from mercurial.node import * |
10 from mercurial import commands, cmdutil, hg, merge, util | 10 from mercurial import commands, cmdutil, fancyopts, hg, merge, util |
11 import os, tarfile | 11 import os, tarfile |
12 | 12 |
13 class InvalidStateFileException(Exception): pass | 13 class InvalidStateFileException(Exception): pass |
14 | 14 |
15 class ImergeStateFile(object): | 15 class ImergeStateFile(object): |
132 | 132 |
133 dp = self.repo.dirstate.parents() | 133 dp = self.repo.dirstate.parents() |
134 p1, p2 = self.wctx.parents() | 134 p1, p2 = self.wctx.parents() |
135 if p1.node() != dp[0] or p2.node() != dp[1]: | 135 if p1.node() != dp[0] or p2.node() != dp[1]: |
136 raise util.Abort('imerge state does not match working directory') | 136 raise util.Abort('imerge state does not match working directory') |
137 | |
138 def status(self): | |
139 p1, p2 = self.wctx.parents() | |
140 self.ui.write('merging %s and %s\n' % \ | |
141 (short(p1.node()), short(p2.node()))) | |
142 | |
143 if self.resolved: | |
144 self.ui.write('resolved:\n') | |
145 for fn in self.resolved: | |
146 self.ui.write(' %s\n' % fn) | |
147 remaining = [f for f in self.conflicts if f not in self.resolved] | |
148 if remaining: | |
149 self.ui.write('remaining:\n') | |
150 for fn in remaining: | |
151 (fd, fo) = self.conflicts[fn] | |
152 if fn == fo: | |
153 self.ui.write(' %s\n' % (fn,)) | |
154 else: | |
155 self.ui.write(' %s (%s)\n' % (fn, fd)) | |
156 else: | |
157 self.ui.write('all conflicts resolved\n') | |
158 | 137 |
159 def next(self): | 138 def next(self): |
160 remaining = self.remaining() | 139 remaining = self.remaining() |
161 return remaining and remaining[0] | 140 return remaining and remaining[0] |
162 | 141 |
200 if m or a or r or d: | 179 if m or a or r or d: |
201 raise util.Abort('working directory has uncommitted changes') | 180 raise util.Abort('working directory has uncommitted changes') |
202 | 181 |
203 rc = im.unpickle(source) | 182 rc = im.unpickle(source) |
204 if not rc: | 183 if not rc: |
205 im.status() | 184 status(im) |
206 return rc | 185 return rc |
207 | 186 |
208 def merge_(im, filename=None): | 187 def merge_(im, filename=None): |
209 if not filename: | 188 if not filename: |
210 filename = im.next() | 189 filename = im.next() |
234 return im.resolve(files) | 213 return im.resolve(files) |
235 | 214 |
236 def save(im, dest): | 215 def save(im, dest): |
237 return im.pickle(dest) | 216 return im.pickle(dest) |
238 | 217 |
239 def status(im): | 218 def status(im, **opts): |
240 im.status() | 219 if not opts.get('resolved') and not opts.get('unresolved'): |
220 opts['resolved'] = True | |
221 opts['unresolved'] = True | |
222 | |
223 if im.ui.verbose: | |
224 p1, p2 = [short(p.node()) for p in im.wctx.parents()] | |
225 im.ui.note(_('merging %s and %s\n') % (p1, p2)) | |
226 | |
227 conflicts = im.conflicts.keys() | |
228 conflicts.sort() | |
229 remaining = dict.fromkeys(im.remaining()) | |
230 st = [] | |
231 for fn in conflicts: | |
232 if opts.get('no_status'): | |
233 mode = '' | |
234 elif fn in remaining: | |
235 mode = 'U ' | |
236 else: | |
237 mode = 'R ' | |
238 if ((opts.get('resolved') and fn not in remaining) | |
239 or (opts.get('unresolved') and fn in remaining)): | |
240 st.append((mode, fn)) | |
241 st.sort() | |
242 for (mode, fn) in st: | |
243 if im.ui.verbose: | |
244 fo, fd = im.conflicts[fn] | |
245 if fd != fn: | |
246 fn = '%s (%s)' % (fn, fd) | |
247 im.ui.write('%s%s\n' % (mode, fn)) | |
248 if opts.get('unresolved') and not remaining: | |
249 im.ui.write(_('all conflicts resolved\n')) | |
250 | |
241 return 0 | 251 return 0 |
242 | 252 |
243 def unresolve(im, *files): | 253 def unresolve(im, *files): |
244 if not files: | 254 if not files: |
245 raise util.Abort('unresolve requires at least one filename') | 255 raise util.Abort('unresolve requires at least one filename') |
246 return im.unresolve(files) | 256 return im.unresolve(files) |
247 | 257 |
248 subcmdtable = { | 258 subcmdtable = { |
249 'load': load, | 259 'load': (load, []), |
250 'merge': merge_, | 260 'merge': (merge_, []), |
251 'next': next, | 261 'next': (next, []), |
252 'resolve': resolve, | 262 'resolve': (resolve, []), |
253 'save': save, | 263 'save': (save, []), |
254 'status': status, | 264 'status': (status, |
255 'unresolve': unresolve | 265 [('n', 'no-status', None, _('hide status prefix')), |
266 ('', 'resolved', None, _('only show resolved conflicts')), | |
267 ('', 'unresolved', None, _('only show unresolved conflicts'))]), | |
268 'unresolve': (unresolve, []) | |
256 } | 269 } |
257 | 270 |
258 def dispatch(im, args, opts): | 271 def dispatch(im, args, opts): |
259 def complete(s, choices): | 272 def complete(s, choices): |
260 candidates = [] | 273 candidates = [] |
261 for choice in choices: | 274 for choice in choices: |
262 if choice.startswith(s): | 275 if choice.startswith(s): |
263 candidates.append(choice) | 276 candidates.append(choice) |
264 return candidates | 277 return candidates |
265 | 278 |
266 c, args = args[0], args[1:] | 279 c, args = args[0], list(args[1:]) |
267 cmd = complete(c, subcmdtable.keys()) | 280 cmd = complete(c, subcmdtable.keys()) |
268 if not cmd: | 281 if not cmd: |
269 raise cmdutil.UnknownCommand('imerge ' + c) | 282 raise cmdutil.UnknownCommand('imerge ' + c) |
270 if len(cmd) > 1: | 283 if len(cmd) > 1: |
271 cmd.sort() | 284 cmd.sort() |
272 raise cmdutil.AmbiguousCommand('imerge ' + c, cmd) | 285 raise cmdutil.AmbiguousCommand('imerge ' + c, cmd) |
273 cmd = cmd[0] | 286 cmd = cmd[0] |
274 | 287 |
275 func = subcmdtable[cmd] | 288 func, optlist = subcmdtable[cmd] |
289 opts = {} | |
276 try: | 290 try: |
277 return func(im, *args) | 291 args = fancyopts.fancyopts(args, optlist, opts) |
292 return func(im, *args, **opts) | |
293 except fancyopts.getopt.GetoptError, inst: | |
294 raise cmdutil.ParseError('imerge', '%s: %s' % (cmd, inst)) | |
278 except TypeError: | 295 except TypeError: |
279 raise cmdutil.ParseError('imerge', '%s: invalid arguments' % cmd) | 296 raise cmdutil.ParseError('imerge', _('%s: invalid arguments') % cmd) |
280 | 297 |
281 def imerge(ui, repo, *args, **opts): | 298 def imerge(ui, repo, *args, **opts): |
282 '''interactive merge | 299 '''interactive merge |
283 | 300 |
284 imerge lets you split a merge into pieces. When you start a merge | 301 imerge lets you split a merge into pieces. When you start a merge |