Using Cogito

Cogito is a version control system layered on top of the git content-tracking filesystem. This document first describes some quick ways to get started using Cogito, then goes over each available command one by one.

1. Quickstart

1.1. Downloading Cogito From Scratch

Cogito can be obtained as a tarball from

http://www.kernel.org/pub/software/scm/cogito/

Download and unpack the latest version, build with make, put the executables somewhere in your $PATH (or add your Cogito directory itself to your $PATH), and you're ready to go!

The following tools are required by Cogito:

Tool Description
bash All Cogito executables are scripted in bash.
sed, grep, textutils The basic shell environment.
diff, patch The basic utilities for tracking file changes.
diffstat Needed for showing patch summaries. (optional)
RCS Specifically, the merge program from this package.
mktemp 1.5+ Mandrake users beware! Upgrade might be needed.
libssl Specifically, the SHA1 functions from this library.
rsync For pulling files with the rsync backend.
libcurl, wget For pulling files with the HTTP backend.
ssh For pulling files with the git+ssh backend.
asciidoc, xmlto Needed for building documentation. (optional)

1.2. Starting A Fresh git Repository

If you want to start your own project using Cogito, there are two basic ways to do this. You may start a fresh repository with no files in it, or you may take an existing directory tree and turn it into a git repository.

1.2.1. Starting An Empty Repository

To create a new repository with no files in it, cd into an empty directory, and give the following command:

$ cg-init

Your editor will start up, and you will be asked to type in an initial commit description. Type something cute, and exit your editor.

That's it! You're now in your own git repository. Notice there is now a .git directory. Go into it and look around, but don't change anything in there. That's what the Cogito commands are for.

1.2.2. Turning An Existing Directory Into A Repository

If you have a directory full of files, you can easily turn this into a git repository. In fact, it is virtually the same as starting an empty repository. Just cd into the directory you want converted into a git repository, and give the following command:

$ cg-init

Your editor starts up, you type in an initial commit message, exit your editor, and you're good to go. All of the files and directories within that directory are now part of a git archive.

1.3. Accessing Someone Else's git Repository

1.3.1. Creating The Repository

If you want to get started tracking an outside git repository, you first must have Cogito's executables on your $PATH. Next, you need the URL (or local directory path) of the repository you want to track. You can't just use the URL of a tarball, like the one given above for the Cogito source. The URL must point specifically to a .git directory somewhere. For instance, the URL for Cogito's self-hosting repository is

rsync://rsync.kernel.org/pub/scm/cogito/cogito.git

Notice that the final filename, cogito.git, is not called .git. That is fine. It's still a .git directory.

To clone the repository to your local filesystem, use the cg-clone command. cg-clone can be told to create a new directory for your repository, or to drop the repository into the current directory.

To have a new directory created, just include the directory in the command, as follows:

$ cg-clone rsync://rsync.kernel.org/pub/scm/cogito/cogito.git cogitodir

You will see a whole bunch of output, and when it is over, there will be a new directory called cogitodir (or whatever name you chose) in the current directory. cd into it. Because we used the Cogito URL, you will see the Cogito source tree, with its own .git directory keeping track of everything.

If, instead, you want to clone the repository to the current directory, first make sure you are in an empty directory. Then give the following command:

$ cg-clone -s rsync://rsync.kernel.org/pub/scm/cogito/cogito.git

When you get your prompt back, do an ls to see the source tree and .git directory.

1.3.2. Tracking The Repository

Of course, once you have cloned a repository, you don't just want to leave it at that. The upstream sources are constantly being updated, and you want to follow these updates. To do this, cd into the repository directory (not the .git directory, but the directory that contains the .git directory), and give the following command:

$ cg-update

You don't use a URL anymore. Cogito knows which tree you're tracking, because this information is stored in the .git directory. The above command will track the origin branch, which is the primary branch of development. But cg-update can also be used to track specific branches. See below for more discussion of branches, and how to track them.

When you give the above cg-update command, this performed two actions. First, it pulled all new changes from the upstream repository into your local repository. At that point, the changes exist in your local repository as part of the project's history. The changes themselves are not actually visible in the files you see, but reside in the .git directory's awareness. The second thing cg-update does is to merge these changes into the files you see and work with. The end result is that, when the cg-update has finished, you will see all the upstream changes reflected in your local files, and the .git directory will be aware of the history of those changes as well.

It may be that you want to be aware of the history of the upstream work, but you don't yet want those changes merged with your own local files. To do this, give the following command:

