Version: June 8, 2016 Authors: Alexander Reeder, Daniel Schlaepfer
We use the 'Github flow' (a 'feature branch workflow') as the basis for our projects. Suggestions and improvements are welcome. The workflow description is based on terminal/console 'git' commands; the GUI program 'GitHub Desktop' for Mac OSX and Microsoft Windows allows for visually friendly handling of pull requests, merges, commits, branches, and diffs, but lacks some advanced features (e.g., management of sub-modules).
-
The 4 levels of the git organization
- Working directory (on local computer): work in text editor and/or RStudio
- Staging area: include/save changes to the next commit
- Local repository: commit to project history
- Remote repository on github.com: share code with collaborators and backup local branches
-
There are two types of branches: the master branch and development/feature branches. Any commit on the master branch is deployable and has a unique version number. Deployable for us means that commits are tested. Such commits are usually the result of merging/rebasing with a development branch. The previous de facto master branches 'Rsoilwat_v31' and 'wrapper_sw31' have been merged with the true master branches.
-
Testing involves at least that each line of code was executed and did not throw an error or stopped execution unexpectedly. However, writing re-usable unit test cases (for R code based on the package testthat) is the preferred way to test our code.
-
Documentation: Comment the code well and write object documentation with roxygen, if using R, or with doxygen, if using another programming language.
-
We use semantic versioning using the format MAJOR.MINOR.PATCH. Every commit to the master branch updates the version number. A backwards-incompatible commit increases MAJOR and resets MINOR and PATCH to 0. A backwards-compatible commit adding new functionality increases MINOR and resets PATCH to 0. A backward-compatible commit fixing bugs (etc) increases PATCH.
-
Inspecting a repository
- State of working directory and staging area: git status
- History of commits:
git log --graph --full-history --oneline --decorate
- List of branches (* indicates the active branch):
- Local branches:
git branch
- Remote branches:
git branch -r
- List of remote connections:
git remote -v
-
Error reporting: If you come across a bug in our code, please do something about it.
- You can report it as a new issue, e.g., here for Rsoilwat, and communicate with the person who committed the buggy code.
- If you can fix the problem yourself, then can create a new branch, improve the code, test the code and check that the changes did not break anything, and create a pull request (the commit message can automatically close the issue number(s); see workflow below).
-
Set global user options to identify your commits
git config --global user.name <name>
git config --global user.email <email>
git config --global core.editor <editor>
# e.g., vi, emacs, nano, TextWrangler (Microsoft Windows user refer to First-Time-Git-Setup)
-
Create a new (development) branch each time you start to develop new functionality or work on improving code. Use descriptive branch names (e.g., new-snowmelt)
- Get a copy of a remote repository to your local computer:
git clone https://github.com/Burke-Lauenroth-Lab/SOILWAT.git
git clone https://github.com/Burke-Lauenroth-Lab/SoilWat_R_Wrapper.git
- Get a copy of a specific branch:
git clone -b segfault1 https://github.com/Burke-Lauenroth-Lab/SOILWAT.git
- If the repository contains sub-modules:
git clone --single-branch --recursive https://github.com/Burke-Lauenroth-Lab/Rsoilwat.git Rsoilwat_v31
- Make a new branch:
git branch <branch>
- Change into a branch:
git checkout <branch>
- Push/export local to remote/upstream:
git push origin <branch>
- Get a copy of a remote repository to your local computer:
-
Work on code
- Stage your changes in a snapshot:
git add <file>
orgit add <directory>
orgit add -p
- Navigation
- Between branches:
git checkout <branch>
- Between commits:
git checkout <commit>
# HEAD points to in a 'detached HEAD' state (i.e., view but do not edit!)
- Between branches:
- Remove commits from current (private, i.e., not published on remote repository) state of a branch (i.e., re-writing history)
- From working directory, staged snapshot, and commit history:
git reset --hard HEAD
- From staged snapshot and commit history:
git reset --mixed HEAD
- From commit history:
git reset --soft HEAD
- From working directory, staged snapshot, and commit history:
- Remove commits from current published branch (by creating a new commit, i.e., it does not re-write history):
git revert HEAD
- Interruptions to coding
- Pulling into a dirty tree (i.e., git pull cannot merge):
git stash
thengit pull
andgit stash pop
- Interrupted workflow:
git stash
; work on interruption and commit;git stash pop
- Pulling into a dirty tree (i.e., git pull cannot merge):
- Stage your changes in a snapshot:
-
Commit to your development branch regularly and use explanatory commit messages in order to create a transparent work history (e.g., to help with debugging; to find specific changes at a later time). Each commit is a separate logical unit of change and is therefore composed of related changes.
- Check state of staging area:
git status
- Commit/save to project history:
- Commit staged snapshot:
git commit -m "<message>"
# where contains the commit description on the first line (< 50 characters), a blank line, and a detailed description (include keywords to close/fix/resolve issues, e.g., closes #45 will close issue #45 in the repository)
- Commit staged snapshot:
- Invoke a text editor to compose :
git commit
- Commit all changes:
git commit -am "<message>"
- Check state of staging area:
-
Share and backup your development commits on the remote repository. Our standard method for publishing local contributions to the github.com repository: 0. Make sure you are on the development branch:
git checkout <branch>
- Make local commit(s) to the development branch (see previous step)
- Import/merge new commits from remote/upstream to local repository branch:
git pull origin <branch>
- Push/export local project history to remote/upstream:
git push origin <branch>
Text tools, e.g., Winmerge/Textwrangler, compare two files (versions of the same file) and offer the possibility to take over changes from either version to the other version. Such functionality can be very helpful to resolve conflicts during merging.
-
Repeat steps 3-5 until the development branch is ready for deployment. Open a pull request and ask for feedback from the team members. It usually does not hurt if someone else than the developer does a test on a feature, since another person may test differently.
-
If necessary, repeat steps 3-5 to complete review of the pull request, e.g. to deal with issues and fix bugs.
-
After a team member has reviewed the development branch, you should deploy the development branch and merge/rebase to the master. Our standard method with two options for deploying a development/feature branch to the master branch on github.com repository (option (i) with rebasing is ideal for small development branches; option (ii) with merging is preferred for large development branches): 0. Make sure you are on the development branch:
git checkout <branch>
-
Create an annotated version tag using semantic versioning with a format like v1.0.4:
git tag -a v1.0.4 -m "<message>"
-
If the repository is a R package, then adjust the lines 'Version' and 'Date' of the file DESCRIPTION to reflect the new version and potentially adjust package startup message in function '.onAttach' of the file R/zzz.R
-
Option (i): Rebase development branch onto the tip of the master branch (given that there are no branches on ):
git rebase master
-
Options (i) and (ii): Integrate with the main code base:
git checkout master
git merge <branch>
-
Inspect outcome of merge (e.g., resolution of potential merge conflicts), commit and push the merge to remote/upstream with a detailed particularly when using option (ii)
git commit -a
git push origin --tags
-
Add a new release against master based on the version tag
-
Delete the development branch:
git branch -d <branch>
-