A script for converting CVS log messages to ChangeLog files.

The latest version is 2.73, released 17 May, 2008.

NOTICE (March 2021):

cvs2cl still works fine but it is no longer actively maintained. Martyn Pearce stepped down many years ago after a long and successful stint as cvs2cl's maintainer (thanks, Martyn!). The original author, Karl Fogel, continues to accept patches. The most recent patch (applied 2011-11-10) was from Yuri Lebedev and added the --xml-stylesheet option.


cvs2cl is Perl script that does what you think it does: it produces a GNU-style ChangeLog for CVS-controlled sources, by running "cvs log" and parsing the output. Duplicate log messages get unified in the Right Way. There is also XSLT available to convert the ChangeLog output to HTML.

You can download the latest version of the script directly, or clone the project from (Yes, cvs2cl is now hosted in Git, not in CVS.)

To report a bug, please use the issue tracker. In your report, include the exact command you ran, what you expected to happen, how what you got differed from what you expected, and whatever excerpt of 'cvs log' output is necessary to reproduce the problem. A patch to fix the bug is always welcome, of course. (Due to, ahem, historical reasons, cvs2cl's old bug tickets are kept in this file. We haven't bothered to port them over to the new issue tracker, but anyone is welcome to do so.)

You can view a Unix-style man page for cvs2cl by using perldoc:



cvs2cl is capable of producing XML output.

David Carlson (davidwcarlson at hotmail dot com) has come up with a draft dtd and schema for cvs2cl's XML output.

Here's an XSL stylesheet kindly donated by Daniel Ciaglia (daniel at ciaglia dot de), that's a variant on the html XSLT below, with the following amendments:

Example output from this stylesheet may be seen here Daniel also contributed a bash script to use with XSLT transformations.

Here's a development of Daniel's stylesheet kindly donated by Alexander Ruether that features:

Here's an XSL stylesheet kindly donated by Joseph Walton (joe at kafsemo dot org) that generates RSS output from changelogs in XML mode (requires 2.51 for the isoDate patch).

Here's an XSL stylesheet that kind donator Nicolas Karageuzian (nicolas at karageuzian dot com) describes as "quick and dirty", that generates rss and html using a table with colour changing for files

Here's a simple xslt (1.0) example for converting the XML output to XHTML. It really is a very simple example, for I am no expert: it's just a starting point. If anybody else has a nicer application to share, please send it to the bug address, and I'll post it here.

Here's an XSD, kindly donated by Yury Lebedev (yurylebedev at mail dot ru), that can translate's XML output into DataSet from MS dotNet Framework or can be used to validate/transform XML output data types in DOM document. Instead of XDR, this XSD can be used 'as is' without any modification of XML output - it's necessary only attach this XSD as separate 'schema' for '' namespace before loading such XML into a DOM document (depending on used XML parser implementation).

Release History:


Here is generating several flavors of its own ChangeLog.

Note that all of these invocations also used the "--fsf" option (omitted below for brevity), because a few log entries were written in FSF-style as an experiment.

2. --xml
3. --revisions
4. --tags
5. --branches
6. --tags --revisions
7. --branches --revisions
8. --tags --branches
9. --tags --branches --revisions
10. --tags --branches --revisions --usermap $CVSROOT/CVSROOT/users --day-of-week

Running --help will get you a thorough usage message, too.


Here are some links to related resources:

Summarized Change History

  • #50 Correct sense of --no-ancestors
  • #79 Fix non-working --prune
  • #80 Fix use of quotes in shell interpolation (that is, exec directly rather than using the shell).
  • #81 Fix implementation of --ignore to match documentation (i.e., use regexen).
  • #82 Fix implementation of branch recognition to handle branches with 10+ members.
  • #83 Add tag dates to XML output.
  • #75 Add patch to allow correct date format reading under cvs 1.12.9
  • #19 Fix regression of handling carriage returns with windows cvs log
  • #76 Fix missing use of File::Basename in ChangeLog::FileEntry
  • #77 Fix gecos handling to read getpwnam correctly
