If you’re just starting with Git, you have probably only used Git as the sole developer working on your own repository. When working with a team, a bit more care is needed to manage simultaneous development and avoid conflicts with other team members as much as possible.

There are many “workflows” one can use with Git. The one I’ll suggest here is suggested by GitHub, and it is known as “The GitHub Flow.” This article by Scott Chacon gives even more detail and motivation for the flow.

Overall, the workflow involves 1) keeping the main branch “clean,” 2) always doing development work on separate, individual branches, and 3) using pull requests to manage the integration of that development work back into the main branch.

Branching

The main branch should only ever hold tested, complete, working code. As the GitHub flow description states, “anything in the main branch is always deployable.” Each new feature or fix or user story should be developed within its own branch, with as many commits as needed in that branch to get it right before merging it into main. With separate branches for each feature, the development can be done in parallel while minimizing edit conflicts in files.

See the “Branching” and “Merging” sections of the Git Cookbook for the most relevant Git commands for managing branches.

Pull Requests

Once the work in a development branch is complete and ready to be integrated into the main branch, you can use a pull request to manage the integration with your team. Opening a pull request will initiate the merging of the branch back into the main branch, and it allows for the following:

  1. The team can review the code, discuss the changes, suggest improvements, and add more commits as needed until they agree it is in good shape to merge.
  2. A continuous integration tool (e.g., Travis-CI or Github Actions) can automatically tell you if the resulting merge will pass your unit tests.
  3. The merge itself can be completed with a few clicks in GitHub’s web interface.

However, there are a few steps to complete before you open the pull request.

Merge First

Before opening a pull request, first merge any recent changes from the main branch back into your development branch. That is, if anything has changed in main since you first created your branch, you want those changes incorporated into your branch also. In this way, you can make sure the merge back into main will go smoothly.

To do this:

  1. First, make sure you have the latest version of everything from GitHub by running git fetch.
  2. Then, while your development branch is the active branch (remember, you can always check that using git status and/or git branch -v), run git merge origin/main. That will merge the main branch as it exists on GitHub into your currently active branch.
  3. If you end up in an interface asking you to type a message for the new merge commit, you just need to exit that program to accept the default message. The default editor in many cases is a program called Vim, which you can exit by typing :q and pressing enter.

Merge Conflicts

If the merge results in a conflict, git will warn you about this. In that case, this guide can help you resolve it. However, you do not want to run git add . in their step 7. That is likely to bring more files and changes into the commit than you want. Instead, specify individual files using git add until the “to be committed” part of git status contains everything you want to commit in the merge.

Please ask me for help if you run into this and don’t work it out quickly yourself.

Test Merged Code

Once you have successfully merged main into your development branch, test the resulting code. The merge may be successful (with no conflicts or with conflicts resolved) and still break something. So test the code and make sure everything is still working. A good suite of unit tests will help a lot here. If everything still works and you are confident in the code, then you can open the pull request.

The Pull Request

Decide in your team how you will manage pull requests. At least one other member of the team should review the changes, provide feedback, suggest or make changes (make changes in additional commits to the development branch — the pull request will reflect those automatically when you push them to Github), and eventually sign off on the pull request. Decide among yourself if you want the whole team to review pull requests or just one additional team member for each. If you have one person review each pull request, you will need to figure out how to assign someone to each pull request.

When the pull request is reviewed and accepted, merge it, and a new commit will be created in the main branch with the added feature. Hooray!