Ehsan Akhgari <mailto:ehsan.akhg...@gmail.com>
2017 September 18 at 12:59
I think there is a way to have our cake and eat it too, which is enabling git-cinnabar to understand a custom mapping of SHA1 so that we can rewrite the history and have cinnabar be able to deal with that when it maps hg/git revisions to each other.
We might be able to use Git's replace command [1], which enables you to "graft" one history onto another without rewriting revision IDs, such that Git commands like log, bisect, and blame traverse the two histories as one.

To test this out, I created a new repository mykmelez/gecko-test [2]; imported CVS history into a branch called "cvs"; imported the "central" branch from mozilla/gecko [3] (which is synced with cinnabar); and replaced e18f9a37a98d, which is the initial (earliest) commit on the central branch, with 3ec464b55782, which is the tip (latest) commit on the cvs branch.

The resulting log, starting from a9d623d0878b (the third-earliest commit on central), still shows e18f9a37a98d but decorates it with the "(replaced)" label and displays its replacement's commit message, after which the next two commits (55d824018c96 and 62453dda752a) are from CVS history:

 git log --oneline --decorate a9d623d0878b
a9d623d0878b Bug 374866. Reftests for text-transform. r=dbaron
028d2077b626 Free the (distributed) Lizard! Automatic merge from CVS: Module mozilla: tag HG_REPO_INITIAL_IMPORT at 22 Mar 2007 10:30 PDT, e18f9a37a98d (replaced) - update headers - remove pango workarounds - update wget files paths
55d824018c96 - updating headers
62453dda752a split out breakpad symbol build and upload into two config options, r=preed

Neither history is altered, as the replacement is stored as a ref (in refs/replace/), which most Git commands respect ("except those doing reachability traversal (prune, pack transfer and fsck)"). So the store still contains the original initial mozilla-central commit:

 git --no-replace-objects log --oneline --decorate e18f9a37a98d
e18f9a37a98d Set up .hgignore to ignore CVS files.

And removing the replacement ref reverts the "graft," returning the two histories to their original, disconnected state.

A downside of this approach is that the replacement ref isn't fetched by default. You need to fetch it manually after cloning the repo:

git fetch origin 'refs/replace/*:refs/replace/*'

But you only need to do that once. And if you don't do it, you still get a working clone with a central branch that is the equivalent of mozilla-central cloned with cinnabar, along with a branch containing the CVS history. You just don't get combined history.

The CVS history doesn't take much space either. A fresh clone of mozilla/gecko takes 4.9GB on my system, while a fresh clone of mykmelez/gecko-test takes 5.2GB (about the same as gecko-dev, which is 5.3GB).

So this seems like a promising option for having our cake and eating it too. Although further investigation is warranted to ensure that it works well with the Git commands (and editor integrations) that developers use when traversing history.

-myk

[1] https://git-scm.com/book/en/v2/Git-Tools-Replace
[2] https://github.com/mykmelez/gecko-test
[3] https://github.com/mozilla/gecko

_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to