Re: cvs2git conversion produces "spurious" commits in the history.
Michael Haggerty <[email protected]> Mon, 08 Oct 2012 05:47:04 +0200
| Newsgroups | gmane.comp.version-control.subversion.cvs2svn.devel |
|---|---|
| Message-ID | <[email protected]> |
On 10/08/2012 12:01 AM, Etan Reisner wrote: > 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). If you use the "-f" option, as above, then cvs creates the commit anyway. >> 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. I don't understand your point. >> 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). While editing the git-dump.dat file is possible, it becomes cumbersome in real-world situations when the file can be many GiB in size and when manually finding the places that need "fixing up" becomes impractical. > 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. There is a lot of information in doc/design-notes.txt about the algorithms used. Most of the intelligence for simplifying single-file histories happens during FilterSymbolsPass in the class CVSFileItems. The work of deducing the project-wide commits from all of the single-file histories is done in the passes starting with InitializeChangesetsPass. Michael -- Michael Haggerty [email protected] http://softwareswirl.blogspot.com/ ------------------------------------------------------ http://cvs2svn.tigris.org/ds/viewMessage.do?dsForumId=1667&dsMessageId=3018242 To unsubscribe from this discussion, e-mail: [[email protected]].