Git workflow for small teams and single repository

This is meant to be a simple guideline for a team of 4 or 5 working on a single git repository.  This will not cover anything more complicated such as forking a project and submitting pull requests for a specific bug. This process, in my opinion, is best for internal teams working on the same projects.


The basic steps to managing the a single git repository, is by:

  1. Assign a delivery lead
  2. Delivery lead creates 3 branches when initialising a repository: dev (development), qa, master
  3. Each team member creates their own branch (including the delivery lead, if they are also a developer)
  4. Team members only work on their branch
  5. Multiple commits should be squashed into one (git rebase -i)
  6. The squashed commit should then be push to the team members remote branch
  7. The delivery lead must then merge their changes into the dev branch for testing with other developers code
  8. Once all changes are tested and working in dev, then the delivery lead will merge the changes into qa for formal testing
  9. Once testing is passed in qa then the delivery lead will merge into qa into a version branch  with a tag to signify version in commits (git checkout -b v1.0.0 && git merge qa && git tag v1.0.0)
  10. The version branch will then be merge into master

Delivery Lead

The project must begin by deciding a git repository manager or a delivery lead (DL). This person will be responsible for everything to do with the git repository. The DL will create all the necessary branches and tags to signify a release major or minor. The DL at a minimum needs to have reasonable experience dealing with git related issues. They don’t have to be an expert, but they must be able to navigate git commands easily.

The DL must then begin with creating an initial repository with at minimum, a README file for the repository. Once the README file is created, use the following to create the necessary branches:

git add .
git commit -m "init commit"
git checkout -b dev
git checkout -b qa
git remote add origin [URL]
git push -u origin --all

These commands will create three branches: dev, qa, and master. The dev branch will have the latest code from all of the developers. This branch will be used for internal testing among the team, with their own own. The dev branch will be merged into qa, when dev has stabilised. The qa branch will be used to formally test all the code features. Managing the master branch will be explained a little down the page.

Team Members

Every team member must have their own branch and they must only work within their branch. No team member is allowed to touch any other branch. Only the delivery lead can do that.

Team members must keep their branch up-to-date with dev branch, either by rebasing or merging. They can use the following commands from within their branch:

git rebase dev OR git merge dev

Rebase will try to pull all of the dev branch’s commits and push the current branch’s commits on top of them.

Merge will try to pull all the dev branch’s commits and mix the current branch’s commits with them.

When a conflict is encountered with a rebase, the developer must resolve the conflicts and use the following command to continue:

git rebase --continue

When a conflict is encountered with a merge, the developer must resolve the conflicts and commit those changes.

This is the reason rebase is preferred over merge. A conflict in a merge will add another commit to the branch’s commit history. The team needs to avoid polluting the commit history with unnecessary commits.

If a developer does have multiple commit they should not push those commits to their remote branch. The developer should do an interactive rebase to squash those commits into one.

git rebase --interactive

An editor will appear with all of the current commits and instructions at the bottom about what all of the keywords at the beginning of the commits mean.

Only one commit should have the pick keyword in front of a commit, ideally the commit at the top. The rest of the commits should an s or the squash keyword. This will tell the rebase command to take all the changes from the commits marked as squash and merge them into one commit marked as pick.

As a rule of thumb the developer should only make a single commit per issue. If there are multiple commits for any reason, an interactive rebase should be used.

Overall Git Workflow

Once the DL has created the dev, qa, and master branches, each developer on the team should create their own branch with their name or username.

Each developer will commit changes to their branch. Make multiple commits locally, then do an interactive rebase. All developers should keep their branch up-to-date with dev. So developers should either rebase or merge their branch with dev prior to pushing code. Once their remote branch is updated, they will notify the DL that changes are ready to be merged into dev. Each developer should only push changes that are in working condition, and don’t break any working code from other developers.

The DL takes the changes from the developers and merges them into dev. Then the developers should be notified to get the latest code from dev and test that the project is still functional.

Once all of the features, in a particular release, are merged into dev, the DL merges dev into qa for formal testing of all of the features. If rejected, the process starts again until reaches qa and gets accepted. If accepted, the DL creates a version branch. This branch will be same as the version number of the release. For example, for version 0.8.1 the DL would create a branch like so:

git checkout -b v0.8.1

The DL would then tag the last commit with the same version number as the branch that they just created:

git tag v0.8.1

The DL will then push this two changes to the remote repository:

git push -u origin heads/v0.8.1
git push --tags

The DL will then merge the version branch with the master branch.

This cycle would repeat for each release.


This is just the initial draft of a small process to manage git repositories with a small team. There is definitely room for improvement.

This process is still evolving and will continue to evolve, as it does I will continue to update this post.