def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None): if dry_run is None: dry_run = opts.get('dry_run') if similarity is None: similarity = float(opts.get('similarity') or 0) # we'd use status here, except handling of symlinks and ignore is tricky added, unknown, deleted, removed = [], [], [], [] audit_path = pathauditor(repo.root) m = match(repo[None], pats, opts) rejected = [] m.bad = lambda x, y: rejected.append(x) for abs in repo.walk(m): target = repo.wjoin(abs) good = True try: audit_path(abs) except (OSError, util.Abort): good = False rel = m.rel(abs) exact = m.exact(abs) if good and abs not in repo.dirstate: unknown.append(abs) if repo.ui.verbose or not exact: repo.ui.status(_('adding %s\n') % ((pats and rel) or abs)) elif repo.dirstate[abs] != 'r' and (not good or not os.path.lexists(target) or (os.path.isdir(target) and not os.path.islink(target))): deleted.append(abs) if repo.ui.verbose or not exact: repo.ui.status(_('removing %s\n') % ((pats and rel) or abs)) # for finding renames elif repo.dirstate[abs] == 'r': removed.append(abs) elif repo.dirstate[abs] == 'a': added.append(abs) copies = {} if similarity > 0: for old, new, score in similar.findrenames(repo, added + unknown, removed + deleted, similarity): if repo.ui.verbose or not m.exact(old) or not m.exact(new): repo.ui.status(_('recording removal of %s as rename to %s ' '(%d%% similar)\n') % (m.rel(old), m.rel(new), score * 100)) copies[new] = old if not dry_run: wctx = repo[None] wlock = repo.wlock() try: wctx.forget(deleted) wctx.add(unknown) for new, old in copies.iteritems(): wctx.copy(old, new) finally: wlock.release() for f in rejected: if f in m.files(): return 1 return 0
def _findrenames(repo, matcher, added, removed, similarity): """Find renames from removed files to added ones.""" renames = {} if similarity > 0: for old, new, score in similar.findrenames(repo, added, removed, similarity): if repo.ui.verbose or not matcher.exact(old) or not matcher.exact(new): repo.ui.status( _("recording removal of %s as rename to %s " "(%d%% similar)\n") % (matcher.rel(old), matcher.rel(new), score * 100) ) renames[new] = old return renames
def _findrenames(repo, matcher, added, removed, similarity): '''Find renames from removed files to added ones.''' renames = {} if similarity > 0: for old, new, score in similar.findrenames(repo, added, removed, similarity): if (repo.ui.verbose or not matcher.exact(old) or not matcher.exact(new)): repo.ui.status( _('recording removal of %s as rename to %s ' '(%d%% similar)\n') % (matcher.rel(old), matcher.rel(new), score * 100)) renames[new] = old return renames
def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None): if dry_run is None: dry_run = opts.get('dry_run') if similarity is None: similarity = float(opts.get('similarity') or 0) # we'd use status here, except handling of symlinks and ignore is tricky added, unknown, deleted, removed = [], [], [], [] audit_path = pathauditor(repo.root) m = match(repo[None], pats, opts) rejected = [] m.bad = lambda x, y: rejected.append(x) ctx = repo[None] dirstate = repo.dirstate walkresults = dirstate.walk(m, sorted(ctx.substate), True, False) for abs, st in walkresults.iteritems(): dstate = dirstate[abs] if dstate == '?' and audit_path.check(abs): unknown.append(abs) elif dstate != 'r' and not st: deleted.append(abs) # for finding renames elif dstate == 'r': removed.append(abs) elif dstate == 'a': added.append(abs) unknownset = set(unknown) toprint = unknownset.copy() toprint.update(deleted) for abs in sorted(toprint): if repo.ui.verbose or not m.exact(abs): rel = m.rel(abs) if abs in unknownset: status = _('adding %s\n') % ((pats and rel) or abs) else: status = _('removing %s\n') % ((pats and rel) or abs) repo.ui.status(status) copies = {} if similarity > 0: for old, new, score in similar.findrenames(repo, added + unknown, removed + deleted, similarity): if repo.ui.verbose or not m.exact(old) or not m.exact(new): repo.ui.status(_('recording removal of %s as rename to %s ' '(%d%% similar)\n') % (m.rel(old), m.rel(new), score * 100)) copies[new] = old if not dry_run: wctx = repo[None] wlock = repo.wlock() try: wctx.forget(deleted) wctx.add(unknown) for new, old in copies.iteritems(): wctx.copy(old, new) finally: wlock.release() for f in rejected: if f in m.files(): return 1 return 0
def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None): if dry_run is None: dry_run = opts.get('dry_run') if similarity is None: similarity = float(opts.get('similarity') or 0) # we'd use status here, except handling of symlinks and ignore is tricky added, unknown, deleted, removed = [], [], [], [] audit_path = pathauditor(repo.root) m = match(repo[None], pats, opts) rejected = [] m.bad = lambda x, y: rejected.append(x) ctx = repo[None] dirstate = repo.dirstate walkresults = dirstate.walk(m, sorted(ctx.substate), True, False) for abs, st in walkresults.iteritems(): dstate = dirstate[abs] if dstate == '?' and audit_path.check(abs): unknown.append(abs) elif dstate != 'r' and not st: deleted.append(abs) # for finding renames elif dstate == 'r': removed.append(abs) elif dstate == 'a': added.append(abs) unknownset = set(unknown) toprint = unknownset.copy() toprint.update(deleted) for abs in sorted(toprint): if repo.ui.verbose or not m.exact(abs): rel = m.rel(abs) if abs in unknownset: status = _('adding %s\n') % ((pats and rel) or abs) else: status = _('removing %s\n') % ((pats and rel) or abs) repo.ui.status(status) copies = {} if similarity > 0: for old, new, score in similar.findrenames(repo, added + unknown, removed + deleted, similarity): if repo.ui.verbose or not m.exact(old) or not m.exact(new): repo.ui.status( _('recording removal of %s as rename to %s ' '(%d%% similar)\n') % (m.rel(old), m.rel(new), score * 100)) copies[new] = old if not dry_run: wctx = repo[None] wlock = repo.wlock() try: wctx.forget(deleted) wctx.add(unknown) for new, old in copies.iteritems(): wctx.copy(old, new) finally: wlock.release() for f in rejected: if f in m.files(): return 1 return 0