[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Monotone-devel] Re: CVS -> SVN -> Git
From: |
Markus Schiltknecht |
Subject: |
[Monotone-devel] Re: CVS -> SVN -> Git |
Date: |
Sat, 21 Jul 2007 09:55:36 +0200 |
User-agent: |
Icedove 1.5.0.12 (X11/20070607) |
Hi,
(I'm cross posting to monotone-devel, as that might be of interest.)
This is an overview about how to represent tags or branches in
distributed VCSes. It focuses on 'broken' tags which span multiple
revisions, because they are imported from a legacy VCS (like CVS or
subversion) where such things were possible.
Karl Fogel wrote:
Right now, cvs2svn goes out of its way to try and do all that in *one*
commit. It's not immediately obvious to me which way is better...
For monotone, git and mercurial, you always have to add an artificial
revision. The question is, how to create those artificial revisions to
represent the original history the best. For example, let's have three
revisions, A, B, C, following each other:
A
|
B
|
C
Let's assume, that CVS (or svn) defines a tag which spans all three
revisions (i.e. files from A, B and C get tagged together), most of them
from B. There are basically two possibilities, on how you could
represent that in the mtn/git/hg world.
Variant 1. - artificial patches
A
|
B
| \
C X
Where X is the artificial revision which gets tagged. X needs to add all
the (reverting or forwarding) changes needed, to satisfy what the tag wants.
For a file tagged at A, the log would show something like:
X: an artificial revision for your tag (a merge)
(reverting 'some change to the file')
B: some change to the file
A: initial import
For a file tagged at C, the log would show:
X: an artificial revision for your tag (a merge)
(forward patch to 'some future change')
B: some change to the file
A: initial import
(Note that C doesn't even show up)
Variant 2. a) - multiple artificial merges
A
| \
B - Y - X
| /
C ----+
This involves two additional artificial revisions, which merge contents
together until we meet the requirements for our tag.
For a file tagged at A, the log would show:
X: an artificial revision for your tag (a merge)
Y: an artificial revision for your tag (a merge)
A: some change to your file
For a file tagged at C, the log would show:
X: an artificial revision for your tag (a merge)
C: some other change to another file
This variant does not need to add artificial changes (patches), but only
needs to add artificial merges. That's why I'm favoring this approach.
Variant 2. b) - a single artificial merge
I've just discovered, that git can handle revisions with multiple
parents... Monotone can't. That would allow, what others probably called
a "one commit" solution:
A
| \
B - X
| /
C
The logs would even be cleaner than in variant 2. a), as we have one
less artificial merge. Likewise, that would only add a merge, but no
artificial patches.
I'm clearly favoring variant 2. Wherever possible (git?), 2. b),
otherwise 2. a) (monotone, mercurial, codeville).
Please note again, that all the above does not only apply to tags, but
also to branchpoints, which makes the whole issue more important.
Also, you might have noted, that such an artificial revision creates a
new head in the main branch (trunk). This is disturbing and unwanted,
but can easily be circumvented by putting the artificial revisions into
a separate branch for the tag. For branchpoints that's not an issue, as
we already have a branch to put the artificial revisions in.
I hope to have brought some clarity into the discussion and provided
examples which can be discussed further.
Regards
Markus
- [Monotone-devel] Re: CVS -> SVN -> Git,
Markus Schiltknecht <=