Wiki

Clone wiki

gkw / Git_Bitbucket

Getting started with Git

Git is a distributed version control system, and is very powerful and flexible. It means you can commit as much as you like, on your local machine, without worrying about everyone else. Branching and merging are easy. When you're ready, you can share your changes via Bitbucket.

If you're used to SVN (a centralised version control system), learning git will require a bit of re-education, because things are a bit different.

Quickstart

Get GKW: Anyone can clone the repository. Those with developer permissions should make their clone using the email address and password of their bitbucket account, to allow them to push changes. If you created your bitbucket account with a third party login (e.g. a google account), you will first need to set a bitbucket specific password - which is the one you will use for accessing the repository. You can also upload a public ssh key.

git config --global user.name "Your Full Name"
git config --global user.email your_address_used_at_bitbucket@foobar.com
# download the gkw repository (enter your bitbucket password). 
git clone git@bitbucket.org:gkw/gkw.git gkw_git
# if ssh access as above fails, try http instead (username optional)
git clone https://username@bitbucket.org/gkw/gkw.git gkw_git

# make a few more reasonable settings (explained in git notes below)
cd gkw_git
# push current branch by default (not in older git clients)
git config --global push.default simple  
# rebase on pull by default (svn update like behaviour)
git config --global pull.rebase preserve

# For developers, track the develop branch 
git branch --track develop origin/develop
# then check it out
git checkout develop
🍎 For git testing purposes you are encouraged to clone gkw-sandbox where everyone is invited to try out things and make a mess.
git clone git@bitbucket.org:gkw/gkw-sandbox.git
After you made some changes, then
# look at your changes
git diff
# add all changes to your local index (so-called staging the commit)
git add -u .
# create a commit locally
git commit
# locally, you can do as many commits as you want.

# when you're ready, send your changes to bitbucket (e.g. like svn commit)
git push origin develop
# arguments optional if you set git config push.default simple

Get changes from others (like svn update)

git pull --rebase
# argument optional if you set git config pull.rebase preserve

Unlike svn, branches are not folders but rather like a pointer, and are all stored internally to git (git itself is a filesystem on top of the normal one). With git, you only ever need one set of gkw folders in your usual filesystem. To switch between branches, use git checkout. To list branches, and see which one you are on, use git branch/

Do

  • Use git status, often (after almost every other git command), gives you helpful advice
  • Ask for help
  • Clone the repository to your machine
  • Set the recommended config switches in the quickstart above.
  • Branch and experiment locally. To experiment with git you can also make multiple repository clones or clone the gkw-sandbox repository.
  • Commit little and often
  • Write nice commit messages with a single summary line followed by a empty line, then everything else
  • Push to bitbucket when you're ready
  • Install and use a git gui like git-gui or gitg or gitk - it will help you explore and get a feel for git (particularly staging and branches)
  • In the commit message, link to related issues with the notation refs issue #3

