Bky - a minimalistic, distributed VCS / SCM
===========================================

 Angel Ortega <angel@triptico.com>

Bky is a minimalistic, distributed Version Control System / Source Code
Management tool that uses rsync as a backend to store revisions as
complete trees, optimizing the size by storing unchanged files as hard
links.

License: BSD style (Freely distributable)
See the 'License' file for details.

Features
--------

 * Distributed: The repository is not stored in a central server as in CVS
   or Subversion, but as a subdirectory inside your working directory,
   like Arch, Darcs or Linus Torvalds' git. Developers communicate via
   patches.
 * Cheap branches: Just copy your tree to another directory and you've
   started a new branch.
 * Old history is easily pruned: Legacy revisions can just be deleted or
   moved to another place with your usual filesystem tools.
 * Safety: Any given revision under the repository is a directory with all
   your files that can be used, copied or stored as-is.
 * Repository is easily manipulable: As every revision is stored as plain
   files, you can delete, add or modify files, or update the commit
   message without interfering.
 * No need for special commands to put files under version control: Just
   create a file in your working directory and it will automatically be
   version-controlled. Uninteresting files as object files, libraries or
   other generated files are automatically ignored. Also, there is support
   for .cvsignore files.
 * Small dependencies: Bky is a shell script. It needs rsync, diff and
   the usual Unix basic tools. You also need a filesystem that support
   hard and symbolic links. That's it. It's just a version control system.

Operations
----------

Initialize a repository
~~~~~~~~~~~~~~~~~~~~~~~

 bky init [-m "Initial commit message"]

Creates the basic infrastructure to convert the current directory in a
working directory + bky repository. This means creating the .bky directory
and asking for an initial commit message (unless specified by -m).

Putting new files under version control
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

There is no special command for this; any new file in the working
directory will be put under version control unless considered
'non-interesting' by rsync's -C (CVS) command line option. This means that
.o, .a, .bak and many more will automatically be ignored (see rsync
documentation). For any other file not convered there that must be
ignored, create .cvsignore files whenever needed.

Listing the changed files
~~~~~~~~~~~~~~~~~~~~~~~~~

 bky status

This command lists the files under version control that have been modified,
compared with the working directory's parent (probably the HEAD). New
files will be listed as well. Files that will disappear will be prefixed
by 'deleting'.

Seeing differencies
~~~~~~~~~~~~~~~~~~~

 bky diff
 bky diff {commit_id}
 bky diff {commit_id} -p
 bky diff {commit_id} {commit_id}

The first form compares the files in the working directory with those
stored in the working directory's parent commit id, the second one
compares the files in the working directory with those in the selected
commit id or tag, the third compares the specified commit id with its
own parent and the fourth compares the files stored in those two
commit ids. The output of these commands is in 'diff -u' (unified) format.

Please note that diff does not compare binary files.

Commiting changes
~~~~~~~~~~~~~~~~~

 bky commit [-n]
 bky commit [-m "message"]

Commits the changes in the working directory into the repository. A commit
message is asked for by spawning a text editor, unless one is specified by
the -m option.

Generating changelogs
~~~~~~~~~~~~~~~~~~~~~

 bky log

Dumps a log of the commit messages starting from the working directory's
parent commit id back to the start of the project's history.

Changing the working directory to specific revisions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 bky update -r {commit_id}
 bky update -A

The first form updates the working directory with that in the specified
commit id, and the second ones does the same with the project's HEAD (this
one works as an effective revert function). In any case, any non-commited
change to the working directory will be lost.

Please note that this command is *NOT* the same as the CVS one. Don't use
update neither to know about changes by other users (this can't be done in
distributed version control systems) nor to merge (you must do that by
applying diffs with the patch utility).

Tagging special revisions
~~~~~~~~~~~~~~~~~~~~~~~~~

 bky tag {tag}

Creates a tag for the working directory's parent commit id. The tag must
follow the filesystem's conventions for file names.

If tag is not specified, all tags are listed.

Pushing the repository to a remote site
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 bky push [rsync_directory]

Pushes the repository (including the working directory) to a remote site.
The remote repository is an rsync destination (can include a host name).
The remote site will become an exact copy of the current repository, so be
careful.

The last remote repository is stored in .bkyremote and used in next
calls if ommited. This value is shared with the 'bky pull' command.

Pulling the repository from a remote site
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 bky pull [rsync_directory]

Pulls the repository (including the working directory) from a remote site.
The remote repository is an rsync source (can include a host name). The
current repository will become an exact copy of the remote one, so be
careful.

The last remote repository is stored in .bkyremote and used in next
calls if ommited. This value is shared with the 'bky push' command.

Exporting the head of a project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 bky export {rsync_directory}

Exports the working directory's parent commit id into another directory,
without any bky metadata. This is usually done to start a branch.

Working with branches
~~~~~~~~~~~~~~~~~~~~~

There is no special command to start a branch; on distributed systems, you
just copy the project files to another place and start from there. When
the branch is ready to be merged, a diff patch is created against the root
of the branch and applied to the trunk.

If you are starting a branch to implement a complex feature that will end
up in the trunk, you probably won't need all the project history, so you
can start a new bky project for itself. You'll also want do this if you are
modifying another one's sources and want to put your changes under bky's
control.

	cd myproj
	bky-export ../myproj-cool-features
	cd ../myproj-cool-features
	bky-init -m "Start of cool-features branch."

or

	tar xzvf another-ones-project-1.0.tar.gz
	cd another-ones-project-1.0
	bky-init -m "Start of my changes to another-ones-project."

So you'll start to work in your changes, deleting, modifying and adding
files, and bky-committing when you consider and such. After you think
you're over, you'll have to patch the trunk of your project or send the
changes to the developer of the external project. So you'll want to create
a diff between the root of your branch (the commit id # 0) and your HEAD:

	bky-diff 0 > ~/cool-feats.patch

That you'll apply to your trunk

	cd myproj
	patch -p0 < ~/cool-feats.patch
	bky-commit -m "Merge of the cool-features branch."

or send to the original developer

	mail him@example.com -s "You'll like it!" < ~/cool-feats.patch

Sometimes you want to start a branch not from the HEAD of your project,
but from an important checkpoint in the past (for example, to start a
branch fixing bugs to your 1.0 release when you're deep in the development
of the 1.1 one). It's easy:

	cd myproj
	bky-update -r version-1.0
	bky-export ../myproj-1.0-bugfixes
	cd ../myproj-1.0-bugfixes
	bky-init -m "Start of the 1.0 bugfixes branch."

Importing from CVS
------------------

The cvs2bky Perl script helps in migrating from CVS to bky. You need the
_cvsps_ and _patch_ tools to do it:

	mkdir project
	cd project
	bky-init -m "Bky init."
	cvsps -b HEAD -g {cvs project name} | cvs2bky

_Cvsps_ usually chokes on binary files, so you'll probably have to add
them manually before the bky-init call. Also, sometimes _cvsps_ guesses
bad and patchsets arrive with an incorrect order; if that is your case,
you probably have to dump its output to a file (instead of piping
directly) and reorder the patchsets yourself.

If your CVS repository is remote, the whole operation can be very long.

---
Angel Ortega http://www.triptico.com