Re: cvs2git conversion produces "spurious" commits in the history.
Etan Reisner <[email protected]> Sun, 7 Oct 2012 18:01:34 -0400
| Newsgroups | gmane.comp.version-control.subversion.cvs2svn.devel |
|---|---|
| Message-ID | <CAM=quGUxCsRmEQ3Q9fV=w1CN6Bm-MbzfnX2JZRFmUUeZHAf3GQ@mail.gmail.com> |
On Sat, Oct 6, 2012 at 2:08 AM, Michael Haggerty <[email protected]> wrote: <snip> > 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 As far as I'm aware (and as some quick testing seems to indicate) this will not generate the same RCS file as in my sample repo (or real repo). CVS will not generate an empty commit like that for a file that it knows has not been changed (that is that cvs ci will be a no-op). So while I see why those would look the same from the 'file c added to branch' perspective they aren't from a 'history of file c' one (or even just a 'contents of RCS file c,v' one). > 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. I completely agree with cvs2git not throwing away the real commit. Having done that would have been much worse than the current situation. > 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). Merging the commits in that direction would generate the wrong history though and CVS knows the timestamp of the correct history (as oppposed to your suggested history above which doesn't contain that additional timestamp information). As far as the actual CVS history is involved in this case the generated commit here seems to be entirely spurious and erroneous. > 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 I haven't had time to ensure that I understand the full details of these other versions though I certainly see the general similarities (though not completely the added complexity yet). > 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. I haven't investigated what would need to be done to use git-filter-branch to sort out these sorts of problems though that's certainly an avenue I should look into. That being said though, and as I indicated in my original email, I believe that given the duplicated content of these commits and the fact that the real commits are left intact (and that the git-dump.dat file contains the correct blob references for them) it should be possible for me to simply delete the generated commits from the dump file before import to get a correct history (and we started working on gathering the information necessary to run a verify across those timestamps to be sure we got things right). I won't have time until at least Tuesday night to look into this more but I'm planning to work up examples of the alternate histories on the version of cvs used to generate my problematic history to ensure that they don't cause the same problem/have the same issues as my original report. I also intend to run my initial testcase with a current version of CVS to see what cvs2git does with the new version of the generated history (though I imagine it will do a better job). Thanks for the answer and all the information. -Etan P.S. Where in cvs2svn is this sort of determination made? What logic is involved exactly? I've been having a difficult time sorting out where all the moving parts in this process are and how they interact. ------------------------------------------------------ http://cvs2svn.tigris.org/ds/viewMessage.do?dsForumId=1667&dsMessageId=3017849 To unsubscribe from this discussion, e-mail: [[email protected]].