$ cg-pull

This does the first part of cg-update's behavior, but skips the second part. Now your local files have not been changed, but your .git directory has been updated with the history of all the changes that have occurred in the upstream sources.

Using cg-pull is useful for a variety of purposes, for instance if you want to construct a diff against the latest version of the upstream sources, but don't want those changes to disturb your ongoing work. cg-pull will update your .git directory with the history you need to construct your diff, without merging that history into your tree, potentially breaking your changes.

Typically, if you are not making changes to a repository yourself, but just want the latest version of a given project for your own use, you would use cg-update. cg-pull is strictly for development work.

Once you've done a cg-pull, you may decide you want to merge after all. In this case a cg-update command will do the trick, however you will also update your local files with any further upstream changes that have occurred since your cg-pull.

1.4. Getting Help

Cogito commands come with their own helpful documentation. To get help on cg-update, for example, give this command:

$ cg-pull --help

or, for the same information, try this:

$ cg-help cg-pull

2. Command Reference

Heres a quick overview of the available commands:

Command Summary
cg-add Add files to the GIT repository.
cg-admin-lsobj List objects of the GIT repository.
cg-admin-uncommit Undo a commit or a series of commits.
cg-branch-add Add new branch to the GIT repository.
cg-branch-ls List configured GIT branches.
cg-cancel Cancels current edits in the working tree.
cg-clone Clone a remote GIT repository.
cg-commit Commit into a GIT repository.
cg-diff Make a diff between two GIT trees.
cg-export Exports a particular revision from a GIT repository.
cg-help Show help for Cogito commands.
cg-init Initialize a GIT repository.
cg-log Make a log of changes in a GIT branch.
cg-ls List contents of a particular tree in a GIT repository.
cg-merge Merge a branch to the current tree.
cg-mkpatch Make a patch from one or several commits.
cg-patch Apply a diff generated by cg-diff.
cg-pull Pull changes from a remote branch to the local GIT repository.
cg-restore Restore removed/changed files in the working tree.
cg-rm Remove files from a GIT repository.
cg-seek Seek the working tree to a given commit.
cg-status Show status of entries in your working tree.
cg-tag Mark certain commit by a tag.
cg-tag-ls List stored GIT tags.
cg-update Pull and merge changes from a branch to the local repository.
cg-version Show the version of the Cogito toolkit.

2.1. Caveats

2.1.1. What are those cg-X* and *-id files?

There are three executables, cg-Xdiffdo, cg-Xlib, and cg-Xmergefile, that are not meant to be used from the command line. They provide a library of generic functions used by many of the real cg-* commands. The same is pretty much true for commit-id, tree-id, and parent-id. They are used by the Cogito scripts to translate stuff like symbolic names such as branches and tags to IDs used by the git layer. You can safely ignore them, unless you want to contribute to Cogito development.

2.1.2. What about file renames?

File renaming (and tracking the history of a file from name to name) is being worked on. git provides a wonderful, elegant way to track content as it moves from file to file, and renames should be a special case of this.

2.1.3. Can I give Cogito commands from a subdirectory?

Cogito currently requires that commands be given from the base directory, the one containing the .git directory. Patches have been submitted to implement the ability to give Cogito commands from subdirectories within the repository, but Linus prefers the current behavior.

2.2. cg-add

This command is used to add files to the git repository. It takes a list of files on the command line, and schedules them for addition. To actually add them, however, you must subsequently give a cg-commit command.

$ cg-add file1 file2 dir1/file3 dir1/file4 dir2/dir3/file5

The above command schedules file1, file2, file3, file4, and file5 to be added to the repository at the next cg-commit.

Notice that you never need to add directories to a repository, in fact Cogito won't let you. Directories are added automatically when you add the files that are inside them. So you can do something like this:

$ mkdir testdir
$ echo "testtext" > testdir/testfile
$ cg-add testdir/testfile
$ cg-commit

and the testdir directory and testfile file will both be added to the repository. If you then do a cg-seek to look at an earlier version of the repository, both the file and the directory will be gone.

2.3. cg-admin-lsobj

This lowlevel command makes it possible to query and list list objects from the git database. The listing can be restricted to a specific object type, such as blob, tree, commit or tag. This can be handy if you were messing with your HEAD and lost track of a few commits. It would be possible to find them by doing:

for i in `cg-admin-lsobj commit | cut -f 1`; do
        echo -e "\n==================\nme $i"; cat-file commit $i;
