vc-dwim and vc-chlog

vc-dwim is a version-control-agnostic ChangeLog diff and commit tool. vc-chlog is a helper tool for writing GNU-style ChangeLog entries.


vc-dwim requires a version control system to be usable, currently one or more of Bazaar, CVS, git, Mercurial, and Subversion. It should be easy to add support for more.

vc-chlog requires vc-dwim and a ctags implementation, preferably Exuberant Ctags.


git repository:
release tarballs:

Mailing Lists


The vc-dwim manual can be found in several formats at


What can vc-dwim do?

vc-dwim is useful if you like to maintain a ChangeLog file describing the changes you make to version-controlled files. It can save you from making some small mistakes when using version control programs from the command line.

For example, if you have unsaved changes in an editor buffer and use vc-dwim to print diffs or to commit changes involving that file, it will detect the problem, tell you about it, and fail. This works as long as you use Emacs or Vim.

Another common error you can avoid with this tool is the one where you create a new file, add its name to Makefiles, etc., mention the addition in a ChangeLog, but forget to e.g., git add (or hg add, etc.) the file to the version control system. vc-dwim detects this discrepancy and fails with a diagnostic explaining the probable situation. You might also have simply mistyped the file name in the ChangeLog.

Also, vc-dwim makes it a little easier/safer to commit a strict subset of the modified files in a working directory. But no one ever does *that*.

How can you use vc-dwim?

Print diffs of arbitrary files:

Use an alias like this to show all or specified diffs:

      cv='vc-dwim --diff'

Use that when you want to see diffs of a specified file, regardless of whether you have written new ChangeLog entries for it. It works the same for cvs, git, hg, svn repositories, as long as all you want are the difference between your local copy and the checked out version.

Print diffs of files with new ChangeLog entries:

Let's say you have made local changes to a file, and you've also added at least one corresponding entry in a ChangeLog file. Then, you can use vc-dwim ChangeLog to print the diffs for which there are ChangeLog entries, warning about the potential problems mentioned above (editor temporaries that can imply there are unsaved changes, and files listed in ChangeLog, but not cvs added). If your changes affect files covered by more than one ChangeLog, you might use vc-dwim ChangeLog lib/ChangeLog, or more concisely, vc-dwim {,lib/}ChangeLog.

Commit changes to files with new ChangeLog entries:

Use vc-dwim --commit ChangeLog or vc-dwim --commit ChangeLog lib/ChangeLog src/ChangeLog to commit the changes you would see without the --commit option.

Assuming you have completed a change and have documented everything in one or more ChangeLog file, run vc-dwim --commit ChangeLog to commit that ChangeLog file and the files "implied" by the new ChangeLog lines. The commit log message is derived from the added ChangeLog lines. With a single ChangeLog file, the log message is nearly identical to the list of added lines. One leading TAB is removed and any date user-name <email> lines are elided. When there are two or more ChangeLog files, the log message includes a line for each indicating the affected directory. For example:

      * some-file-in-top-level-dir: ...
      * lib.c: ...
      * foo.m4: ...


What can vc-chlog do?

vc-chlog is about writing GNU Coding Standards-compliant ChangeLog entries easily.

Say you have made some changes to your code, ready to be committed. The only remaining part is to write one or more ChangeLog entries: for each ChangeLog governing a part of the package, collect the list of changed files, in each file list the changed functions, and mention all of those, in order to afterwards describe the changes:

      * file1.c (foo, bar, ...): ...
      * file2.c (baz): ...

vc-chlog attempts to help with this step. It scans the diff (obtained by vc-dwim --diff or passed on standard input with --stdin) for the files that were touched and the set of lines that have been changed. It then uses the ctags program to try to find out in which functions those changes have occurred, and formats the file and functions names in a prototype ChangeLog entry form on standard output.

There is a crucial assumption behind this idea to work well in practice: ctags should be able to generate tags for the identifiers that changed. For example, it should list functions in C source files (but not function- local or other nested entities); it should list macros in M4 files (e.g., those that serve as input to Autoconf), or it should list "@node"s in Texinfo files. The output of vc-chlog improves with that of ctags.

Exuberant Ctags is a powerful and extensible implementation of this command, and therefore preferred. For example, with the .ctags file in this package:
it detects the shell script as such. With a ~/.ctags containing
    --regex-texinfo=/^@node[	 ]+([^,]+)/\1/d,definition/
it detects Texinfo node names (vc-chlog uses some heuristic to deal with spaces in the identifier names when Exuberant Ctags is used).

Autoconf macros may be tagged by options such as


vc-chlog tries to find out about added as well as removed identifiers by examining both the new and the old version of a file. Here, it works hard not to change any file in your working directory, by using ctags -x and keeping all intermediate files in a temporary directory.

For some languages, vc-chlog attempts to guess where functions end, and thus not attribute changes past that end to the previous identifier.

Typically, vc-chlog is exact in the list of files that changed, false negatives in the list of identifiers stem from a ctags that failed to enumerate all identifiers properly, or changes before a function, false positives typically stem from constructs like nested functions.

Use vc-chlog with multiple ChangeLog files in a project

If a project uses multiple ChangeLog files, vc-chlog assumes that changes are to be recorded in the log file that is nearest up the directory tree. One possibility is to invoke vc-chlog always from the project root and put the output of

      find . -name ChangeLog | sed 's,^\./,--changelog ,'

into the .vc-chlogrc file at the root.