[PATCH 2 of 2] addremove: add --full option to force rematching of all removed files (status ! or R)
Peter Arrenbrecht
peter.arrenbrecht at gmail.com
Tue Apr 1 09:49:48 CDT 2008
# HG changeset patch
# User Peter Arrenbrecht <peter.arrenbrecht at gmail.com>
# Date 1207061261 -7200
# Node ID ea56bff9616527db57e26a9a0b8215c5f4556e35
# Parent 33a11aaa6dcf99969f932e7e6f9f88ec8c2ab810
addremove: add --full option to force rematching of all removed files (status ! or R)
With -s the addremove command only checks files with status ! (missing)
against files with status ? (new). Use the -f option with -s to force
(re)checking of all deleted files (status ! or R) against all new files
(status ? or A). This is especially helpful if you forgot -s or set
the similarity too high.
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -267,29 +267,40 @@
if bestname:
yield bestname, a, bestscore
-def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None):
+def addremove(repo, pats=[], opts={}, dry_run=None, similarity=None, full=None):
if dry_run is None:
dry_run = opts.get('dry_run')
if similarity is None:
similarity = float(opts.get('similarity') or 0)
+ if full is None:
+ full = opts.get('full')
+ unadded, unremoved = [], []
add, remove = [], []
mapping = {}
for src, abs, rel, exact in walk(repo, pats, opts):
target = repo.wjoin(abs)
- if src == 'f' and abs not in repo.dirstate:
- add.append(abs)
- mapping[abs] = rel, exact
- if repo.ui.verbose or not exact:
- repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
- if repo.dirstate[abs] != 'r' and (not util.lexists(target)
- or (os.path.isdir(target) and not os.path.islink(target))):
- remove.append(abs)
- mapping[abs] = rel, exact
- if repo.ui.verbose or not exact:
- repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
+ if src == 'f':
+ isrecorded = abs in repo.dirstate
+ if not isrecorded:
+ unadded.append(abs)
+ if repo.ui.verbose or not exact:
+ repo.ui.status(_('adding %s\n') % ((pats and rel) or abs))
+ if not isrecorded or full:
+ add.append(abs)
+ mapping[abs] = rel, exact
+ if (not util.lexists(target) or
+ (os.path.isdir(target) and not os.path.islink(target))):
+ isrecorded = repo.dirstate[abs] == 'r'
+ if not isrecorded:
+ unremoved.append(abs)
+ if repo.ui.verbose or not exact:
+ repo.ui.status(_('removing %s\n') % ((pats and rel) or abs))
+ if not isrecorded or full:
+ remove.append(abs)
+ mapping[abs] = rel, exact
if not dry_run:
- repo.remove(remove)
- repo.add(add)
+ repo.remove(unremoved)
+ repo.add(unadded)
if similarity > 0:
for old, new, score in findrenames(repo, add, remove, similarity):
oldrel, oldexact = mapping[old]
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -58,6 +58,12 @@
those similar enough as renames. This option takes a percentage
between 0 (disabled) and 100 (files must be identical) as its
parameter. Detecting renamed files this way can be expensive.
+
+ With -s this command normally only checks files with status ! (missing)
+ against files with status ? (new). Use the -f option with -s to force
+ (re)checking of all deleted files (status ! or R) against all new files
+ (status ? or A). This is especially helpful if you forgot -s or set
+ the similarity too high.
"""
try:
sim = float(opts.get('similarity') or 0)
@@ -2892,7 +2898,9 @@
"addremove":
(addremove,
[('s', 'similarity', '',
- _('guess renamed files by similarity (0<=s<=100)')),
+ _('guess renamed files (status !) by similarity (0<=s<=100)')),
+ ('f', 'full', None,
+ _('make -s check all removed files (status R or !)')),
] + walkopts + dryrunopts,
_('hg addremove [OPTION]... [FILE]...')),
"^annotate|blame":
diff --git a/tests/test-addremove-similar b/tests/test-addremove-similar
--- a/tests/test-addremove-similar
+++ b/tests/test-addremove-similar
@@ -50,4 +50,34 @@
hg addremove -s -1
hg addremove -s 1e6
+cd ..
+
+echo % --full option
+
+hg init rep3; cd rep3
+python -c 'for x in range(50): print x' > a
+hg add a; hg ci -m a
+mv a b
+echo "One more" >> b
+
+# so here we forget -s
+hg stat -C
+hg addrem
+hg stat -C
+
+# and try again with it, but it doesn't capture already recorded removals
+hg addrem -s 90
+hg stat -C
+
+# so we use the --full option
+hg addrem -fs 90
+hg stat -C
+
+# if we place another copy there, it gets recorded as a second target
+python -c 'for x in range(50): print x' > c
+hg addrem -s 90 --full
+hg stat -C
+
+cd ..
+
true
diff --git a/tests/test-addremove-similar.out b/tests/test-addremove-similar.out
--- a/tests/test-addremove-similar.out
+++ b/tests/test-addremove-similar.out
@@ -20,3 +20,24 @@
abort: similarity must be a number
abort: similarity must be between 0 and 100
abort: similarity must be between 0 and 100
+% --full option
+! a
+? b
+adding b
+removing a
+A b
+R a
+A b
+R a
+recording removal of a as rename to b (96% similar)
+A b
+ a
+R a
+adding c
+recording removal of a as rename to b (96% similar)
+recording removal of a as rename to c (100% similar)
+A b
+ a
+A c
+ a
+R a
More information about the Mercurial-devel
mailing list