done

2.4. cg-admin-uncommit

STUB

2.5. cg-branch-add

STUB

2.6. cg-branch-ls

$ cg-branch-ls
origin  /home/user/projects/cogito/.git
pasky   rsync://rsync.kernel.org/pub/scm/cogito/cogito.git

STUB

2.7. cg-cancel

This undoes all the changes you have made but not committed to your repository. Changes you have already committed are kept. All others are reverted to their previous form.

If you have given any cg-add commands, these are also undone in the sense that the files and directories will no longer be added on a cg-commit. The files and directories themselves are not deleted by a cg-cancel.

2.8. cg-clone

This checks out a remote repository into a local filesystem. It is only used for the initial creation of the local repository. Subsequent updates to track the upstream sources are done with cg-update or cg-pull.

In its simplest form, cg-clone takes a URL or directory path to a remote repository:

$ cg-clone rsync://rsync.kernel.org/pub/scm/cogito/cogito.git

The above command interprets the URL and takes the base directory (in this case cogito) as the target for the new repository. If the directory already exists within the current directory, cg-clone exits with an error message. Otherwise this directory is created within the current directory. cg-clone then clones the upstream repository into that directory.

It's also possible to specify the target directory by hand on the command line, as follows:

$ cg-clone rsync://rsync.kernel.org/pub/scm/cogito/cogito.git targetdir

If targetdir already exists, cg-clone will exit again with an error message. Otherwise, targetdir is created, and the upstream repository is cloned into it.

If you want to clone the upstream sources into the current directory, use the -s option:

$ cg-clone -s rsync://rsync.kernel.org/pub/scm/cogito/cogito.git

This will not create a new directory anywhere, but will just create the repository directly into the current directory. Any files or directories already in the current directory will not be overwritten, and files of the same name will retain their old contents. Typically, you never want to use the -s option in a directory with existing files or subdirectories.

2.9. cg-commit

This command is used after you have edited files in a repository, and now want to include your changes in the project history. After a cg-commit, your changes will have a changelog entry, including your identity, the date of the change, and other information.

Typically you do not need to give any command line options to cg-commit, but just use it in its simplest form:

$ cg-commit

This will fire up your editor and ask for a changelog entry. If you leave this text blank, a changelog entry will still be created, but with no explanatory text. When you exit your editor, your changed files and changelog entry are included in the history of the repository, and are subject to full version control.

There are several ways to avoid dealing with an editor at commit time. cg-commit accepts changelog entries from standard input:

$ echo "my first changelog entry" | cg-commit

You can also specify your changelog entry with the -m option to cg-commit:

$ cg-commit -m"my first changelog entry"

If a changelog entry is sent via standard input, and another one is included in a -m option, the entry from standard input is appended with no blank line after the entry from the -m option.

Multiple -m options can also be given, and they will each be appended, with a blank line between, after the one before in the changelog entry.

A -e option also exists, to force an editor to come up for a commit message, even if -m options are present, or if there is data coming from standard input. In this case, all input from standard input or -m options is appended with a blank line after the text typed into the editor.

A -E option also exists and behaves identically to -e, except it will force the commit even if the default commit message is not changed.

A -C option also exists, but it is for internal purposes. You can safely ignore it.

There are several environment variables you may use to control the authentication information included with the changelog entry. Typically, Cogito uses getpwuid(getuid()) to identify the user. This can be overridden with these variables:

Environment variable Description
GIT_AUTHOR_NAME Author's name
GIT_AUTHOR_EMAIL Author's e-mail address
GIT_AUTHOR_DATE Date, perhaps from a patch e-mail
GIT_COMMITTER_NAME Committer's name
GIT_COMMITTER_EMAIL Committer's e-mail address

In the above variables - and in the changelog entries - the author is the person who actually wrote a given patch, and the committer is the person who actually gave the command to include this patch in the repository. If you are just working on your own repository, or if you commit your own patches, then the author and committer are both you.

2.10. cg-diff

This compares two trees and outputs a diff, suitable for feeding into the patch program. If there is no difference between the trees, cg-diff just outputs "ok".

With no arguments, it compares the state of your working tree, including all your uncommitted changes, with the state of the tree at the last commit. The result in this case is a diff showing only the changes you have not yet committed. To do this, give the following command:

$ cg-diff

You can use the -r command to specify a single tree to compare against your current working directory:

$ cg-diff -r 9e734775f7c22d2f89943ad6c745571f1930105f

