Skip to content

Code Review Workflow

Jason Mobarak edited this page Aug 1, 2013 · 3 revisions

This page describes a workflow for code review, through github pull requests, but that still allows for a linear commit history.

Super simple overview for cozybit devs (TL;DR)

In general, we want to use the github "pull request" workflow, with a couple (very important, modifications) to keep the commit history as linear as possible.

For authors

  1. Don't use a fork, use a branch of the main repo
  2. Create a branch of each blob of work to be reviewed (format: <AUTHOR>-<DATE>-<FEATURE>)
  3. Try to rebase before submitting the pull request on the GitHub website
  4. Push changes to remote prior to issuing pull request
  5. Use git pr to issue the pull request (install instructions)

For reviewers

  1. Don't click the 'merge' button on GitHub!
  2. Use the manual instructions quoted on GitHub to pull down and merge code
  3. Try to always run tests before pushing the merge back to GitHub
  4. Try to use --ff-only (fast-forward) for git merge

(NB: you may need to git rebase master, then git push -f origin <branch> prior to git checkout master; git merge <branch> in order to update the remote branch in the pull request, this allows GitHub to correctly detect that the branch was rebased and merged.)

Install the tools

Install the tools from here:

$ git clone https://github.com/silverjam/cozyreview
$ cd cozyreview
$ ./install.sh

Then you can:

  • Issue a pull request with git pr
  • Start a review with git review

Manually issuing a pull-request

Use 'hub' to issue a pull-request

To avoid having to use the website to issue a pull request you can use the hub tool.

$ git clone git://github.com/github/hub.git
$ cd hub
$ rake install prefix=/usr/local

Make changes, issue pull request

git commit
git push origin my-feature-branch
hub pull-request -b <github_org>:<base_branch> -h <github_org>:<branch_to_be_pulled>

Where:

  • github_org = cozybit
  • base_branch = master
  • branch_to_be_pulled = my-feature-branch

Easy git aliases

You can also add an alias to make your life easier, add the following aliases to ~/.gitconfig:

[alias]
    cbr = rev-parse --abbrev-ref HEAD                                           
    pr = "!f() { git prb master; }; f"                                          
    prb = "!f() { patch=`tempfile --suffix=.mkd` ; echo 'PULL-REQUEST-TITLE' >>$patch ; echo >>$patch; echo '```' >>$patch ; git format-patch --stdout $1 >>$patch ; echo '```' >>$patch ; [ -z \"$EDITOR\" ] && EDITOR=vi ; $EDITOR $patch ; cbr=$(git cbr) ; hub pull-request -F $patch -b cozybit:$1 -h cozybit:$cbr ; rm -f $patch ; } ; f"

This allows you to do the following: git checkout master git checkout -b my-feature # ... make changes git commit # ... make changes git commit git push origin my-feature git pr

Commands added:

  • git pr: issue pull request for feature branches based on master
  • git prb: issue pull request, but based on a branch other than master (usage: git prb other-branch)

Viewing pull-requests as git branches

If you want to see pull-requests as branches in git (without needing hub) you can do something like:

git config --add remote.origin.fetch "+refs/pull/*/head:refs/remotes/origin/pull-request/*"
git remote update

And now you will have remote branches from origin named like:

origin/pull-request/<pull-request-num>

This leaves your .git/config with two "fetch" keys for [remote "origin"] .. like this:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = [email protected]:cozybit/distro11s.git
    fetch = +refs/pull/*/head:refs/remotes/origin/pull-request/*

Idea found here: https://gist.github.com/piscisaureus/3342247

You can add an alias to accomplish this too (git config --global --edit):

[alias]
    apr = "config --add remote.origin.fetch \"+refs/pull/*/head:refs/remotes/origin/pull-request/*\""

Code author workflow (using a local clone):

(1) Create a local clone + feature branch:

Create local branch to work in, push to remote for reviewers to pull from. This branch should remain unchanged until it is merged upstream once the submitter has sent a pull request:

git clone [email protected]:cozybit/android-proximity-networking.git
cd android-proximity-networking
git checkout -b jlopex-featurex

Push the branch for reviewers to fetch:

git push origin jlopex-featurex

(2) Work on feature

 git commit ...
 git commit ...
 git commit ...

(3) Fetch upstream

git checkout master
git pull origin master

(4) Prepare 'jlopex-featurex' for review

git checkout jlopex-featurex
git rebase --interactive master

(5.1) Send feature for review using request-pull

git push origin jlopex-featurex
git request-pull origin/master origin jlopex-featurex | mailclient reviewers@project

(5.2) Or... use GitHub "pull request"

  • Select the new branch on GitHub
  • Click on the pull request tab
  • Send a pull request from the feature branch to master

Workflow: Code author using GitHub fork

{{ Note: this is not the recommended workflow, since it involves the added complexity of a github fork, people with direct push access to the "upstream" repo should not use a fork. }}

This illustrates the workflow needed for a code author using a fork. This is more complicated because the author must track and pull in changes from the upstream repo.

(1) Fork the repo

github fork git://project-upstream project-my-remote-fork
git clone git://project-my-remote-fork project-my-fork

(2) Add a remote to track upstream

cd project-my-fork
git remote add upstream git://project-upstream

(3) Create a branch for the pull request / feature

git checkout -b myfeature

(4) Working on feature

 git commit ...
 git commit ...
 git commit ...

(5) Update upstream

 git fetch upstream/master

(6) To update local master from upstream

 git checkout master
 git merge upstream/master

Then push to remote

git push origin master

Prepare 'myfeature' for submission

git checkout myfeature
git rebase --interactive master # or: git rebase --interactive upstream/master

git push origin myfeature
git request pull upstream/master git://project-my-remote-fork | mailclient reviewers@project-upstream

Code reviewer workflow

(1) Fetch the branch

git clone [email protected]:cozybit/android-proximity-networking.git
cd android-proximity-networking
git pull origin jlopex-featurex

(2) Merge the feature

git checkout jlopex-featurex
git rebase --interactive master
git checkout master
git merge jlopex-featurex

Review the changes... test... etc...

(3) Push to origin master

git push origin master

(4) Delete feature branch

After the review + merge + push, the feature branch is not needed anymore:

git push origin :jlopex-featurex  # delete remote branch
git branch -d jlopex-featurex     # delete local branch