Git Branches for the Impatient

2016 07 01 head

You are working in a small mostly collocated development team. Sometimes a team member works from a remote location.

You have one git repository accessible to all team members.

This repository is used to share source code and documentation artifacts.

You use the actual industrial standard for version control systems is git.

You decided to use branches to implement new features or fix errors instead of using Trunk-Based Development.

Here the cookbook to create, edit, merge and delete local and remote branches in Git (version 2.x).

Git branches have two important qualities.

  • A branch is like an idea. Once you implemented the idea, feature or fix, you just merge back to trunk and delete the branch.

  • Multiple branches coexist in a repository. Ideally, branches should be short-lived to avoid waste.

  • The history of the branch commits is still visible upon deletion of the branch.

In an agile working setup, a branch should be merged before the end of the sprint.

All stories should be completed inside a sprint time slot.

You should use meaningful names for your branch name and associated commit messages. Put the ticket number into the branch name and messages for future searches.

A lot of servers support keywords such as fix #42 to automatically close ticket 42.

The described approach is optimal for small teams. The approach is compatible with pull requests if you introduce such a workflow later. You do not need to pull requests when you are working collocated. I prefer pair programming and pair check-in sessions against the trunk.

For a short introduction to how to start using Git in software projects, see the blog Git Local Repositories for the Impatient.

Create the Branch

You get a list of branches with:

git branch                                      (1)
git fetch                                       (2)
1 List of all branches in the local repository.
2 Retrieve all changes from the remote repository including new branches and store them in the local repository. Your working directory is not modified.

Create new branch feat-#42 locally.

git checkout -b feat-#42                        (1)
git checkout feat-#42                           (2)
1 Create a new local branch.
2 Select an existing branch.

Create the remote branch with the same name and initiate tracking, assuming your remote uses the standard default name origin.


git push -u origin feat-#42

Publish files on branch when you are ready to share your changes. Once files are available on remote repository, you should avoid rebasing your branch.

Work on the Branch

Add your changes and commit them regularly.

git commit -a -m “commit message describing activities for feat-#42“

As long as you are working alone on the branch, regularly synchronize it with the main trunk using rebase operations. I suggest performing the synchronization at least daily.

Once you share your branch, synchronize using merge operations. Doing a rebase will confuse other developers by providing an alternate version of the same change.

This housekeeping avoids stress when you finally merge your branch back to trunk.

Upon running the unit tests locally, push the changes to the repository.

git push

Now you can test the branch from the central repository and deploy it to your continuous integration pipeline environment.

When working in a team, you can request a review of your branch before closing it.

GitHub calls such a request a pull request. You can open a request through the platform.

GitLab calls such a request a merge request. You can open a request through the platform.

These platforms provide tools to identify open requests you are requested to provide feedback.

Major IDEs provide some support to create and edit a merge request. Often GitHub is better supported than GitLab or Bitbucket.

Merge the Branch

Switch to main and synchronize with your remote repository, the -p parameter means --prune.

git checkout main       (1)
git fetch --all -p
git pull
1 The default branch is often called main, master, or trunk.

Merge to main. The option --no-ff will always keep branch information.

git merge --no-ff feat-#42

Or if you want a single commit to the complete branch.

git merge —squash —no-ff feat-#42       (1)
1 You can perform complex squashing of selected commits using git rebase -i HEAD-X. X the number of commits in the past you want to manipulate. Please consult a tutorial or an expert before trying it.

The strategy using squash when merging is often used when a Pull Request is closed. Code hosting platforms like GitHub, GitLab, or Bitbucket support this as an option when merging a pull request.

Push the changes.

git push

For advanced users, you can first rebase your branch and squash superfluous commits before merging the branch back to trunk.

Delete the Branch

Delete the remote branch (also git branch -dr origin/feat-#42).

git push origin --delete feat-#42

Delete the local branch.

git branch -d feat-#42

You are done. Now you are ready to implement the next feature.

View Local and Remote Branches

If you want to view branches, use the following commands for the local branches.

git branch
git branch --no-merged

If you want to view remote branches.

git branch -r
git branch -r --no-merged

Checkout Remote Branch.

The -p parameter means --prune

git fetch --all -p
git checkout #feat_42

Thoughts

You can find a lot of information on Stack Overflow. Beware when reading the answers on Stack Overflow that Git commands have changed over time. Select new posts to find the best answers.

The nifty-gritty details can be found in the official Git documentation.

The Pro Git book can be downloaded from Git SCM.

Beware that gitolite does not support special characters such as # in branch names. Use them only in the commit messages.

These same characters work in bitbucket.