More generally, cg-diff can be used to produce a diff between any two SHA1 IDs (or tags). The most common way is with a single -r command line argument, specifying two trees by hash IDs:

$ cg-diff -r 9e734775f7c22d2f89943ad6c745571f1930105f:0397236d43e48e821cce5bbe6a80a1a56bb7cc3a

The same command using tags would be:

$ cg-diff -r v2.6.12-rc2:v2.6.12-rc3

Or you could use two -r commands to accomplish the same thing:

$ cg-diff -r v2.6.12-rc2 -r v2.6.12-rc3

Using the colon-separated form, leaving one SHA1 ID or tag name out implies that cg-diff should compare the specified tree to the current HEAD:

$ cg-diff -r v2.6.12-rc2:

compares Linux kernel version 2.6.12-rc2 with HEAD, creating a patch to convert the 2.6.12-rc2 tree into HEAD. To do the reverse, you simply put the : at the other end of the string:

$ cg-diff -r :v2.6.12-rc2

This command compares HEAD to Linux kernel version 2.6.12-rc2, creating a patch to convert HEAD into the 2.6.12-rc2 tree.

The cg-diff command can also take a -p argument.

STUB - get more info on the -p arg

2.11. cg-export

This command extracts the actual project under version control and puts it somewhere for you. Not the revision control history but the project files themselves. So if you have the Linux kernel in a git repository and you give a cg-export command, only the kernel files themselves, not the git repository files, will be exported.

You must specify a destination for the export on the command line. This may have several different interpretations:

$ cg-export dirname

In the command above, dirname is a directory name. In this case, cg-export exports the current state of the project to that directory.

$ cg-export filename.tar

In the above, filename.tar has a .tar extension, and so cg-export produces a tarball of the current state of the project. Other recognized extensions are .tar.gz, .tgz, and .tar.bz2.

You may specify an additional command line argument that is an SHA1 hash ID (or tag), to indicate the particular version of the tree you wish to export:

$ cg-export filename.tgz 0397236d43e48e821cce5bbe6a80a1a56bb7cc3a

or equivalently:

$ cg-export filename.tgz v2.6.12-rc3

This ability makes cg-export quite powerful. It is not just a tool for packaging the current state of the tree, it can package any past state as well.

2.12. cg-help

This command is used to get help about other Cogito commands. The form is very simple. For instance, to get help on cg-pull, give the following command:

$ cg-help cg-pull

This is identical to giving this command as well:

$ cg-pull --help

Help for all other commands use an identical form.

2.13. cg-init

This is used to initialize a new git repository. There are two cases: either you want to start a repository in an empty directory; or you want to start a repository in a full directory, using the existing files in that directory to seed the repository. In both cases the procedure is the same. Change directories into the directory you want to turn into the repository. Do not create a .git directory or anything weird like that. Just go into your target directory and give this command:

$ cg-init

Your editor (as defined in the $EDITOR environment variable) will start up and you will be asked to write your first commit message. Make it a good one. Exit the editor. Welcome to Cogito.

2.14. cg-log

This command generates changelog entries. Unless output is explicitly redirected, cg-log pipes all of its output to less. If invoked with no arguments, it shows all available changelog entries:

$ cg-log

You may use the -r command line argument to specify an SHA1 hash ID (or tag name), or a pair of these. cg-log will generate all log entries starting after the first, up to and including the second:

$ cg-log -r v2.6.12-rc2:v2.6.12-rc3

The above command shows all the log entries starting after the actual 2.6.12-rc2 release, up to and including the entry marking the release of 2.6.12-rc3. In other words, it produces the full changelog for 2.6.12-rc3.

You may also use the -u command line argument, to specify the name - or part of the name - of the person who authored or committed the patch.

$ cg-log -uStroesser

Notice that there is no space between the -u and the name. If there are spaces in the name, you must use quotes, like this:

$ cg-log -u"Irwin Fletcher"

Whatever other arguments you give, you may also append a list of files on the command line. In that case, cg-log will output only the log entries of patches that altered those files.

$ cg-log README Documentation/git.txt

or

$ cg-log -r v2.6.12-rc2:v2.6.12-rc3 -uLinus Makefile

There are two options that control how output is displayed in cg-log. The -f option can be given with no arguments, to tell cg-log to include a list of all affected files with each changelog entry.

$ cg-log -f -r v2.6.12-rc2:v2.6.12-rc3

The other option to control output is -c. It can be given with no arguments, to cause cg-log to display its output in color.

