Detecting Renames Automatically

posted by Steve Losh on September 30, 2009

The hg addremove command comes in handy when you manually move around a bunch of files. You can use any interface you like (Finder, Windows Explorer, a shell, etc) to change the structure and then run hg addremove to tell Mercurial to figure out what you changed.

A little-known feature of hg addremove is the ability to detect when you’ve moved or renamed a file and record that action as a rename instead of a separate add and remove. Recording the action as a rename lets Mercurial merge changes more intelligently.

To tell Mercurial to detect renames, you can use the --similarity option with hg addremove:

$ hg addremove --similarity 100

The number is a percentage. In this example, Mercurial will count an add/remove pair as a rename action only if the added file is identical (100% similar) to the removed file.

Using a lower number will catch renames that also include other changes to the file, but increases the risk of false positives. A good habit is to do all your file and directory structure changes as one commit, and keep changes to the contents of those files for a separate commit.

If you find yourself using this frequently you can make --similarity 100 a default by editing your ~/.hgrc file to contain:

[defaults]
addremove = --similarity 100

Be careful, using [defaults] will affect every run of the command, including when it is run from a script!

Mercurial can figure out which adds/removes are actually renames, if you ask nicely.