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