$ cg-log -c -f -r v2.6.12-rc2:v2.6.12-rc3

Currently, the following changelog elements map to the following colors:

Element Color
commit, tree, parent Green
author Cyan
committer Magenta
files Blue
signoff Yellow

2.15. cg-ls

This command lists all the files in the repository, along with their current SHA1 hash ID and the type of data they represent to git (blob, tree).

With no arguments, cg-ls operates on the current state of the repository. If given a commit ID or tree ID as a command line argument, it will list the files current as of that commit, or to that tree.

STUB (this section needs filling out)

2.16. cg-merge

STUB

2.17. cg-mkpatch

STUB

2.18. cg-patch

STUB

2.19. cg-pull

See the section on tracking a repository above.

2.20. cg-restore

STUB

2.21. cg-rm

This command schedules a group of files for removal from the git repository, and also removes them right away from your working set of files. Although gone from your working set of files, the repository still considers them part of the tree until you give a cg-commit command.

2.22. cg-seek

STUB

2.23. cg-status

This command takes no arguments, and returns a list of files you have changed in your local tree, but that you have not yet committed with cg-commit. File additions and removals with cg-add and cg-rm are not listed. A sample usage follows:

$ cg-status
M cache.h
$

2.24. cg-tag

This command gives a convenient name of your choosing to a particular state of the repository, associating that name with the otherwise cumbersome hash ID. You may tag the current state of a repository, or you may specify a particular hash ID to tag from any previous state. In software development, a developer might tag a particular release with a version number. When Linus releases a new kernel, he tags it v2.6.12-rc4 or something similar.

To tag the current state of a repository, just specify the name of the tag, as follows:

$ cg-tag v2.6.12-rc4

To tag a specific state from some time in the past, you must specify the SHA1 hash ID, like this:

$ cg-tag v2.6.12-rc4 ebb5573ea8beaf000d4833735f3e53acb9af844c

You can select a particular hash ID by looking at the commit of the changelog entry representing the repository state you wish to tag.

Tags are interchangeable with hash IDs in Cogito commands. Typically, to do a diff between two states of a repository, you must give a command like this:

$ cg-diff -r 0397236d43e48e821cce5bbe6a80a1a56bb7cc3a:ebb5573ea8beaf000d4833735f3e53acb9af844c

With tags, the same command can be given much more intuitively, like this:

$ cg-diff -r v2.6.12-rc3:v2.6.12-rc4

Both of the above examples will show you the diff between Linux kernel version 2.6.12-rc3 and 2.6.12-rc4.

2.25. cg-tag-ls

This command takes no arguments, and lists all tags in a given repository in alphabetical order, along with their corresponding SHA1 hash IDs. Doing this on the current Cogito repository, for instance, produces the following output:

$ cg-tag-ls
cogito-0.10     4ed293bc0a5ffca9683e139cad499b69a4c4d569
cogito-0.8      f9f0459b5b39cf83143c91ae39b4eaf187cf678a
cogito-0.9      cc5517b4ea4134c296d4ce2b1d82700c44200c1e
git-pasky-0.1   463d05c7c4fe7f24da29749f4c7f25893fc20b8c
git-pasky-0.2   2c70421be7d88fbee49986d7a5584d1f010a25de
git-pasky-0.3   d14925c87cdb6ca6345bcb3c8e34a2d659c79451
git-pasky-0.4   b0bb73f33fc06cc5ff6fca0d2dfce484c5f191b7
git-pasky-0.5   0ec59a771ff9d618a1b86e0cc1b93e3d9dad17a9
git-pasky-0.6   b498dafca4dcc136294853d1de09fb64b0b0deea
git-pasky-0.6.1 1690697813ffcfc35075859534a627699d07c613
git-pasky-0.6.2 b21cee2236b494787204754960d6a5d2916dfeb4
git-pasky-0.6.3 acc71aab89b4ae8d5f4a03c758cc4c2bc04a3229
git-pasky-0.7   bc61d9a04dc39598014f38b0ad7422f0ceaf2cc9
pull_from_pasky 11ed64c1b141c9ba397a1ca76aef2cd250976007
$

2.26. cg-update

See the section on tracking a repository above.

2.27. cg-version

This commands prints the version of the installed Cogito. If you installed Cogito from a git repository you will also see the .git/HEAD ID of the installed version:

$ cg-version
cogito-0.10 (5b8a6821715d2af7085ae7c408d1ccd4133462b0)