48 except IOError, inst: |
48 except IOError, inst: |
49 raise util.Abort(_("can't read commit message '%s': %s") % |
49 raise util.Abort(_("can't read commit message '%s': %s") % |
50 (logfile, inst.strerror)) |
50 (logfile, inst.strerror)) |
51 return message |
51 return message |
52 |
52 |
53 def matchpats(repo, pats=[], opts={}, head=''): |
|
54 cwd = repo.getcwd() |
|
55 if not pats and cwd: |
|
56 opts['include'] = [os.path.join(cwd, i) for i in opts['include']] |
|
57 opts['exclude'] = [os.path.join(cwd, x) for x in opts['exclude']] |
|
58 cwd = '' |
|
59 return util.cmdmatcher(repo.root, cwd, pats or ['.'], opts.get('include'), |
|
60 opts.get('exclude'), head) |
|
61 |
|
62 def makewalk(repo, pats, opts, node=None, head='', badmatch=None): |
|
63 files, matchfn, anypats = matchpats(repo, pats, opts, head) |
|
64 exact = dict(zip(files, files)) |
|
65 def walk(): |
|
66 for src, fn in repo.walk(node=node, files=files, match=matchfn, |
|
67 badmatch=badmatch): |
|
68 yield src, fn, util.pathto(repo.getcwd(), fn), fn in exact |
|
69 return files, matchfn, walk() |
|
70 |
|
71 def walk(repo, pats, opts, node=None, head='', badmatch=None): |
|
72 files, matchfn, results = makewalk(repo, pats, opts, node, head, badmatch) |
|
73 for r in results: |
|
74 yield r |
|
75 |
|
76 def walkchangerevs(ui, repo, pats, opts): |
53 def walkchangerevs(ui, repo, pats, opts): |
77 '''Iterate over files and the revs they changed in. |
54 '''Iterate over files and the revs they changed in. |
78 |
55 |
79 Callers most commonly need to iterate backwards over the history |
56 Callers most commonly need to iterate backwards over the history |
80 it is interested in. Doing so has awful (quadratic-looking) |
57 it is interested in. Doing so has awful (quadratic-looking) |
113 start -= windowsize |
90 start -= windowsize |
114 if windowsize < sizelimit: |
91 if windowsize < sizelimit: |
115 windowsize *= 2 |
92 windowsize *= 2 |
116 |
93 |
117 |
94 |
118 files, matchfn, anypats = matchpats(repo, pats, opts) |
95 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) |
119 follow = opts.get('follow') or opts.get('follow_first') |
96 follow = opts.get('follow') or opts.get('follow_first') |
120 |
97 |
121 if repo.changelog.count() == 0: |
98 if repo.changelog.count() == 0: |
122 return [], False, matchfn |
99 return [], False, matchfn |
123 |
100 |
651 |
628 |
652 If no names are given, add all files in the repository. |
629 If no names are given, add all files in the repository. |
653 """ |
630 """ |
654 |
631 |
655 names = [] |
632 names = [] |
656 for src, abs, rel, exact in walk(repo, pats, opts): |
633 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts): |
657 if exact: |
634 if exact: |
658 if ui.verbose: |
635 if ui.verbose: |
659 ui.status(_('adding %s\n') % rel) |
636 ui.status(_('adding %s\n') % rel) |
660 names.append(abs) |
637 names.append(abs) |
661 elif repo.dirstate.state(abs) == '?': |
638 elif repo.dirstate.state(abs) == '?': |
680 '--after instead)\n')) |
657 '--after instead)\n')) |
681 return addremove_lock(ui, repo, pats, opts) |
658 return addremove_lock(ui, repo, pats, opts) |
682 |
659 |
683 def addremove_lock(ui, repo, pats, opts, wlock=None): |
660 def addremove_lock(ui, repo, pats, opts, wlock=None): |
684 add, remove = [], [] |
661 add, remove = [], [] |
685 for src, abs, rel, exact in walk(repo, pats, opts): |
662 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts): |
686 if src == 'f' and repo.dirstate.state(abs) == '?': |
663 if src == 'f' and repo.dirstate.state(abs) == '?': |
687 add.append(abs) |
664 add.append(abs) |
688 if ui.verbose or not exact: |
665 if ui.verbose or not exact: |
689 ui.status(_('adding %s\n') % ((pats and rel) or abs)) |
666 ui.status(_('adding %s\n') % ((pats and rel) or abs)) |
690 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel): |
667 if repo.dirstate.state(abs) != 'r' and not os.path.exists(rel): |
734 if not opts['user'] and not opts['changeset'] and not opts['date']: |
711 if not opts['user'] and not opts['changeset'] and not opts['date']: |
735 opts['number'] = 1 |
712 opts['number'] = 1 |
736 |
713 |
737 ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0]) |
714 ctx = repo.changectx(opts['rev'] or repo.dirstate.parents()[0]) |
738 |
715 |
739 for src, abs, rel, exact in walk(repo, pats, opts, node=ctx.node()): |
716 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, |
|
717 node=ctx.node()): |
740 fctx = ctx.filectx(abs) |
718 fctx = ctx.filectx(abs) |
741 if not opts['text'] and util.binary(fctx.data()): |
719 if not opts['text'] and util.binary(fctx.data()): |
742 ui.write(_("%s: binary file\n") % ((pats and rel) or abs)) |
720 ui.write(_("%s: binary file\n") % ((pats and rel) or abs)) |
743 continue |
721 continue |
744 |
722 |
789 'specific revision')) |
767 'specific revision')) |
790 |
768 |
791 dest = cmdutil.make_filename(repo, dest, node) |
769 dest = cmdutil.make_filename(repo, dest, node) |
792 if os.path.realpath(dest) == repo.root: |
770 if os.path.realpath(dest) == repo.root: |
793 raise util.Abort(_('repository root cannot be destination')) |
771 raise util.Abort(_('repository root cannot be destination')) |
794 dummy, matchfn, dummy = matchpats(repo, [], opts) |
772 dummy, matchfn, dummy = cmdutil.matchpats(repo, [], opts) |
795 kind = opts.get('type') or 'files' |
773 kind = opts.get('type') or 'files' |
796 prefix = opts['prefix'] |
774 prefix = opts['prefix'] |
797 if dest == '-': |
775 if dest == '-': |
798 if kind == 'files': |
776 if kind == 'files': |
799 raise util.Abort(_('cannot archive plain files to stdout')) |
777 raise util.Abort(_('cannot archive plain files to stdout')) |
901 %s basename of file being printed |
879 %s basename of file being printed |
902 %d dirname of file being printed, or '.' if in repo root |
880 %d dirname of file being printed, or '.' if in repo root |
903 %p root-relative path name of file being printed |
881 %p root-relative path name of file being printed |
904 """ |
882 """ |
905 ctx = repo.changectx(opts['rev'] or "-1") |
883 ctx = repo.changectx(opts['rev'] or "-1") |
906 for src, abs, rel, exact in walk(repo, (file1,) + pats, opts, ctx.node()): |
884 for src, abs, rel, exact in cmdutil.walk(repo, (file1,) + pats, opts, |
|
885 ctx.node()): |
907 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs) |
886 fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs) |
908 fp.write(ctx.filectx(abs).data()) |
887 fp.write(ctx.filectx(abs).data()) |
909 |
888 |
910 def clone(ui, source, dest=None, **opts): |
889 def clone(ui, source, dest=None, **opts): |
911 """make a copy of an existing repository |
890 """make a copy of an existing repository |
965 """ |
944 """ |
966 message = logmessage(opts) |
945 message = logmessage(opts) |
967 |
946 |
968 if opts['addremove']: |
947 if opts['addremove']: |
969 addremove_lock(ui, repo, pats, opts) |
948 addremove_lock(ui, repo, pats, opts) |
970 fns, match, anypats = matchpats(repo, pats, opts) |
949 fns, match, anypats = cmdutil.matchpats(repo, pats, opts) |
971 if pats: |
950 if pats: |
972 modified, added, removed = repo.status(files=fns, match=match)[:3] |
951 modified, added, removed = repo.status(files=fns, match=match)[:3] |
973 files = modified + added + removed |
952 files = modified + added + removed |
974 else: |
953 else: |
975 files = [] |
954 files = [] |
1122 else: |
1101 else: |
1123 tfn = targetpathfn |
1102 tfn = targetpathfn |
1124 copylist = [] |
1103 copylist = [] |
1125 for pat in pats: |
1104 for pat in pats: |
1126 srcs = [] |
1105 srcs = [] |
1127 for tag, abssrc, relsrc, exact in walk(repo, [pat], opts): |
1106 for tag, abssrc, relsrc, exact in cmdutil.walk(repo, [pat], opts): |
1128 origsrc = okaytocopy(abssrc, relsrc, exact) |
1107 origsrc = okaytocopy(abssrc, relsrc, exact) |
1129 if origsrc: |
1108 if origsrc: |
1130 srcs.append((origsrc, abssrc, relsrc, exact)) |
1109 srcs.append((origsrc, abssrc, relsrc, exact)) |
1131 if not srcs: |
1110 if not srcs: |
1132 continue |
1111 continue |
1339 else: |
1318 else: |
1340 ui.write(_("not renamed\n")) |
1319 ui.write(_("not renamed\n")) |
1341 |
1320 |
1342 def debugwalk(ui, repo, *pats, **opts): |
1321 def debugwalk(ui, repo, *pats, **opts): |
1343 """show how files match on given patterns""" |
1322 """show how files match on given patterns""" |
1344 items = list(walk(repo, pats, opts)) |
1323 items = list(cmdutil.walk(repo, pats, opts)) |
1345 if not items: |
1324 if not items: |
1346 return |
1325 return |
1347 fmt = '%%s %%-%ds %%-%ds %%s' % ( |
1326 fmt = '%%s %%-%ds %%-%ds %%s' % ( |
1348 max([len(abs) for (src, abs, rel, exact) in items]), |
1327 max([len(abs) for (src, abs, rel, exact) in items]), |
1349 max([len(rel) for (src, abs, rel, exact) in items])) |
1328 max([len(rel) for (src, abs, rel, exact) in items])) |
1368 it detects as binary. With -a, diff will generate a diff anyway, |
1347 it detects as binary. With -a, diff will generate a diff anyway, |
1369 probably with undesirable results. |
1348 probably with undesirable results. |
1370 """ |
1349 """ |
1371 node1, node2 = revpair(ui, repo, opts['rev']) |
1350 node1, node2 = revpair(ui, repo, opts['rev']) |
1372 |
1351 |
1373 fns, matchfn, anypats = matchpats(repo, pats, opts) |
1352 fns, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) |
1374 |
1353 |
1375 patch.diff(repo, node1, node2, fns, match=matchfn, |
1354 patch.diff(repo, node1, node2, fns, match=matchfn, |
1376 opts=ui.diffopts(opts)) |
1355 opts=ui.diffopts(opts)) |
1377 |
1356 |
1378 def export(ui, repo, *changesets, **opts): |
1357 def export(ui, repo, *changesets, **opts): |
1421 This command is now deprecated and will be removed in a future |
1400 This command is now deprecated and will be removed in a future |
1422 release. Please use revert instead. |
1401 release. Please use revert instead. |
1423 """ |
1402 """ |
1424 ui.warn(_("(the forget command is deprecated; use revert instead)\n")) |
1403 ui.warn(_("(the forget command is deprecated; use revert instead)\n")) |
1425 forget = [] |
1404 forget = [] |
1426 for src, abs, rel, exact in walk(repo, pats, opts): |
1405 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts): |
1427 if repo.dirstate.state(abs) == 'a': |
1406 if repo.dirstate.state(abs) == 'a': |
1428 forget.append(abs) |
1407 forget.append(abs) |
1429 if ui.verbose or not exact: |
1408 if ui.verbose or not exact: |
1430 ui.status(_('forgetting %s\n') % ((pats and rel) or abs)) |
1409 ui.status(_('forgetting %s\n') % ((pats and rel) or abs)) |
1431 repo.forget(forget) |
1410 repo.forget(forget) |
1845 if rev: |
1824 if rev: |
1846 node = repo.lookup(rev) |
1825 node = repo.lookup(rev) |
1847 else: |
1826 else: |
1848 node = None |
1827 node = None |
1849 |
1828 |
1850 for src, abs, rel, exact in walk(repo, pats, opts, node=node, |
1829 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node, |
1851 head='(?:.*/|)'): |
1830 head='(?:.*/|)'): |
1852 if not node and repo.dirstate.state(abs) == '?': |
1831 if not node and repo.dirstate.state(abs) == '?': |
1853 continue |
1832 continue |
1854 if opts['fullpath']: |
1833 if opts['fullpath']: |
1855 ui.write(os.path.join(repo.root, abs), end) |
1834 ui.write(os.path.join(repo.root, abs), end) |
1856 else: |
1835 else: |
2242 remove them, use the -f/--force option. |
2221 remove them, use the -f/--force option. |
2243 """ |
2222 """ |
2244 names = [] |
2223 names = [] |
2245 if not opts['after'] and not pats: |
2224 if not opts['after'] and not pats: |
2246 raise util.Abort(_('no files specified')) |
2225 raise util.Abort(_('no files specified')) |
2247 files, matchfn, anypats = matchpats(repo, pats, opts) |
2226 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) |
2248 exact = dict.fromkeys(files) |
2227 exact = dict.fromkeys(files) |
2249 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5] |
2228 mardu = map(dict.fromkeys, repo.status(files=files, match=matchfn))[:5] |
2250 modified, added, removed, deleted, unknown = mardu |
2229 modified, added, removed, deleted, unknown = mardu |
2251 remove, forget = [], [] |
2230 remove, forget = [], [] |
2252 for src, abs, rel, exact in walk(repo, pats, opts): |
2231 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts): |
2253 reason = None |
2232 reason = None |
2254 if abs not in deleted and opts['after']: |
2233 if abs not in deleted and opts['after']: |
2255 reason = _('is still present') |
2234 reason = _('is still present') |
2256 elif abs in modified and not opts['force']: |
2235 elif abs in modified and not opts['force']: |
2257 reason = _('is modified (use -f to force removal)') |
2236 reason = _('is modified (use -f to force removal)') |
2354 names = {} |
2333 names = {} |
2355 target_only = {} |
2334 target_only = {} |
2356 |
2335 |
2357 # walk dirstate. |
2336 # walk dirstate. |
2358 |
2337 |
2359 for src, abs, rel, exact in walk(repo, pats, opts, badmatch=mf.has_key): |
2338 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, |
|
2339 badmatch=mf.has_key): |
2360 names[abs] = (rel, exact) |
2340 names[abs] = (rel, exact) |
2361 if src == 'b': |
2341 if src == 'b': |
2362 target_only[abs] = True |
2342 target_only[abs] = True |
2363 |
2343 |
2364 # walk target manifest. |
2344 # walk target manifest. |
2365 |
2345 |
2366 for src, abs, rel, exact in walk(repo, pats, opts, node=node, |
2346 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, node=node, |
2367 badmatch=names.has_key): |
2347 badmatch=names.has_key): |
2368 if abs in names: continue |
2348 if abs in names: continue |
2369 names[abs] = (rel, exact) |
2349 names[abs] = (rel, exact) |
2370 target_only[abs] = True |
2350 target_only[abs] = True |
2371 |
2351 |
2372 changes = repo.status(match=names.has_key, wlock=wlock)[:5] |
2352 changes = repo.status(match=names.has_key, wlock=wlock)[:5] |
2574 = the previous added file was copied from here |
2554 = the previous added file was copied from here |
2575 """ |
2555 """ |
2576 |
2556 |
2577 all = opts['all'] |
2557 all = opts['all'] |
2578 |
2558 |
2579 files, matchfn, anypats = matchpats(repo, pats, opts) |
2559 files, matchfn, anypats = cmdutil.matchpats(repo, pats, opts) |
2580 cwd = (pats and repo.getcwd()) or '' |
2560 cwd = (pats and repo.getcwd()) or '' |
2581 modified, added, removed, deleted, unknown, ignored, clean = [ |
2561 modified, added, removed, deleted, unknown, ignored, clean = [ |
2582 [util.pathto(cwd, x) for x in n] |
2562 [util.pathto(cwd, x) for x in n] |
2583 for n in repo.status(files=files, match=matchfn, |
2563 for n in repo.status(files=files, match=matchfn, |
2584 list_ignored=all or opts['ignored'], |
2564 list_ignored=all or opts['ignored'], |