Philip Guo (Phil Guo, Philip J. Guo, Philip Jia Guo, pgbovine)

CVS Lite: A Lightweight Alternative to CVS

UPDATE on 2007-07-25

I've found a better version control system that now makes CVS Lite irrelevant. Please look into using GIT for source control for your future projects.

GIT was originally written by Linus Torvalds and is currently used to maintain the Linux kernel. Besides being massively scalable for real-world applications, it is also RIDICULOUSLY EASY to set-up and use for a small one-person project. Read this tutorial to find out how you can start up a GIT repository in less than 5 minutes. It was so damn simple that the first time I tried it, I couldn't believe my eyes! GIT completely solves the problem that I was trying to solve with CVS Lite (namely, CVS being too big and klunky to use to maintain version histories for small sets of files). Amazing!

Introduction

CVS Lite is a lightweight version control system designed for simplicity and ease-of-use. I frequently use CVS on projects such as software and website development, but I find the overhead of setting up and maintaining a CVS repository too high for simply tracking versions of a single file edited by a single user (I can never quite remember the exact way to invoke cvs import).

Often times, I simply want to archive changes to a text file such as an essay or informal notes and may not want to bother setting up a CVS repository. CVS Lite excels at these small tasks. I have implemented the basic CVS commands that I find to be the most useful for a single-user system.

For instance, I can run cvslite.sh add on a file to create a repository in the same location as that file. I can then use commit to check-in new versions, diff to compare versions, up to retrieve old versions, and log to view my check-in comments. The lightweight representation of the repository (a tarball consisting of patches and text logs) enables me to easily move the file and repository around together or backup both using Unison or even the real CVS.

Quick Start Guide

Follow these steps to get started with CVS Lite:

  1. Download this BASH script, cvslite.sh, move it somewhere convenient (i.e., in your PATH), and chmod it to make it executable.
  2. Switch into some directory and create a text file named test.txt. Type some stuff in it and save it.
  3. Run cvslite.sh add test.txt to create a new repository for this file. You will now enter vi, where you can write a short log message describing this file. When you are done, CVS Lite should create a new sub-directory, CVSLite, and a new tar file in there, test.txt.cvslite.tar, which is the repository.
  4. Now modify test.txt by typing some more stuff and save it.
  5. Run cvslite.sh diff test.txt to view the differences between the current working version and the latest version in the repository, which is the version you just added.
  6. Run cvslite.sh commit test.txt to commit your changes and create a new version in the repository. Once again, you will be prompted to enter a log message in vi (which you can skip by exiting using :q!).
  7. Modify test.txt and run commit again. Now there should be 3 versions in the repository: Version 0 (the original), Version 1, and Version 2.
  8. Run cvslite.sh log test.txt to view the log entries for all 3 versions.
  9. Run cvslite.sh diff -r1 -r2 test.txt to compare Version 1 and Version 2.
  10. Run cvslite.sh up -r1 test.txt to save Version 1 of the file as test.txt.r1 (note that this is different behavior than regular CVS).

CVS Lite Commands

These are the only commands that I have implemented so far. Trying any other commands or fancy options will probably result in your shell blowing up. Enjoy :)

cvslite.sh <command> <optional arguments> <filename>

Each invocation of CVS Lite takes at least 2 parameters: a command name and a filename (it can only operate on one file per invocation). Commands might also take arguments, which should come before the filename. Here are all the commands:

  • add - Creates a repository for a file if one does not already exist. Does nothing if file is already in a repository. (e.g., cvslite.sh add test.txt).

  • commit - Commits the working version of the file (the one currently in the filesystem) to its repository by adding a new version. Prompts user to enter a log message (optional). Does nothing if the working version is identical to the latest version in the repository. (e.g., cvslite.sh commit test.txt)

  • log - Displays the log entries and modification times of all versions in the repository of a file. (e.g., cvslite.sh log test.txt)

  • up - Extracts a specified version of the file from the repository and saves it in a file named $FILENAME.r$VERSION_NUM, where $FILENAME is the filename and $VERSION_NUM is the version number (a non-negative integer). Does nothing if Version $VERSION_NUM does not exist for the file. Note: This is slightly different behavior than the CVS update command.

    • If invoked with one argument, in the form of -r$VERSION_NUM (e.g., -r0, -r4, -r42), extracts Version $VERSION_NUM of the file. (e.g., cvslite.sh up -r1 test.txt extracts Version 1 and saves it as test.txt.r1).
    • If invoked with no arguments (e.g., cvslite.sh up test.txt), extracts the latest version in the repository.

  • diff - Compares two versions of a file.

    • If invoked with two arguments, each in the form of -r$VERSION_NUM, compares the two specified versions. (e.g., cvslite.sh diff -r1 -r3 test.txt)

    • If invoked with one argument, compares the specified version to the working version (e.g., cvslite.sh diff -r1 test.txt)

    • If invoked with no arguments, compares the latest version in the repository to the working version (e.g., cvslite.sh diff test.txt)

    Does nothing if Version $VERSION_NUM does not exist for the file.

Implementation

CVS Lite is implemented as a BASH shell script that invokes diff to generate patches that represent differences between successive versions of a file, patch to apply those patches, and tar to store the patches together (along with the original version of the file and text logs) in a tarball that represents a CVS Lite repository. There is one repository per file. All repositories for files in a directory are located in a CVSLite sub-directory located in that directory.

Download

cvslite.sh - That's all, folks! Lightweight!

You will need a UNIX-like environment such as GNU/Linux, Mac OS X, *BSD, or Cygwin for Windows, the BASH shell, and standard UNIX tools that should come pre-installed on these systems. I have only tested on Ubuntu 5.10 so far, but it should be fairly portable. Please email me if there are compatibility issues (especially with non-GNU versions of tar, diff, patch, etc.)

cvslite.sh.cvslite.tar - If you are curious, save this repository file into a CVSLite/ sub-directory alongside cvslite.sh. You can then invoke CVS Lite on cvslite.sh (itself!) to view the version history of its own source code. Yup! Eating my own dogfood!

Future Work

(To be done whenever I feel like procrastinating)

  1. Add support for renaming files after they have been placed in a CVS Lite repository (could be useful because CVS is horrible at handling file renames)
  2. Add compression of repositories (e.g., gzip, bzip2); could save lots of space because patches and log files are plain text
  3. Add support for processing multiple files in one run of cvslite.sh
  4. Got suggestions? Email me: philip@pgbovine.net
Created: 2006-01-10
Last modified: 2007-07-25
Related pages tagged as software: