User Tools

Site Tools


dev:git

Git

Evergreen uses Git as its primary version control system for both code and documentation. A number of repositories of interest to Evergreen, including the main public repositories for Evergreen, Evergreen's documentation, and OpenSRF, are maintained on the community Git server.

Using Git

Getting commit access to working repositories

Evergreen contributors are encouraged to publish branches containing their contributions to the OpenSRF and Evergreen “working” repositories. We maintain git repositories for this purpose; we simply need to add your SSH public key to the working repository to give you permission to publish branches.

  1. If you do not have an SSH key, you can generate one as follows:
    bash$ ssh-keygen 
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/username/.ssh/id_rsa): 
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again:
  2. Email your public key to the Evergreen git administrators at gitadmin@evergreen-ils.org and request permission to commit to the OpenSRF and Evergreen “working” repositories. NOTE: in the preceding example, your public SSH key would be found at /home/username/.ssh/id_rsa.pub - DO NOT send id_rsa!

Configuring SSH

If the SSH key you use for this Git repo isn't located at: ~/.ssh/id_rsa then you will need the following configuration file in ~/.ssh/config:

  Host EvergreenGitServer
    Hostname=git.evergreen-ils.org
    IdentityFile=<LOCATION OF YOUR SSH KEY>

Then use the name EvergreenGitServer instead of the host in commands, for instance:

git remote add name git@EvergreenGitServer:evergreen/user_foo.git

Quick start for Evergreen contributors

  git clone git://git.evergreen-ils.org/Evergreen.git
  cd Evergreen
 
  # Add the "working" remote to pull from working branches
  git remote add working git://git.evergreen-ils.org/working/Evergreen.git
  # Have the ability to push to the working repo if you send in your SSH key
  git remote set-url --push working git@git.evergreen-ils.org:working/Evergreen.git
 
  # Fetch all of the branches and updates from all remotes
  # Probably a good idea to do this every time you start another working session
  git fetch --all
 
  # Set your email and user name
  git config user.email user@hostname
  git config user.name "Firstname Lastname"
 
  git checkout -b working_branch origin/master
  # hack away
  git commit -as # and enter a useful comment

If you have sent your SSH pubkey to gitadmin@evergreen-ils.org and have commit privileges to the working repository, please publish the branch containing your changes:

  git push working working_branch:user/<username>/working_branch
  # then add 'pullrequest' to the tags for the Launchpad bug

Alternately, to create one or more patch files containing your changes:

  git format-patch origin
  # attach patch file(s) to Launchpad bug

Git resources

Guidelines for contributors

Commit messages

A commit message should consist of a subject line (i.e., the first line of the commit message), then a blank line, then an optional description of the patch, followed by one or more signoffs. The subject line should be brief, ideally no more than 60-70 characters, and should include a bug number from LaunchPad if relevant. Here is an example of a minimum commit message:

LP#24544: fix the quuxifier

Signed-off-by: Jane Hacker <jhacker@example.org>

Of course, sometimes a patch requires more description and review:

LP#542: extend the foobar subsystem

Add support for the thingmajigger interface provided
by the Baz module.  Adds the following OU settings:
  circ.foobar.baz
and the following permissions 
  VIEW_FOOBAR
  UPDATE_FOOBAR
  DELETE_FOOBAR

Signed-off-by: Jane Hacker <jhacker@example.org>
Signed-off-by: Roger Reviewer <roger@example.com>
Signed-off-by: Chris Committer <chris@example.net>

Sign-offs

For the Evergreen and OpenSRF projects, all patches must be signed off by the author. The author sign-off signifies that the author is permitted to submit the patch and is equivalent to signing a DCO (Developer's Certificate of Origin). More information on the DCO is included in the main contributing page.

An author sign-off can have a secondary meaning: that the author has tested the patch and believes it to be of sufficient quality to contribute to Evergreen. All contributors are encouraged to enlist other people to review their patches, and a sign-off by somebody other than the author signifies that the patch has been reviewed.

A sign-off takes the form of the following text in the commit message for a patch:

Signed-off-by: Jane Hacker <jhacker@example.org>

Signing off on one or more commits

The easiest way to sign-off on one or more commits is to:

  1. Create a new branch based on current master (or, if backporting a fix to a previous release, from the appropriate release branch)
  2. Cherry-pick the commits using the -s flag
  3. Test to ensure that everything still works
  4. Then push that branch to the working repository

To get a list of commits of interest for a given branch, you can use git log to display the commit log for any branch in any remote that you have synchronized. For example, to get a commit log for someone else's branch user/danger/add_dangerous_stuff in the working remote that you're interested in testing out:

git log working/user/danger/add_dangerous_stuff

We typically create branches for review that have the pertinent commits at the tip of the branch - that is, the most recent commits. However, if a long-lived branch has merged changes from master over time, you might need to use a tool like tig to view the changes.

For example, to sign-off on two commits with hashes matching d28dfa2 and a30de02 using a local branch name of openurl-more and push them to a remote branch in the working repo named user/myname/openurl-signoff:

# Ensure you have the latest revision of master
$ git fetch --all
$ git checkout -b openurl-more origin/master
# or if the intention is to backport to the rel_2_1 release:
# git checkout -b openurl-more_rel_2_1 origin/rel_2_1
$ git cherry-pick -s d28dfa2
$ git cherry-pick -s a30de02
# Test
# Test some more
# Test some more
$ git push working openurl-more:user/myname/openurl-signoff

Evergreen.git and OpenSRF.git

The following conventions apply to both Evergreen and OpenSRF. For the sake of concision, only Evergreen will be named in the forgoing.

Branches

The tip of Evergreen development is master, while branches that start with rel_ are maintenance branches for release series. Branches that start with tags/ are legacies of Evergreen's previous Subversion repository, and should not be confused with Git tags.

Community Git Repository

http://git.evergreen-ils.org is the main community repository and is used for the following:

  • the main Evergreen, Evergreen documentation, and OpenSRF repositories
  • Evergreen and OpenSRF contribs
  • Working trees of any of the above maintained by individuals and organizations
  • Mirrors of Git repos of dependencies used by Evergreen or OpenSRF
  • Working trees of related projects, e.g., OpenNCIP.

Any individual or group who wishes to have a repository hosted on the community Git server can request one. All repositories must meet the following conditions:

  • They must be relevant to the Evergreen project.
  • They may only contain free and open source software or, in the case of documentation, images, and other non-software artifacts, must be licensed under an appropriate open license such as CC-BY-SA or CC0.

To request a new repository, please email the open-ils-dev mailing list.

Working Repos

Working repos are intended for use by individual developers.

Any developer that has submitted their public key can push to user or collab branches on a working repo.

User branches start with user/USER/ where USER is the developer's username, as known by the git server. Only the user who created the branch can push to it.

Collab branches, on the other hand, start with collab/USER/ where USER is the initial developer's username, as known by the git server. Only the user who created the branch can non-ff push or delete it, but anyone can push to it otherwise.

In some cases the username is simple, in others it is an email address. If you do not know your username you can ask one of the git administrators, and they will be glad to inform you.

To track these repositories, you might do the following:

# with ssh keys, to push branches to the working repos
git remote add working git@git.evergreen-ils.org:working/Evergreen.git
git remote add working_srf git@git.evergreen-ils.org:working/OpenSRF.git
git remote add working_sip git@git.evergreen-ils.org:working/SIPServer.git
 
# or without ssh keys, if you just want to send patches
git remote add working git://git.evergreen-ils.org/working/Evergreen.git
git remote add working_srf git://git.evergreen-ils.org/working/OpenSRF.git
git remote add working_sip git://git.evergreen-ils.org/working/SIPServer.git
 
# then, in both cases, to make git aware of the remote branches
git fetch working

Examples, assuming the working repo is set up as “working” as above and dealing with git user “mrgit”:

To push “myfeature” as a user branch:

git push working myfeature:user/mrgit/myfeature

To push “myfeature” as a collab branch:

git push working myfeature:collab/mrgit/myfeature

To checkout a local copy of a user branch:

git checkout -b theirfeature working/user/mrgit/myfeature

To checkout a local copy of a collab branch:

git checkout -b theirfeature working/collab/mrgit/myfeature

To merge from a user branch:

git merge working/user/mrgit/myfeature

To merge from a collab branch:

git merge working/collab/mrgit/myfeature

To delete a user branch:

git push working :user/mrgit/myfeature

To delete a collab branch:

git push working :collab/mrgit/myfeature

Adding a Sign-off to a new feature in a Collab branch

Note: Assumes developer has submitted their public key to the Git administrators

Add a branch entitled “working”

git remote add working git@git.evergreen-ils.org:working/Evergreen.git

Note: If you've already done this before, you'll get “fatal: remote working already exists.” – Just ignore it.

Make git aware of the remote branch(es)

git fetch working

Make sure we're up to date

git pull

Checkout the feature (“myfeature”) we'll be signing off on, locally

git checkout -b myfeature working/collab/someuser/myfeature

Amend the commit message, to add our signoff

git commit --amend -s

Push our signoff back to a new branch

git push working penalty_null_display:user/mrgit/myfeature

Git administrators

To request a repository, please email gitadmin@evergreen-ils.org.

The people who currently have access to maintain the Git server and create new repositories (and who listen to the gitadmin@evergreen-ils.org address) are:

  • Galen Charlton
  • Thomas Berezansky

Helpful Scripts

Git supports creating custom commands by adding scripts to your path. These scripts take the name git-command and are then run as git command [<args>].

We have some potentially helpful ones here. They can all be installed in, for example, /usr/local/bin (or anywhere else in your path).

Git URL

This script provides an easy way to share “how to use this branch” information with others. It defaults to the currently checked out branch, but can take any branch name as an argument.

Example:

# git url origin/master
For sharing origin/master via the remote repo origin:

Change remote_name as appropriate in the below commands.

You need only add the remote once, regardless of how many branches you wish to look at.
To add this repo as remote_name:
 Read-only (git protocol):
  git remote add remote_name git://git.evergreen-ils.org/Evergreen.git
 Read-write (ssh protocol):
  git remote add remote_name git@git.evergreen-ils.org:Evergreen.git

Once you have the remote added you can check out this branch:
git checkout -b master remote_name/master
git-url
#!/bin/bash
 
# Target Branch
# Defaults to HEAD
giturltarget=${1:-HEAD}
giturlreference="the current branch"
if [ "$giturltarget" != "HEAD" ]; then
    giturlreference=$giturltarget
fi
 
# Current rev:
giturlcurrev=`git rev-list --max-count=1 $giturltarget`
# Find all remote branches that have the current rev as their tip
for giturlremote in `git remote`
do
    giturlhasrev=`git ls-remote $giturlremote | grep "$giturlcurrev.*refs/heads/" | sed 's|.*refs/heads/||'`
    if [ "$giturlhasrev" ]; then
        echo "For sharing $giturlreference via the remote repo $giturlremote:"
        echo ""
        giturlremoteurl=`git config -l | grep ${giturlremote}.url | cut -f2 -d= | sed 's/\\([^@]*@\\|[^:]*:\\/\\/\\)\\([^:\\/]*\\)[:\\/]\\(.*\\)/\\2:\\3/'`
        if [ "$giturlremote" == "origin" ]; then
            giturlremote=remote_name
            echo "Change remote_name as appropriate in the below commands."
            echo ""
        fi
        echo "You need only add the remote once, regardless of how many branches you wish to look at."
        echo "To add this repo as $giturlremote:"
        echo " Read-only (git protocol):"
        echo "  git remote add $giturlremote git://`echo $giturlremoteurl | sed 's/:/\\//'`"
        echo " Read-write (ssh protocol):"
        echo "  git remote add $giturlremote git@$giturlremoteurl"
        echo ""
        echo "Once you have the remote added you can check out this branch:"
        giturlshowor=
        for giturlbranch in $giturlhasrev
        do
            if [ "$giturlshowor" ]; then
                echo "or"
            fi
            giturlshortbranch=`echo $giturlbranch | sed 's|.*/||'`
            echo "git checkout -b $giturlshortbranch $giturlremote/$giturlbranch"
            giturlshowor=yes
        done
        echo ""
    fi
done

Git pushworking/pushcollab

These two scripts are designed to make it easier to push branches to the “working” repos. They do require some configuration:

  1. Add the working repo with SSH
  2. Set the name of the working repo: git config openils.gitpushworkingrepo <repo name> (ex: git config openils.gitpushworkingrepo working-eg) - If you named the repo “working” you can skip this step
  3. Set your git username (for the server, not locally): git config openils.gitpushworkinguser <user name> (ex: git config openils.gitpushworkinguser mrgit)

Once you have done the above you can use the commands:

# git pushworking localbranch - Will push "localbranch" to "user/<user name>/localbranch"
# git pushcollab localbranch - Will push "localbranch" to "collab/<user name>/localbranch"

# git pushworking localbranch:remotebranch - Will push "localbranch" to "user/<user name>/remotebranch"
# git pushcollab localbranch:remotebranch - Will push "localbranch" to "collab/<user name>/remotebranch"

Note that you can use a space instead of a colon in the previous two

# git pushworking +localbranch - Will *force* push "localbranch" to "user/<user name>/localbranch"
# git pushcollab +localbranch - Will *force* push "localbranch" to "collab/<user name>/localbranch"

The + modifier works in all forms of the command when put in front of localbranch to trigger a force push.
git-pushworking
#!/bin/bash
gitpushworkinguser=`git config openils.pushworkinguser`
gitpushworkingrepo=`git config openils.pushworkingrepo || echo working`
if [ "$gitpushworkinguser" == "" ]; then
    echo "ERROR: Username not filled in";
    echo "Try git config openils.pushworkinguser username";
    exit 2;
fi
if [ -z "$1" ]; then
    echo "Usage: git pushworking <branch> [<remotebranch>]";
    exit 1;
fi
gitpushworkinglocalbranch=${1%%:*}
gitpushworkingremotebranch=${2-${1#+}}
git push $gitpushworkingrepo $gitpushworkinglocalbranch:user/$gitpushworkinguser/${gitpushworkingremotebranch##*:}
git-pushcollab
#!/bin/bash
gitpushworkinguser=`git config openils.pushworkinguser`
gitpushworkingrepo=`git config openils.pushworkingrepo || echo working`
if [ "$gitpushworkinguser" == "" ]; then
    echo "ERROR: Username not filled in";
    echo "Try git config openils.pushworkinguser username";
    exit 2;
fi
if [ -z "$1" ]; then
    echo "Usage: git pushcollab <branch> [<remotebranch>]";
    exit 1;
fi
gitpushworkinglocalbranch=${1%%:*}
gitpushworkingremotebranch=${2-${1#+}}
git push $gitpushworkingrepo $gitpushworkinglocalbranch:collab/$gitpushworkinguser/${gitpushworkingremotebranch##*:}
dev/git.txt · Last modified: 2013/02/27 12:17 by paxed

© 2008-2014 GPLS and others. Evergreen is open source software, freely licensed under GNU GPLv2 or later.
The Evergreen Project is a member of Software Freedom Conservancy.