Cvs2git does the best vendor branch handling seen so far, but it can make mistakes in some cases, especially when a vendor branch is present. Note my general pattern for running cvs2git: cvs2git --blobfile=$HOME/tmp/module.blob --dumpfile=$HOME/tmp/module.dump --username=cvs2git --keep-trivial-imports --keep-cvsignore --cvs-revnums --symbol-transform=_:. /cvs/misc/module mkdir g-module cd g-module git init cat $HOME/tmp/module.blob $HOME/tmp/module.dump | git fast-import --stats git checkout Smail is also a test case where all the options are set in a "cvs2git.options" file: /work/woods/m-smail/cvs2git.options Issues with vendor branches =========================== - the default merge-to-trunk-from-vendor-branch comments are atrociously misleading. They should be something simple such as: "Merge from the vendor branch." - The default branch may be set to the vendor branch, normally "1.1.1" while there are also changes on the trunk. To CVS this means that merging to the trunk (from the vendor branch) has been disabled (for the time being) for those files with a default branch matching the vendor branch; and thus the default checkout or update will be from the tip of the vendor branch. This is typically done with: "cvs admin -bVENDOR somefile" This is one of the ways the CVS manual (and various books) recommend to discard local changes and revert to using the vendor's version of a file (see "Reverting local changes" or "Reverting to the latest vendor release" in the CVS manual). Newer manuals do also say the "cvs admin -b" option "Breaks CVS.", though that's not really true, and the authors of such comments fail to define what "breaks" means to them. See the CVS FAQ for more discussion. So, this also means that any changes on the trunk (1.*) for such files are not current! In Git terms it's like discarding local changes to the file(s) before merging from the vendor branch. Unfortunately cvs2git simply fails completely when it encounters any files that have been reset to the vendor branch when they also have revisions on the trunk: ERROR: File '/cvs/misc/vrfy/main.c,v' has default branch=1.1.1 but also a revision 1.2 A possible fix for this, which retains the closest approximation to real history, is to record a "dead" revision on the trunk (here shown using plain RCS commands): co -l -r1 file.c,v ci -u1.3 -f -d'1990/01/12 04:00:00' -sdead -m'stop using local changes' file.c,v The date could/should be the date of, or just before, the next import on the vendor branch, if that can be determined; else the date of, or just after, the last revision on the "1" (trunk) branch. This "dead" revision will mean little to CVS (since it uses the default branch indicator instead), but it could then be used by cvs2git to create a commit reverting local changes before recording the merge from the vendor branch. The tricky part is that this switching between local revisions and the latest vendor import could happen more than once in the lifetime of a file, and since it's not possible in RCS/CVS itself to insert "dead" revisions without renumbering later revisions, and so fixing this up properly using the method I describe above would not be possible as-is and so would either require a new tool, or very careful manual editing of the RCS files. The simplest solution of course is to ignore this possibility and simply treat the "last"/latest import as the only one where the vendor revision has been merged to master. BTW, This issue with default branches is possibly related to the long-ago discussion ending with this message: http://cvs2svn.tigris.org/ds/viewMessage.do?dsForumId=1670&dsMessageId=898106 - Importing with "cvs import -d" ("Use the file's modification time as the time of import.") is/was a handy way to record a more accurate history of vendor artifacts. However if an import was done with "cvs import -d" then the Git record of the merge from vendor to master should only be done once (not once per file); but at what date? Ideally at the time of the import, but that's not recorded? Perhaps the date of the newest-at-the-time file? -- and if there was no "commitid" support at the time of the import, how to determine which? - Ideally a different user could/should be used for the vendor branch deltas and tags, e.g. to represent the original project author or a project maintainer address, etc. When doing imports I occasionally would do them as a generic "vendor" user to make the output of "cvs annotate" read better, but if that was not done in CVS it would still be good to be able to indicate it in the Git conversion. XXX XXX XXX Did I edit the /cvs/misc/vrfy/** RCS files to set e07 as the importer???? Also, it would be incredibly nice if cvs2git supported the "authormap" feature of other similar conversion tools. (XXX It sort of does -- see author_transforms in "cvs2git-example.options".)