kareila: Taking refuge from falling debris under a computer desk. (computercrash)
kareila ([personal profile] kareila) wrote in [site community profile] dw_dev2010-07-09 10:48 pm

Mercurial: (lack of) use of "hg rename"

I've been reading the O'Reilly Mercurial guide, and one item I've run into is the 'hg rename' command for renaming files. We have NOT been using this. Instead, we've been removing the old file and adding the new file.

This is bad for a couple of reasons. One, recent changes to the old file can get dropped on the floor (this has happened at least once). Two, there's a discontinuity in the revision history. You can still access the revision history of the older file under the original file name, but it would be nicer for the entire revision history to remain easily accessible.

Looking Forward



There are a couple of options you can set up in your .hgrc to help with this:

[diff]
git = true


This will tell hg to use "git-style" diffs, which show that a file has been renamed, not add/removed. There are other differences, such as permission changes, that are ignored by the default diff as well.

[defaults]
addremove = --similarity 100


This tells the "hg addremove" command (which should be executed before every commit, probably - how often do committers forget to add new files to the repo?) to detect when the same file has been removed and readded under a different name, and treat it as a rename instead. Presumably values less than 100 allow fuzzier matching.

Looking Backward



I couldn't figure out a way to correct the revision history in our repository without some hideous branch merging scheme for each changeset containing a failed rename, so for now I'll just make a list of the files that should have been renamed and weren't.

27f1a0767ecd: htdocs/userinfo.bml -> htdocs/profile.bml
27f1a0767ecd: htdocs/userinfo.bml.text -> htdocs/profile.bml.text
8428f0b6ae2d: htdocs/translate/* -> htdocs/admin/translate/*
bbe8245e97be: htdocs/mobile/friends.bml -> htdocs/mobile/read.bml
0b30744ab665: htdocs/syn/* -> htdocs/feeds/*
4f61e7788b51: htdocs/editpics.bml -> htdocs/editicons.bml
4f61e7788b51: htdocs/editpics.bml.text -> htdocs/editicons.bml.text
4f61e7788b51: htdocs/stc/editpics.css -> htdocs/stc/editicons.css
4f61e7788b51: htdocs/js/editpics.js -> htdocs/js/editicons.js
8e48610e9122: cgi-bin/talklib.pl -> cgi-bin/LJ/Talk.pm
e932a96a1e51: cgi-bin/parsefeed.pl -> cgi-bin/LJ/ParseFeed.pm
246fde8dc6bf: cgi-bin/cleanhtml.pl -> cgi-bin/LJ/CleanHTML.pm
f8cfab97cc4b: cgi-bin/supportlib.pl -> cgi-bin/LJ/Support.pm
798902bff009: cgi-bin/taglib.pl -> cgi-bin/LJ/Tags.pm
28e0103cbb09: cgi-bin/synlib.pl -> cgi-bin/LJ/Syn.pm
1ad1d37c54ab: cgi-bin/LJ/Event/Befriended.pm -> cgi-bin/LJ/Event/AddedToCircle.pm
1ad1d37c54ab: cgi-bin/LJ/Event/Defriended.pm -> cgi-bin/LJ/Event/RemovedFromCircle.pm
2732c4614ced: cgi-bin/ljlinks.pl -> cgi-bin/LJ/Links.pm
780a3e3275f7: cgi-bin/ljhooks.pl -> cgi-bin/LJ/Hooks.pm
e8d5bfb23489: cgi-bin/ljlang.pl -> cgi-bin/LJ/Lang.pm
f8cfab97cc4b: cgi-bin/supportlib.pl -> cgi-bin/LJ/Support.pm
e808c7233f00: cgi-bin/schoollib.pl -> cgi-bin/LJ/Schools.pm (since deleted)
29f13c2dc059: cgi-bin/ljmood.pl -> cgi-bin/DW/Mood.pm


To be clear, I am not placing blame here, but I would like for us all, and most especially my fellow committers, to be aware of the issue and attempt to do the right thing in the future. :)
jld: (vessel)

[personal profile] jld 2010-07-11 08:44 am (UTC)(link)
Yeah, Hg's repository format (at least the last time I saw it) is actually a CVS-like individual-file thing, with the atomic commits and stuff layered on top of that. I think all hg rename does is leave a note on the new file that it was copied from the old deleted file. (But it's been a while since I actually cared, and it's late enough at night that I probably shouldn't be trusted with the Internet right now.)
ninetydegrees: Text: let's make better mistakes tomorrow. (mistakes)

[personal profile] ninetydegrees 2010-07-10 02:16 pm (UTC)(link)
I actually thought it was policy to delete/add instead of renaming. Thanks for telling me/us renaming is best.
pauamma: Cartooney crab wearing hot pink and acid green facemask holding drink with straw (Default)

[personal profile] pauamma 2010-07-10 02:58 pm (UTC)(link)
Another useful command is "hg copy". Typical use is when a file is split in 2, eg when TTizing a page.

hg copy htdocs/foo/bar.bml cgi-bin/DW/Controller/Foo/Bar.pm
hg mv htdocs/foo/bar.bml views/foo/bar.tt
hg mv htdocs/foo/bar.bml.text views/foo/bar.tt.text

(hg mv is an alias for hg rename)

ETA "hg help addremove" excerpt:

Use the -s/--similarity option to detect renamed files. With a parameter greater than 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.
Edited (ETA "hg help addremove" excerpt) 2010-07-10 15:55 (UTC)
afuna: Cat under a blanket. Text: "Cats are just little people with Fur and Fangs" (Default)

[personal profile] afuna 2010-07-10 04:28 pm (UTC)(link)
Hrrm. How do you apply patches assuming they have the correct metadata? hg import?

(And will this work with patches which have been generated by cvsreport.pl?)
Edited 2010-07-10 16:28 (UTC)
afuna: Cat under a blanket. Text: "Cats are just little people with Fur and Fangs" (Default)

[personal profile] afuna 2010-07-11 11:08 am (UTC)(link)
Hmm, there's the --after option:

-A --after record a rename that has already occurred



Which I think we can use to fix up the old files.