Examples
Enable tab-completion of got command names in ksh(1):
$ set -A complete_got_1 -- $(got -h 2>&1 | sed -n s/commands://p)
Clone an existing Git repository for use with got:
Unfortunately, many of the popular Git hosting sites do not offer anonymous access via SSH. Such sites will require an account to be created, and a public SSH key to be uploaded to this account, before repository access via ssh:// URLs will work.
Most sites offer anonymous repository access via HTTPS:
$ got clone https://github.com/openbsd/src.git
Alternatively, for quick and dirty local testing of got a new Git repository could be created and populated with files, e.g. from a temporary CVS checkout located at /tmp/src:
$ got init /var/git/src.git
$ got import -r /var/git/src.git -I CVS -I obj /tmp/src
Check out a work tree from the Git repository to /usr/src:
$ got checkout /var/git/src.git /usr/src
View local changes in a work tree directory:
In a work tree, display files in a potentially problematic state:
Interactively revert selected local changes in a work tree directory:
In a work tree or a git repository directory, list all branch references:
As above, but list the most recently modified branches only:
In a work tree or a git repository directory, create a new branch called “unified-buffer-cache” which is forked off the “master” branch:
$ got branch -c master unified-buffer-cache
Switch an existing work tree to the branch “unified-buffer-cache”. Local changes in the work tree will be preserved and merged if necessary:
$ got update -b unified-buffer-cache
Create a new commit from local changes in a work tree directory. This new commit will become the head commit of the work tree's current branch:
In a work tree or a git repository directory, view changes committed in the 3 most recent commits to the work tree's branch, or the branch resolved via the repository's HEAD reference, respectively:
As above, but display changes in the order in which patch(1) could apply them in sequence:
In a work tree or a git repository directory, log the history of a subdirectory:
While operating inside a work tree, paths are specified relative to the current working directory, so this command will log the subdirectory sys/uvm:
$ cd sys/uvm && got log .
And this command has the same effect:
$ cd sys/dev/usb && got log ../../uvm
And this command displays work tree meta-data about all tracked files:
Add new files and remove obsolete files in a work tree directory:
$ got add sys/uvm/uvm_ubc.c
$ got remove sys/uvm/uvm_vnode.c
A file can be renamed or moved by removing it from its old location and adding it at the new location:
got does not yet follow file history across renames, but git(1) will be able to do so regardless.
Create a new commit from local changes in a work tree directory with a pre-defined log message.
$ got commit -m 'unify the buffer cache'
Alternatively, create a new commit from local changes in a work tree directory with a log message that has been prepared in the file /tmp/msg:
Update any work tree checked out from the “unified-buffer-cache” branch to the latest commit on this branch:
Roll file content on the unified-buffer-cache branch back by one commit, and then fetch the rolled-back change into the work tree as a local change to be amended and perhaps committed again:
$ got backout unified-buffer-cache
$ got commit -m 'roll back previous'
$ # now back out the previous backout :-)
$ got backout unified-buffer-cache
Fetch new changes on the remote repository's “master” branch, making them visible on the local repository's “origin/master” branch:
Rebase the local “master” branch to merge the new changes that are now visible on the “origin/master” branch:
$ got update -b origin/master
Rebase the “unified-buffer-cache” branch on top of the new head commit of the “master” branch.
$ got rebase unified-buffer-cache
Create a patch from all changes on the unified-buffer-cache branch. The patch can be mailed out for review and applied to OpenBSD's CVS tree:
$ got diff master unified-buffer-cache > /tmp/ubc.diff
Edit the entire commit history of the “unified-buffer-cache” branch:
$ got update -b unified-buffer-cache
Before working against existing branches in a repository cloned with git clone --bare instead of got clone, a Git “refspec” must be configured to map all references in the remote repository into the “refs/remotes” namespace of the local repository. This can be achieved by setting Git's remote.origin.fetch configuration variable to the value “+refs/heads/*:refs/remotes/origin/*” with the git config command:
$ git config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
Additionally, the “mirror” option must be disabled:
$ git config remote.origin.mirror false
Alternatively, the following git-fetch(1) configuration item can be added manually to the Git repository's config file:
fetch = +refs/heads/*:refs/remotes/origin/*
This configuration leaves the local repository's “refs/heads” namespace free for use by local branches checked out with got checkout and, if needed, created with got branch. Branches in the “refs/remotes/origin” namespace can now be updated with incoming changes from the remote repository with got fetch or git-fetch(1) without extra command line arguments. Newly fetched changes can be examined with got log.
Display changes on the remote repository's version of the “master” branch, as of the last time got fetch was run:
$ got log -c origin/master | less
As shown here, most commands accept abbreviated reference names such as “origin/master” instead of “refs/remotes/origin/master”. The latter is only needed in case of ambiguity.
got rebase can be used to merge changes which are visible on the “origin/master” branch into the “master” branch. This will also merge local changes, if any, with the incoming changes:
$ got update -b origin/master
In order to make changes committed to the “unified-buffer-cache” visible on the “master” branch, the “unified-buffer-cache” branch can be rebased onto the “master” branch:
$ got rebase unified-buffer-cache
Changes on the “unified-buffer-cache” branch can now be made visible on the “master” branch with got integrate. Because the rebase operation switched the work tree to the “unified-buffer-cache” branch, the work tree must be switched back to the “master” branch first:
$ got integrate unified-buffer-cache
On the “master” branch, log messages for local changes can now be amended with “OK” by other developers and any other important new information:
$ got update -c origin/master
If the remote repository offers write access, local changes on the “master” branch can be sent to the remote repository with got send. Usually, got send can be run without further arguments. The arguments shown here match defaults, provided the work tree's current branch is the “master” branch:
$ got send -b master origin
If the remote repository requires the HTTPS protocol, the git-push(1) command must be used instead:
When making contributions to projects which use the “pull request” workflow, SSH protocol repository access needs to be set up first. Once an account has been created on a Git hosting site it should be possible to upload a public SSH key for repository access authentication.
The “pull request” workflow will usually involve two remote repositories. In the real-life example below, the “origin” repository was forked from the “upstream” repository by using the Git hosting site's web interface. The got.conf(5) file in the local repository describes both remote repositories:
# Jelmers's repository, which accepts pull requests
remote "upstream" {
server [email protected]
protocol ssh
repository "/jelmer/dulwich"
branch { "master" }
}
# Stefan's fork, used as the default remote repository
remote "origin" {
server [email protected]
protocol ssh
repository "/stspdotname/dulwich"
branch { "master" }
}
With this configuration, Stefan can create commits on “refs/heads/master” and send them to the “origin” repository by running:
$ got send -b master origin
The changes can now be proposed to Jelmer by opening a pull request via the Git hosting site's web interface. If Jelmer requests further changes to be made, additional commits can be created on the “master” branch and be added to the pull request by running got send again.
If Jelmer prefers additional commits to be “squashed” then the following commands can be used to achieve this:
$ got update -c origin/master
$ got send -f -b master origin
In addition to reviewing the pull request in the web user interface, Jelmer can fetch the pull request's branch into his local repository and create a local branch which contains the proposed changes:
$ got fetch -R refs/pull/1046/head origin
$ got branch -c refs/remotes/origin/pull/1046/head pr1046
Once Jelmer has accepted the pull request, Stefan can fetch the merged changes, and possibly several other new changes, by running:
The merged changes will now be visible under the reference “refs/remotes/upstream/master”. The local “master” branch can now be rebased on top of the latest changes from upstream:
$ got update -b upstream/master
As an alternative to got rebase, branches can be merged with got merge:
$ got merge upstream/master
The question of whether to rebase or merge branches is philosophical. When in doubt, refer to the software project's policies set by project maintainers.
As a final step, the forked repository's copy of the master branch needs to be kept in sync by sending the new changes there:
$ got send -f -b master origin
If multiple pull requests need to be managed in parallel, a separate branch must be created for each pull request with got branch. Each such branch can then be used as above, in place of “refs/heads/master”. Changes for any accepted pull requests will still appear under “refs/remotes/upstream/master,” regardless of which branch was used in the forked repository to create a pull request.