6 # of the GNU General Public License, incorporated herein by reference. |
6 # of the GNU General Public License, incorporated herein by reference. |
7 |
7 |
8 from node import * |
8 from node import * |
9 from i18n import _ |
9 from i18n import _ |
10 import os, sys, atexit, signal, pdb, traceback, socket, errno, shlex |
10 import os, sys, atexit, signal, pdb, traceback, socket, errno, shlex |
|
11 import bisect, stat |
11 import mdiff, bdiff, util, templater, patch, commands, hg, lock, time |
12 import mdiff, bdiff, util, templater, patch, commands, hg, lock, time |
12 import fancyopts, revlog, version, extensions, hook |
13 import fancyopts, revlog, version, extensions, hook |
13 |
14 |
14 revrangesep = ':' |
15 revrangesep = ':' |
15 |
16 |
623 if myscore >= bestscore: |
624 if myscore >= bestscore: |
624 bestname, bestscore = r, myscore |
625 bestname, bestscore = r, myscore |
625 if bestname: |
626 if bestname: |
626 yield bestname, a, bestscore |
627 yield bestname, a, bestscore |
627 |
628 |
628 def addremove(repo, pats=[], opts={}, wlock=None, dry_run=None, |
629 def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None): |
629 similarity=None): |
|
630 if dry_run is None: |
630 if dry_run is None: |
631 dry_run = opts.get('dry_run') |
631 dry_run = opts.get('dry_run') |
632 if similarity is None: |
632 if similarity is None: |
633 similarity = float(opts.get('similarity') or 0) |
633 similarity = float(opts.get('similarity') or 0) |
634 add, remove = [], [] |
634 add, remove = [], [] |
635 mapping = {} |
635 mapping = {} |
636 for src, abs, rel, exact in walk(repo, pats, opts): |
636 for src, abs, rel, exact in walk(repo, pats, opts): |
637 target = repo.wjoin(abs) |
637 target = repo.wjoin(abs) |
638 if src == 'f' and repo.dirstate.state(abs) == '?': |
638 if src == 'f' and abs not in repo.dirstate: |
639 add.append(abs) |
639 add.append(abs) |
640 mapping[abs] = rel, exact |
640 mapping[abs] = rel, exact |
641 if repo.ui.verbose or not exact: |
641 if repo.ui.verbose or not exact: |
642 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs)) |
642 repo.ui.status(_('adding %s\n') % ((pats and rel) or abs)) |
643 if repo.dirstate.state(abs) != 'r' and not util.lexists(target): |
643 if repo.dirstate[abs] != 'r' and not util.lexists(target): |
644 remove.append(abs) |
644 remove.append(abs) |
645 mapping[abs] = rel, exact |
645 mapping[abs] = rel, exact |
646 if repo.ui.verbose or not exact: |
646 if repo.ui.verbose or not exact: |
647 repo.ui.status(_('removing %s\n') % ((pats and rel) or abs)) |
647 repo.ui.status(_('removing %s\n') % ((pats and rel) or abs)) |
648 if not dry_run: |
648 if not dry_run: |
649 repo.add(add, wlock=wlock) |
649 repo.add(add) |
650 repo.remove(remove, wlock=wlock) |
650 repo.remove(remove) |
651 if similarity > 0: |
651 if similarity > 0: |
652 for old, new, score in findrenames(repo, add, remove, similarity): |
652 for old, new, score in findrenames(repo, add, remove, similarity): |
653 oldrel, oldexact = mapping[old] |
653 oldrel, oldexact = mapping[old] |
654 newrel, newexact = mapping[new] |
654 newrel, newexact = mapping[new] |
655 if repo.ui.verbose or not oldexact or not newexact: |
655 if repo.ui.verbose or not oldexact or not newexact: |
656 repo.ui.status(_('recording removal of %s as rename to %s ' |
656 repo.ui.status(_('recording removal of %s as rename to %s ' |
657 '(%d%% similar)\n') % |
657 '(%d%% similar)\n') % |
658 (oldrel, newrel, score * 100)) |
658 (oldrel, newrel, score * 100)) |
659 if not dry_run: |
659 if not dry_run: |
660 repo.copy(old, new, wlock=wlock) |
660 repo.copy(old, new) |
661 |
661 |
662 def service(opts, parentfn=None, initfn=None, runfn=None): |
662 def service(opts, parentfn=None, initfn=None, runfn=None): |
663 '''Run a command as a service.''' |
663 '''Run a command as a service.''' |
664 |
664 |
665 if opts['daemon'] and not opts['daemon_pipefds']: |
665 if opts['daemon'] and not opts['daemon_pipefds']: |
1271 fns = fns_generator() |
1271 fns = fns_generator() |
1272 yield 'add', rev, fns |
1272 yield 'add', rev, fns |
1273 for rev in nrevs: |
1273 for rev in nrevs: |
1274 yield 'iter', rev, None |
1274 yield 'iter', rev, None |
1275 return iterate(), matchfn |
1275 return iterate(), matchfn |
|
1276 |
|
1277 def commit(ui, repo, commitfunc, pats, opts): |
|
1278 '''commit the specified files or all outstanding changes''' |
|
1279 message = logmessage(opts) |
|
1280 |
|
1281 if opts['addremove']: |
|
1282 addremove(repo, pats, opts) |
|
1283 fns, match, anypats = matchpats(repo, pats, opts) |
|
1284 if pats: |
|
1285 status = repo.status(files=fns, match=match) |
|
1286 modified, added, removed, deleted, unknown = status[:5] |
|
1287 files = modified + added + removed |
|
1288 slist = None |
|
1289 for f in fns: |
|
1290 if f == '.': |
|
1291 continue |
|
1292 if f not in files: |
|
1293 rf = repo.wjoin(f) |
|
1294 try: |
|
1295 mode = os.lstat(rf)[stat.ST_MODE] |
|
1296 except OSError: |
|
1297 raise util.Abort(_("file %s not found!") % rf) |
|
1298 if stat.S_ISDIR(mode): |
|
1299 name = f + '/' |
|
1300 if slist is None: |
|
1301 slist = list(files) |
|
1302 slist.sort() |
|
1303 i = bisect.bisect(slist, name) |
|
1304 if i >= len(slist) or not slist[i].startswith(name): |
|
1305 raise util.Abort(_("no match under directory %s!") |
|
1306 % rf) |
|
1307 elif not (stat.S_ISREG(mode) or stat.S_ISLNK(mode)): |
|
1308 raise util.Abort(_("can't commit %s: " |
|
1309 "unsupported file type!") % rf) |
|
1310 elif f not in repo.dirstate: |
|
1311 raise util.Abort(_("file %s not tracked!") % rf) |
|
1312 else: |
|
1313 files = [] |
|
1314 try: |
|
1315 return commitfunc(ui, repo, files, message, match, opts) |
|
1316 except ValueError, inst: |
|
1317 raise util.Abort(str(inst)) |