Bky - a minimalistic, distributed VCS / SCM =========================================== Angel Ortega 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