# Game of Trees [Game of Trees (Got)](/http://gameoftrees.org) is a simple, easy to use version control system that aims to be compatible with git repos. It's still under development, but can be used today as a substitute for git. It is freely reusable under a BSD license. ## Install $ doas pkg_add got ## Configuring got First, we need to tell [got](/http://gameoftrees.org/got.1.html) about the author of the repo: $ export GOT_AUTHOR="username " Replace `username` and `username@example.com`. It's recommended to add this as part of your [~/.profile](/ksh/profile): $ echo 'export GOT_AUTHOR="username "' >> ~/.profile Let's also enable tab-completion of got commands: $ echo 'set -A complete_got_1 -- $(got -h 2>&1 | sed -n s/commands://p)' >> ~/.profile By default, got uses the text editor [ed](Openbsd/Ed) if [$EDITOR](/ksh/editor) or [[$VISUAL](/ksh/editor) are not set. By default, got uses the text editor [ed](Openbsd/Ed) if [$EDITOR](/ksh/editor) or [[$VISUAL](/ksh/editor) are not set. ## Clone a repository To clone a repo without encryption (**WARNING**: insecure): $ got clone git://example.com/repo.git Replace `example.com/repo.git` with your actual path. For this guide, we will use the ngircd git repo as an example: $ cd ~ $ got clone git://github.com/ngircd/ngircd To clone a repo using [ssh](/OpenSSH/Connect): $ got clone ssh://example.com/repo.git For example, to clone OpenBSD's github repo: $ cd /var/git/ $ got clone ssh://git@github.com/openbsd/src.git HTTP URLs currently requires [git](/git/usage): $ git clone https://github.com/ngircd/ngircd ## Checkout code Once you have a repository, you must first **checkout** the code into a **work tree** before you can use it: $ got checkout /path/to/repository Replace `/path/to/respository`. Let's checkout the ngircd code: $ cd ~ $ got checkout ~/ngircd.git You can check out code from a specific branch or commit with `-b` and `-c`: $ got checkout -b branch -c commit /path/to/repository got creates an ID SHA1 hash for every commit, so replace `commit` with that hash. Before we can checkout another work tree from ngircd, we must delete the old one: $ rm -r ~/ngircd $ got checkout -b HEAD -c f4ade537d550b872b7e86e6ffce940dfbad4c60c ~/ngircd.git This will first delete the old work tree, then check out the f4ade537d550b872b7e86e6ffce940dfbad4c60c commit from HEAD of the ngircd.git repo. `got checkout` will show these status codes: || border=1 width=50%25 class="sortable simpletable" ||# Status || Meaning || || A || new file added || || E || file already exists || For the next step, we will go ahead and delete this work tree, then check out a work tree based on the most recent commit: $ rm -r ~/ngircd $ got checkout ~/ngircd.git ## Create a new repository To create an empty repository: $ got init /path/to/repository Replace `/path/to/repository`. For example: $ got init ~/ircnowd.git This will create a got repo called ircnowd. Afterwards, we need to import the code for the repository: $ got import -m "Import sources" -r /path/to/repository /path/to/code * `-m` provides the log message for the import. * `-r` provides the repository path. Replace `/path/to/repository` and `/path/to/code`. For example: $ got import -m "Import sources" -r ~/ircnowd.git ~/ngircd This will import the code from `ngircd` into `ircnowd.git`. ## Fetch new changes To fetch changes from a remote repo: $ got fetch ## Add file To add an unversioned file for the next commit: $ got add filename Replace `filename`. For example: $ echo 'print "hello, world"' > ~/ngircd.git/hello.sh $ got add ~/ngircd.git/hello.sh If adding a directory: $ got add -R pathname `-R` allows recursion. Replace `pathname`. Let's add a directory with a file inside `ngircd.git`, then begin tracking the directory with got: $ mkdir -p ~/ngircd.git/newcode/ $ echo 'print "IRCNow and Forever"' > ~/ngircd.git/newcode/ircnow.sh $ got add -R ~/ngircd.git/newcode ## Remove file To remove a versioned file for deletion from the repo in the next commit: $ got remove filename Replace `filename`. Let's remove hello.sh: $ got remove ~/ngircd.git/hello.sh If removing a directory: $ got remove -R pathname `-R` allows recursion. Replace `pathname`. Let's remove the `newcode` directory: $ got remove -R ~/ngircd.git/newcode/ ## View changes To view changes in a work tree: $ got diff If you provide two objects, got will show the diff between just those two: $ got diff object1 object2 Replace `object1` and `object` with the ID SHA1 hash. For example: $ got diff ab0eb099e9c0ed60d25fb50dd78d2a638d3b49b8 f4ade537d550b872b7e86e6ffce940dfbad4c60c This will give you the diff of two files with those ID hashes. ## Blame For a line-by-line history of a file: $ got blame /path/to/file Use `-c commit` and replace `committ` with the ID SHA1 hash to start history from that specific commit. For example: $ cd ~/ngircd $ got blame -c 71ae2b7d ~/ngircd/NEWS ## Update To update the work tree to the most recent commit on the work tree's branch: $ got update This will require manual merging of files if there are conflicts. || border=1 width=100%25 class="sortable simpletable" ||# Status || Meaning || || U || file updated, no local changes || || G || file updated, local changes merged || || C || file updated, conflicts occurred during merge || || D || file deleted || || A || new file added || || ~ || versioned file blocked by non-regular file || || # || missing versioned file restored || || # || file not updated due to merge conflicts || || ? || changes for an unversioned file not merged || **NOTE**: If there are staged changes, you must first commit or unstage them before using `got update`. Suppose we check out a specific commit: $ cd ~ $ rm -r ngircd $ got checkout -b HEAD -c f4ade537d550b872b7e86e6ffce940dfbad4c60c ~/ngircd.git We can then update a specific commit: $ got update -c c8b12af1d2d155ec79dc2044a4ff177cf07de4fe ## View status To view the status of files in a work tree: $ got status || border=1 width=100%25 class="sortable simpletable" ||# Status || Meaning || || M || modified || || A || added in next commit || || D || deleted in next commit || || C || modified or added but contains merge conflicts || || # || versioned file expected but missing || || ~ || versioned file blocked by non-regular file || || ? || unversioned item, not tracked || If changes are staged, the second column uses these codes: || border=1 width=100%25 class="sortable simpletable" ||# Status || Meaning || || M || modification staged || || A || addition staged || || D || deletion staged || ## Show History To show commit history: $ got log This will produce a log of all commits from the current branch: ... ----------------------------------------------- commit ab0eb099e9c0ed60d25fb50dd78d2a638d3b49b8 from: Alexander Barton date: Tue Dec 11 22:04:21 2001 UTC - Test auf stdint.h (HAVE_STDINT_H) hinzugefuegt. ----------------------------------------------- commit f4ade537d550b872b7e86e6ffce940dfbad4c60c from: Alexander Barton date: Tue Dec 11 21:53:04 2001 UTC Initial revision To display commits from other branches `-b`, starting at a specific commit `-c`, limited by the number of commits `-l`: $ got log -b -c commit -l N Replace `commit` with the ID SHA1 hash and `N` with the number of commits. For example: $ got log -b -c 71ae2b7d7f9ae7bc02ed072c07100de0027373d6 -l 10 ----------------------------------------------- commit 71ae2b7d7f9ae7bc02ed072c07100de0027373d6 (master, origin/master, tags/rel-26.1) from: Alexander Barton date: Sat Jan 2 13:32:48 2021 UTC ngIRCd Release 26.1 ... It's also possible to show commits that match a [regular expressions](/https://man.openbsd.org/re_format): $ got log -s regex Replace `regex` with a [regular expression](/https://man.openbsd.org/re_format): $ got log -s ssl ----------------------------------------------- commit daa88b765111b14047c97256bd2a9a2daabe123b from: Christoph Biedl date: Mon Dec 5 22:51:07 2016 UTC via: Alexander Barton Fix building ngIRCd with OpenSSL 1.1 ... ## Branching To print the name of the current branch of the work tree: $ cd /path/to/worktree $ got branch To list all the branches: $ got branch -l Inside a work tree, you can create a branch and switch to it: $ got branch branchname Replace `branchname`. You can also delete a branch: $ got branch -d branchename Only the branch reference `branchname` is deleted; commit, tree, and blob objects remain in the repo. To branch at a specific commit: $ got branch -c commit branchname Replace `commit` with the ID SHA1 hash and replace `branchname`. For example: $ got branch -c 02850008f4a4e8fff5799157d21ee7924345b3e1 gnutls This creates the gnutls branch of ngircd. ## Tags To list all existing tags: $ got tag -l To create a tag pointing to the most recent commit: $ got tag -m "Message" tagname Replace `tagname` and `Message`. To create a tag pointing to a specific commit: $ got tag -c commit -m "Message" tagname Replace `commit` with the ID SHA1 hash and replace `Message` and `tagname`. For example: $ got tag -c 3c627dd70d032fa2c5087617da27586cf85e899a -m "Debian OpenSSL Build" debopenssl This will create the `debopenssl` tag to point to commit `3c627dd70d032fa2c5087617da27586cf85e899a`. ## Revert changes If you make any changes to files or folders in a work tree, you can revert those changes: **WARNING**: There is no way to undo reverted changes! $ got revert /path/to/file Replace `/path/to/file`. Files added with `got add` become unversioned, and files deleted with `got remove` are restored. To be safe, use `-p` so that got asks before reverting. You can also add `-R` for recursion: $ got revert -R -p /path/to/folder For example: $ cd ~/ngircd $ mkdir JUNK $ echo "Here is some new junk" > JUNK/INFO $ got add -R JUNK/ $ got revert -R -p JUNK/ ## Commit To commit changes in a work tree: $ got commit -m "Commit message" Replace `Commit message` with a commit message. If changes have been staged, only staged changes will be committed. || border=1 width=50%25 class="sortable simpletable" ||# Status || Meaning || || M || modified file || || D || file deleted || || A || new file added || **NOTE**: If changes are not based on the most recent commit, you may first be required to run `got update` before commits can be made. **NOTE**: Before running `got commit`, make sure to set up the GOT_AUTHOR environment variable (see above). ## Send Changes To send changes to a remote repo: $ got send -r ssh://path.com/to/repo Replace `ssh://path.com/to/repo` with the protocol and URL. By default, if no remote repo is provided, the work tree's origin (its default repo) will be used. Changes are only be sent if they are based on up-to-date branches in the remote repo. If not, new changes must first be fetched with `got fetch` and local branches must be rebased with `got rebase`. `-f` ignores this requirement. **WARNING**: Try to avoid `-f` because it may result in inconsistent tags in different repos. To send all branches: $ got send -r ssh://path.com/to/repo -a Replace `path.com/to/repo`. To specify a specific branch: $ got send -r ssh://path.com/to/repo -b branchname Replace `branchname`. To delete a branch (only references are deleted): $ got send -r ssh://path.com/to/repo -d branchname ## Rebase When you have multiple branches, you may want to rebase the commits of one branch onto your current branch: $ got rebase branchname Replace `branchname`. Note that `branchname` must have a common ancestor with the current branch. Commits from `branchname` are made to the work tree's current branch. To show a list of past rebases: $ got rebase -l ## Staging To stage for the next commit: $ got stage To stage just one file: $ got stage /path/to/file stage [-l] [-p] [-F response-script] [-S] [path ...] || border=1 width=50%25 class="sortable simpletable" ||# Status || Meaning || || A || addition staged || || M || modification staged || || D || deletion staged || If there are staged changes, got commit will not commit any paths that do not have staged changes. To list staged changes: $ got stage -l If a file is out of date compared with the work tree's current branch, you must run `got update` before staging. To unstage all changes: $ got unstage To unstage a single file: $ got unstage /path/to/file ## Info To show metadata about a work tree: $ got info To show additional data about a file: $ got info /path/to/file