41 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']] |
41 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']] |
42 cwd = '' |
42 cwd = '' |
43 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'), |
43 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'), |
44 opts.get('exclude'), head) |
44 opts.get('exclude'), head) |
45 |
45 |
46 def makewalk(repo, pats, opts, node=None, head=''): |
46 def makewalk(repo, pats, opts, node=None, head='', badmatch=None): |
47 files, matchfn, anypats = matchpats(repo, pats, opts, head) |
47 files, matchfn, anypats = matchpats(repo, pats, opts, head) |
48 exact = dict(zip(files, files)) |
48 exact = dict(zip(files, files)) |
49 def walk(): |
49 def walk(): |
50 for src, fn in repo.walk(node=node, files=files, match=matchfn): |
50 for src, fn in repo.walk(node=node, files=files, match=matchfn, |
|
51 badmatch=None): |
51 yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact |
52 yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact |
52 return files, matchfn, walk() |
53 return files, matchfn, walk() |
53 |
54 |
54 def walk(repo, pats, opts, node=None, head=''): |
55 def walk(repo, pats, opts, node=None, head='', badmatch=None): |
55 files, matchfn, results = makewalk(repo, pats, opts, node, head) |
56 files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch) |
56 for r in results: |
57 for r in results: |
57 yield r |
58 yield r |
58 |
59 |
59 def walkchangerevs(ui, repo, pats, opts): |
60 def walkchangerevs(ui, repo, pats, opts): |
60 '''Iterate over files and the revs they changed in. |
61 '''Iterate over files and the revs they changed in. |
2001 requested revision. Files that changed between either parent are |
2002 requested revision. Files that changed between either parent are |
2002 marked as changed for the next commit and a commit must be |
2003 marked as changed for the next commit and a commit must be |
2003 performed before any further updates are allowed. |
2004 performed before any further updates are allowed. |
2004 """ |
2005 """ |
2005 return update(ui, repo, node=node, merge=True, **opts) |
2006 return update(ui, repo, node=node, merge=True, **opts) |
2006 |
2007 |
2007 def outgoing(ui, repo, dest="default-push", **opts): |
2008 def outgoing(ui, repo, dest="default-push", **opts): |
2008 """show changesets not found in destination |
2009 """show changesets not found in destination |
2009 |
2010 |
2010 Show changesets not found in the specified destination repository or |
2011 Show changesets not found in the specified destination repository or |
2011 the default push location. These are the changesets that would be pushed |
2012 the default push location. These are the changesets that would be pushed |
2284 |
2285 |
2285 In its default mode, it reverts any uncommitted modifications made |
2286 In its default mode, it reverts any uncommitted modifications made |
2286 to the named files or directories. This restores the contents of |
2287 to the named files or directories. This restores the contents of |
2287 the affected files to an unmodified state. |
2288 the affected files to an unmodified state. |
2288 |
2289 |
|
2290 Modified files have backup copies saved before revert. To disable |
|
2291 backups, use --no-backup. To change the name of backup files, use |
|
2292 --backup to give a format string. |
|
2293 |
2289 Using the -r option, it reverts the given files or directories to |
2294 Using the -r option, it reverts the given files or directories to |
2290 their state as of an earlier revision. This can be helpful to "roll |
2295 their state as of an earlier revision. This can be helpful to "roll |
2291 back" some or all of a change that should not have been committed. |
2296 back" some or all of a change that should not have been committed. |
2292 |
2297 |
2293 Revert modifies the working directory. It does not commit any |
2298 Revert modifies the working directory. It does not commit any |
2298 |
2303 |
2299 If names are given, all files matching the names are reverted. |
2304 If names are given, all files matching the names are reverted. |
2300 |
2305 |
2301 If no arguments are given, all files in the repository are reverted. |
2306 If no arguments are given, all files in the repository are reverted. |
2302 """ |
2307 """ |
2303 node = opts['rev'] and repo.lookup(opts['rev']) or \ |
2308 parent = repo.dirstate.parents()[0] |
2304 repo.dirstate.parents()[0] |
2309 node = opts['rev'] and repo.lookup(opts['rev']) or parent |
2305 |
2310 mf = repo.manifest.read(repo.changelog.read(node)[0]) |
2306 files, choose, anypats = matchpats(repo, pats, opts) |
2311 |
2307 modified, added, removed, deleted, unknown = repo.changes(match=choose) |
2312 def backup(name, exact): |
2308 repo.forget(added) |
2313 bakname = make_filename(repo, repo.changelog, |
2309 repo.undelete(removed) |
2314 opts['backup_name'] or '%p.orig', |
2310 |
2315 node=parent, pathname=name) |
2311 return repo.update(node, False, True, choose, False) |
2316 if os.path.exists(name): |
|
2317 # if backup already exists and is same as backup we want |
|
2318 # to make, do nothing |
|
2319 if os.path.exists(bakname): |
|
2320 if repo.wread(name) == repo.wread(bakname): |
|
2321 return |
|
2322 raise util.Abort(_('cannot save current version of %s - ' |
|
2323 '%s exists and differs') % |
|
2324 (name, bakname)) |
|
2325 ui.status(('saving current version of %s as %s\n') % |
|
2326 (name, bakname)) |
|
2327 shutil.copyfile(name, bakname) |
|
2328 shutil.copymode(name, bakname) |
|
2329 |
|
2330 wlock = repo.wlock() |
|
2331 |
|
2332 entries = [] |
|
2333 names = {} |
|
2334 for src, abs, rel, exact in walk(repo, pats, opts, badmatch=mf.has_key): |
|
2335 names[abs] = True |
|
2336 entries.append((abs, rel, exact)) |
|
2337 |
|
2338 changes = repo.changes(match=names.has_key, wlock=wlock) |
|
2339 modified, added, removed, deleted, unknown = map(dict.fromkeys, changes) |
|
2340 |
|
2341 revert = ([], _('reverting %s\n')) |
|
2342 add = ([], _('adding %s\n')) |
|
2343 remove = ([], _('removing %s\n')) |
|
2344 forget = ([], _('forgetting %s\n')) |
|
2345 undelete = ([], _('undeleting %s\n')) |
|
2346 update = {} |
|
2347 |
|
2348 disptable = ( |
|
2349 # dispatch table: |
|
2350 # file state |
|
2351 # action if in target manifest |
|
2352 # action if not in target manifest |
|
2353 # make backup if in target manifest |
|
2354 # make backup if not in target manifest |
|
2355 (modified, revert, remove, True, True), |
|
2356 (added, revert, forget, True, True), |
|
2357 (removed, undelete, None, False, False), |
|
2358 (deleted, revert, remove, False, False), |
|
2359 (unknown, add, None, True, False), |
|
2360 ) |
|
2361 |
|
2362 for abs, rel, exact in entries: |
|
2363 def handle(xlist, dobackup): |
|
2364 xlist[0].append(abs) |
|
2365 if dobackup and not opts['no_backup']: |
|
2366 backup(rel, exact) |
|
2367 if ui.verbose or not exact: |
|
2368 ui.status(xlist[1] % rel) |
|
2369 for table, hitlist, misslist, backuphit, backupmiss in disptable: |
|
2370 if abs not in table: continue |
|
2371 # file has changed in dirstate |
|
2372 if abs in mf: |
|
2373 handle(hitlist, backuphit) |
|
2374 elif misslist is not None: |
|
2375 handle(misslist, backupmiss) |
|
2376 else: |
|
2377 if exact: ui.warn(_('file not managed: %s\n' % rel)) |
|
2378 break |
|
2379 else: |
|
2380 # file has not changed in dirstate |
|
2381 if node == parent: |
|
2382 if exact: ui.warn(_('no changes needed to %s\n' % rel)) |
|
2383 continue |
|
2384 if abs not in mf: |
|
2385 remove[0].append(abs) |
|
2386 update[abs] = True |
|
2387 |
|
2388 repo.dirstate.forget(forget[0]) |
|
2389 r = repo.update(node, False, True, update.has_key, False, wlock=wlock) |
|
2390 repo.dirstate.update(add[0], 'a') |
|
2391 repo.dirstate.update(undelete[0], 'n') |
|
2392 repo.dirstate.update(remove[0], 'r') |
|
2393 return r |
2312 |
2394 |
2313 def root(ui, repo): |
2395 def root(ui, repo): |
2314 """print the root (top) of the current working dir |
2396 """print the root (top) of the current working dir |
2315 |
2397 |
2316 Print the root directory of the current repository. |
2398 Print the root directory of the current repository. |
2927 ('X', 'exclude', [], _('exclude names matching the given patterns'))], |
3009 ('X', 'exclude', [], _('exclude names matching the given patterns'))], |
2928 _('hg rename [OPTION]... SOURCE... DEST')), |
3010 _('hg rename [OPTION]... SOURCE... DEST')), |
2929 "^revert": |
3011 "^revert": |
2930 (revert, |
3012 (revert, |
2931 [('r', 'rev', '', _('revision to revert to')), |
3013 [('r', 'rev', '', _('revision to revert to')), |
2932 ('I', 'include', [], _('include names matching the given patterns')), |
3014 ('', 'backup-name', '', _('save backup with formatted name')), |
2933 ('X', 'exclude', [], _('exclude names matching the given patterns'))], |
3015 ('', 'no-backup', None, _('do not save backup copies of files')), |
|
3016 ('I', 'include', [], _('include names matching given patterns')), |
|
3017 ('X', 'exclude', [], _('exclude names matching given patterns'))], |
2934 _('hg revert [-r REV] [NAME]...')), |
3018 _('hg revert [-r REV] [NAME]...')), |
2935 "root": (root, [], _('hg root')), |
3019 "root": (root, [], _('hg root')), |
2936 "^serve": |
3020 "^serve": |
2937 (serve, |
3021 (serve, |
2938 [('A', 'accesslog', '', _('name of access log file to write to')), |
3022 [('A', 'accesslog', '', _('name of access log file to write to')), |