Maciek Sakrejda <msakrejda(at)truviso(dot)com> writes:
>> Many of the problems in the core conversion stemmed from the weird way
>> in which CVS deals with files that are added to branches later than they
>> are added to mainline.
> You mean something like branch REL_X_STABLE created, file A added to
> trunk, some more commits to trunk, then eventually the addition of A
> back-ported to REL_X_STABLE?
Yeah, except it's not the other activity on trunk that's interesting,
it's the other activity on the branch. To be concrete:
1. Branch REL_X_STABLE is forked off trunk.
2. Time passes, some commits occur in REL_X_STABLE.
3. File A gets added to trunk.
4. More time passes, more commits occur in REL_X_STABLE.
5. We make a release and apply a tag REL_X_Y in the branch.
(In CVS this means that every single RCS file that has
live content in the branch receives a tag marker. Since
file A is not in the branch, it gets no tag marker.)
6. File A gets added to branch REL_X_STABLE.
In the representation used by CVS, the commit 6 appears to be a direct
child of commit 3 (or maybe even commit 1, I forget); therefore it
appears that file A has existed on the branch since its inception.
But the lack of a REL_X_Y tag marker puts the lie to that appearance,
so cvs2git can tell the history is inconsistent. To fix it, we need to
insert a deletion event on the branch immediately after commit 3
(or was it commit 1? ... anyway look at the pgsql-hackers discussions
for details). Recent versions of CVS know to insert a special deletion
event when first adding a file to a branch, but older ones didn't.
One thing that took me awhile to figure out is that these magic deletion
events have to conform to exactly the format cvs2git expects, including
the wording of the manufactured commit message, else it fails to
understand what it's supposed to do with them.
regards, tom lane