Shallow Clone Plan
This is the new plan for adding shallow clones (clones containing only newer history) to Mercurial. It is based on the older plan in ShallowClone, and discussions at the Paris sprint in early 2010.
Implement punching first (see TrimmingHistory). This is useful for both shallow clones and for deleting information from a repo - copyrighted material, for example.
- Implement single-rooted shallow clones only (for example, everything from 1.0 forward).
- Always keep the entire changelog around.
- In manifest and filelogs, simply punch all revs which are ancestors of the shallow root.
Later add truncation of manifest and filelogs. A change to the ShallowClone plan is that we don't rewrite unwanted parentrevs to nullrev directly on needed nodes. Instead, we use punched nodes for the unwanted parents, which have their parentrevs nulled. This way, we can still store the id of unwanted parents in the index.
- Implement deepening of history by internally cloning a deeper repo from the newly desired root to the current root, then pulling from the current shallow clone onto this new, deeper clone, then switching over to the new version and discarding the old one.
One goal of supporting only single-rooted shallow clones is to ensure that merges in shallow clones cannot silently yield different results than in full clones. Since we keep the entire changelog, and common ancestor resolution is now based on the changelog only, there is only one problematic area: copy (and thus rename) tracking.
A copy is used by merge if it is an ancestor in the file graph of exactly one of the merged file revs (see copies.py). [@mpm, is this correct?] So we should prove that in a single-rooted shallow clone with filelog truncation as shown above, we cannot have a situation where a merge in a shallow clone would differ in its treatment of copies from a full clone.