Re: cvs2git conversion produces "spurious" commits in the history.

Michael Haggerty <[email protected]> Sat, 06 Oct 2012 08:08:56 +0200
Newsgroups gmane.comp.version-control.subversion.cvs2svn.devel
Message-ID <[email protected]>
On 10/05/2012 08:59 PM, Etan Reisner wrote:
> While attempting a cvs2git (cvs2svn r5401, python 2.6.6, CentOS 6.3)
> conversion I noticed that cvs2svn was creating some extra symbol_commit
> commits that seem to be unnecessary. The commits seem to be duplicates
> of one (or more) commits that appear later on the branch and simply
> pre-create (via cherry pick) the contents that the correct commits would
> add later.

Thanks for your detailed problem report.  I wish everybody would
document their problems so carefully!

The result of the conversion looks like this:

> $ git log --decorate --graph --all --oneline
> * 096ce16 (branch) Import from MAIN c
> * 082d2de This commit was manufactured by cvs2svn to create branch 'branch'.
> * deeed43 Update a
> | * fb9a0dc (HEAD, master) Add c
> |/  
> * c841f5d Add a

The effect that you are seeing is caused by a combination of CVS
recording too little information about the history and perhaps cvs2git
not being aggressive enough about throwing out redundant commits.

There are two ways that the history of file c that is present in your
repository could have been generated:

1. Merge from HEAD (what you did):

       cvs up -r branch
       cvs up -j 1.1 c
       cvs ci -m "Import from MAIN c"

2. Add branch tag explicitly, then "modify" c with no changes:

       cvs tag -b branch c
       cvs up -r branch
       cvs ci -f -m "Import from MAIN c" c

cvs2git is guessing that the second happened.  It doesn't throw away
082d2de because this commit adds file c to branch.  And it doesn't throw
away 096ce16 (even though it doesn't modify the tree) because throwing
away the commit would mean that its commit message would be lost forever.

In this particular case it would be reasonable to merge the two commits
into a single one, moving your "Import from MAIN c" commit message onto
the commit that adds c to b (i.e., sacrificing the autogenerated commit
message, which is anyway misleading).  But this is a rather special case
that is only obvious because only a single file is affected.  It is hard
to generalize to a more complicated version of history (2), which might
look like

       cvs tag -b branch c d e f
       cvs up -r branch
       $EDITOR d
       cvs ci -f -m "Touch c and d on branch" c d
       $EDITOR e
       cvs ci -m "Modify e" e

(Please note that the history of file c in this scenario would be
identical to your history of file c.)  In this case it would be
misleading to smash the "Touch c and d on branch" commit into the
branching commit, because that would make it look like the log message
also applied to files e and f.  Meanwhile, since CVS doesn't record the
timestamps of branching operations, the same CVS history could also be
generated by lots of other "true" histories, like

       cvs tag -b branch c d
       cvs up -r branch
       $EDITOR d
       cvs ci -f -m "Touch c and d on branch" c d
       cvs tag -b branch e
       $EDITOR e
       cvs ci -m "Modify e" e
       cvs tag -b branch f

The real *practical* problem is that picking more cleverly between these
various scenarios requires global information about the CVS history of
all files, and that is very expensive to compute during the conversion.
 On the other hand, git has excellent tools for examining and modifying
the history *after* the conversion (see git-filter-branch(1)).  For 2git
conversions, I think it would be much easier to write a tool that
examines the post-commit git history looking for these kinds of commit
constellations and fixes them up using git tools, then bake the result
in using "git filter-branch" *before* publishing the converted repository.

Hope that helps,
Michael

-- 
Michael Haggerty
[email protected]
http://softwareswirl.blogspot.com/

------------------------------------------------------
http://cvs2svn.tigris.org/ds/viewMessage.do?dsForumId=1667&dsMessageId=3015050

To unsubscribe from this discussion, e-mail: [[email protected]].