Sometimes, you don’t remember to hg mv or hg rename. It slips your mind. And why should you? You’re saving the world … with code.
Sometimes, you can’t. A big strong IDE (Visual C#) takes over renames and moves because every file is referenced by an XML file, somewhere.
And, for those situations, you have hg addremove -s 82. Quoth the
docs,
Use the -s option to detect renamed files. With a parameter > 0, this compares every removed file with every added file and records 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.
…
-s --similarity guess renamed files by similarity (0<=s<=100)
You probably want to --dry-run this first: hg addremove -n -s 82.
How it works.
You thought I’d leave you hanging. No. I moderately like you too much to do that.
Mercurial commands like addremove are implemented in mercurial/commands.py. Those commands, usually, in turn call addremove in mercurial/cmdutil.py. Which then calls cmdutil.findrenames, and then the mathemagic happens.
For each tuple of (some added file, some removed file), findrenames checks the number of bytes in their matching lines. That gets stored in a variable called “equal.” If equal*2 divided by len(added file) + len(removed file) is greater than your similarity threshold (from 0 to 100) divided by 100, the removed file gets added to a list of possible candidates.
Let’s say you did this
mv hello-world.py hello-world.py rm very-old-hello-wrold.py rm unrelated-file.txt
So, in our example, there would be three tuples for hello-world.py: (hello-world.py, hello-wrold.py); (hello-world.py, very-old-hello-wrold.py); and (hello-world.py, unrelated-file.txt). The formula discards unrelated-file.txt. However, it might detect both hello-wrold.py and very-old-hello-wrold.py as within your threshold.
But then it’ll just choose the one with the highest score. And now Mercurial knows you moved hello-wrold.py to hello-world.py.
Hooray.