Don't

  • NEVER force a push (if git won't let you push, it means something is wrong)
  • NEVER rebase already published commits, like a branch that you've pushed to or that you've pulled from Bitbucket (rebase re-writes history, which is fine, but only to clean up your private, not-yet-pushed history)
  • Delete the master or develop branches
  • Delete other remote branches (unless they are yours)
  • Push without first running the test cases (but you can commit (which is local) as much as you like!)
  • Commit large (>512kB) files, e.g. large images, binaries, or tarballs. If pushed, they will increase the size of the cloned repository for everyone, forever !
  • Try to switch branches with uncommitted changes - a "dirty" working directory (use git stash instead)

GKW development workflow

Git Branching Model for GKW development

We are testing a new branching model for GKW development, please read the article for full details, and see the discussion.

In this model there are two perpetual public branches of GKW:

  • master: points to a recent, stable, and well tested version of the code, recommended for users.
  • develop: latest working version, where all new work is merged, prior to becoming master. Must pass test cases.

Developers can make changes directly to develop, but for any major changes, a new branch from develop is encouraged. No changes should be made directly in master (see Release Procedure).

a-git-branching-model-simplified.png

Branch conventions

This model implies a few rules for how branches are managed and named.

You can create new public branches as follows:

  • feature-x: For new features - must branch off develop, and merge back into develop
  • rewrite-x: For code clean-up - must branch off develop, and merge back into develop
  • hotfix-x: For urgent bug or config fixes to the code on the master branch - must branch off master, and be merged into both develop and master .

Special names, to avoid using for new branches:

  • develop
  • master
  • origin

Permissions

Bitbucket allows to restrict write access of certain users to certain branches.

A sketch of the current access policy: (🔨 still in discussion, we'll see how we want to handle this)

There are two user groups

  • developers working only on a particular feature
    • may commit directly to the develop branch
    • may create and write to feature-x branches, and merge them into the develop branch
    • may create and write to hotfix-x branches and create Pull Requests for it, however merges have to be done by a core person
  • core These have the same rights as developers and additionally
    • have write access to the master branch. However, as the master branch shall contain only comparatively trusted and stable versions, one could try to respect a certain procedure by convention, e.g. merges to master only via Pull Request, more careful testing (as described in tag 0.3-b2), and review by somebody else.

🔨 We are establishing a Release Procedure to follow for updates to master.

Workflow Examples

For feature branches

A workflow to maintain a linear (alternative - parallel) history on a feature branch. This section illustrates how one could develop a new feature on single branch. The example branches from the develop branch.

# start from the right place
git checkout develop
# create a local branch once
git branch feature-new
# list the branches
git branch
which is rebased (alternative - merged) every now and then with the develop branch.

The workflow loop looks approximately like this

# work on this branch
git checkout feature-new
#check which branch you are on
git branch
# ...edit, do stuff, commit all or some of your changes to your local dev branch
git add -u .
git commit
# you can make as many local commits as you would
# like, amend forgotten files, reword their messages, squash them
# together, change their order, etc. to make it easily
# understandable what they are about, using for example
#git commit --amend
#git rebase --preserve-merges -i HEAD~2

# whenever you want, pull other peoples new commits
# from bitbucket. this will fetch commits into
# origin/develop and fast-forward your develop branch
git checkout develop
git pull
#rebase is not needed, if you did not change develop

# having checked out feature-new, move your local changes in
# the feature-new branch on top of the new ones in develop
git checkout feature-new
git rebase develop 
# But, do not rebase changes if you already pushed them to bitbucket !
# instead, do git merge develop
# (you may have to resolve conflicts here...
# https://help.github.com/articles/resolving-merge-conflicts-after-a-git-rebase/ )

# You can publish the feature branch as follows (or you can keep it local)
git push -u origin feature-new
# or git push --set-upstream origin feature-new
# after the first push, you can just do git push

# when you are ready to merge to develop, fast-forward merge the develop branch
git checkout develop
git merge feature-new
# look at it
gitg & # or git gui 
# run the testcases ;-)
gkw_run_tests
# publish develop
git push origin develop

# and continue working on your development branch ...
git checkout feature-new
# or delete it (see the hotfix example)

For hotfixes

💡 To make a hotfix branch, commit to it, merge it back and get rid of the branch pointer, with lots of intermediate pushes (alternatively one could do everything locally and just push in the end):

git checkout master
git branch hotfix-issue13
# edit and commit, as many time as you need...
# TEST thoroughly, because you are going to update master !
# push to the central repo, and because its the first time this branch is pushed and it does not exist 
# there: create also a upstream tracking reference in the local repository.
git push --set-upstream origin hotfix-issue13

# merge it to master
# (If you don't have the permission, submit a pull request instead)
git checkout master
git merge --no-ff hotfix-issue13
# push the merge commit
git push

# merge it to develop
git checkout develop
git merge --no-ff hotfix-issue13
# retest, because this branch is different
# push the merge commit
git push

# delete the remote branch. This is equivalent to deleting the branch on the bitbucket web interface
git push :hotfix-issue13
# delete the local branch
git branch -d hotfix-issue13
# delete all references to not-existing remote branches
git remote prune origin

Tagging convention

Commits on the master branch, should be tagged. Tag any commit on the master branch by incrementing the minor version number. Commits on other branches may be publicly tagged using the last master tag and a suffix.

Tags should be updated to create sensible executable names (the executable name is derived from the latest tag with git describe --always --tags --dirty). Tags on master should be made following the numbering convention already started. Please annotate these tags along the lines of 0.3-b2. (See also http://semver.org/, http://stackoverflow.com/a/11660153/3357325).

Emails from Bitbucket

The gkw-updates and gkw-issues lists are no longer used.

To receive updates about changes to the repository, you need to "watch" the repository (click the eye in the top right) and configure the notifications you want in your user account.

You can also configure your bitbucket account to send you emails on just the issues you are involved with, or watch specific issues.

Other notes and Git Snippets

💡 In some situations, if there are local commits on develop and you want to pull new commits from the repository nevertheless, it can be useful to do

git pull --rebase
as this will rebase the existing local commits on top of the pulled ones (like svn update does with local changes) and maintain a linear commit history. This behaviour is the default if you have set git config pull.rebase preseve

💡 Push default: only push the current branch (not in older git clients) git config push.default simple

💡 Put some lines e.g. into your ~/.bashrc to display helpful git infos at the command line prompt, like the current branch, repo state, ...

export GIT_PS1_SHOWDIRTYSTATE=1
export GIT_PS1_SHOWSTASHSTATE=1
export GIT_PS1_SHOWUNTRACKEDFILES=1
export PS1='\[\033[1;37m\][\[\033[1;32m\]\u\[\033[0m\]@\h\[\033[0m\] $? \[\033[1;34m\]\w\[\033[0;33m\]$(__git_ps1 " %s")\[\033[1;37m\]]\[\033[0m\] '

💡 Remember that in most places where commands expect you to specify a commit, you may give a tag name instead.

# e.g. look at that master release commit
git show 0.4-b1
# e.g. look at the changes this old revision introduces
git show r2000

Updated