2.55 New features:
  • #73 Add --lines-modified option
  • #74 Add --follow-only option
2.53 Bug fixes:
  • #71 (provide non-zero exit code if cvs log fails)
  • #70 (eliminate unitialized value warnings with --follow)
  • #69 (fix --gecos to cope if author is missing, or if gecos field lacks commas)
  • #68 (fix -t -b to not die with a bad array dereference)
  • #65 (formatting fixes for pod)
2.52 New features:
  • Factor out a number of classes to ease maintenance and clarify data-flow
  • #65 (Reformat/Rewrite POD to form a valid manpage)
Bug fixes:
  • #66 (make --no-indent to not indent with --hide-filenames & --no-wrap)
2.51 New features:
  • #64 (Add --no-indent option)
  • #60 (Add ISO date to XML output)
Bug fixes:
  • #61 (Add examples of date use)
  • #63 (Partial implementation of group-within-date)
  • #56 (avoid uninitialized value warnings with --gecos)
  • Fix --FSF to not indent extra spaces
  • #57 (remove Attic/ path from --rcs output (to match non-rcs output))
  • #59 (handle files with a space in their name that were added on a branch)
2.50 New features:
  • Sort tags on output to ensure determinism to assist in tests (and other change-check mechanisms).
  • #52 (Add --noxmlns option)
  • #49 (Interpret "[user@]host:/file/whatever" in -U option)
Bug fixes:
  • Undocument --update since it doesn't actually do anything useful.
  • #51 (Remove additional newline from msg in XML mode)
  • #46 (Better wrapping of filenames with --no-wrap)
Implementation Changes:
  • Change 'wrap' to 'mywrap' because Text::Wrap in perl 5.005_03 exports wrap unconditionally and generates an override warning
2.49 New features:
  • #47 (Don't show log entries for branch-file addition)
  • #46 (Cosmetic Improvement to Indenting)
  • #45 (Fix awkward wrapping on two-space sentence gap)
  • #44 (Remove end-of-line whitespace being generated)
  • #43 (Conflate --mailname/--domain)
  • #42 (document --chrono flag)
  • #41 (Recognize RCS File on Windoze boxen)
  • #3 (Stop re-adding same logs with --accum --utc)
    New features:
  • #40 (Add --summary option to summarize groups in terms of added, deleted & changed files)
  • #39 (Add --update option to list only files that have changed since last run) #38
  • (Add --no-ancestors option to track only changes since a branch began)
  • #37 (Add --show-dead option to record dead files in output)
  • #36 (Add --rcs option to read raw rcs files)
  • #35 (Add --passwd option to read details from passwd file)
  • #35 (Add --mailname option to specify mail domain)
2.47 New features:
  • #33 (Document --delta flag)
  • #32 (Add --gecos, --domain options to include email & gecos informatin)
  • #29 (Add --FSF option to default output to FSF style)
  • #28 (Add --no-common-dir option to disable common-directory clustering in file output)
  • #26 (Add --show-tag option as opposite of --ignore-tag)
  • #25 (Add --chrono option to write output in chronological order)
2.46 New feature
  • #24 (Option to not print HH:MM on timestamps)
2.45 Fixes to bugs
  • #19 (carriage returns wreak havoc on windoze)
  • #22 (extra square brackets appeared on revision numbers)
  • #23 (perl version hardwired)
2.44 Fix to bug
  • #18 (spurious `malformed utf-8 character' warnings emitted)
2.43 Fixes to bugs
  • #14 (conflict with --accum and -D)
  • #11 (log tags with date the first tag occurred)
2.42 Fix to bug
  • #8 (delta option for trimming log between two tags)
2.41 Fix to bug
  • #5 (-W fails to handle argument '0')

Authors & Contributors



brought to you by red-bean