As of 1.2, renames copy a full file revision in the history. For large binary files, this is expensive. It would be desirable to store a pointer plus a delta. This is [http://www.selenic.com/mercurial/bts/issue883 issue883].

This creates several issues:

So a fix requires:

Currently, revlogs are (by design) insulated from other revlogs. Knowledge of how and where other revlogs are stored is only available at a higher level (filelog). A revlog is a black box which higher level code hands a revision number and receives a complete revision in return, with its hash checked.

To remain backwards-compatible with clients over the wire, we must violate this abstraction. Here's a proposed approach:

returned by revlog is not a full revision as promised but a revision of file x@rev + the body here treated as a delta."

delta

work. Otherwise, we'll need to hack revlog.revision to call itself (and thereby filelog.revision) to grab the base revision.

So now we've got a scheme that mostly does away with the layering violations as revlog doesn't have to have any special knowledge about other revlogs (it's all in the filelog class, which already knows how to find and open revlog from a pathname). It even gets the case where c@z is a copy of b@y which is a copy of a@x right automatically.

But we've also got a huge compatibility problem. An old client can't just pull this data and expect it to work. Instead, we've got to add a new version of the wire protocol that allows us to send these sorts of deltas to new clients, but sends full revisions to old clients using the old wire protocol. And a new client would like to take old client data and deltify the copies, which may not be possible at pull time (for instance, if the destination revlog is sent before the source revlog).