Case study: Branching and merging#

This case study assumes you have worked through case studies 1 and 2.

A key feature of version control is the ability to create a branch seperate from the main code that are used for development. Once the code within a branch is complete it is merged into the repo’s master branch.

You should always use branches even when working alone.

Strictly speaking it is best practice to use a branch to create new features and conduct testing. We have ignored branching so far to keep our introductory material as simple as possible. Ideally you always have a clean (and as best you can bug free) main (master) branch that you or your users/colleagues use for production. Obviously if you are working on your own then simplicity is key. A minimum safe option is to create a dev branch where you work towards a new version of your code (perhaps a group of new features) and then merge when everything is complete and tested.

Scenario#

Now that you reverted the master branch to the last working version the code will run correctly every night. In parrallel you will create a new branch and fix the bug in the modified code. Once you are satified it works you will merge the code into the master branch to use in production.

To do this you will need to

  • Create and checkout a new branch called dev

  • Restore the version of main.py that contains the bug

  • Fix and test the bug

  • Merge the dev branch into main

Step 1: Create and checking out a new branch#

We create a new branch using the git branch <branch_name> command. To fix the bug we will work on a branch called dev

$ git branch dev
$ git branch

The second command will list all of the branches available in the repo.

  dev
* master

The output reports that there are two available dev and master. The * indicates the active branch. To switch the dev branch we can either

$ git switch dev
$ git checkout dev

Both git checkout and git switch will move the branch you are working on to dev.

At this point the code in dev is an identical copy of master with the same commit history.

Step 2: restore the buggy code.#

One option now is to write the new code from scratch again - this time making sure that is properly tested and working before merging into main. This isn’t really making the most of git, however. Instead we will restore the buggy version of main.py and fix it in the dev branch. First let’s have a look at the git commit log.

73fcaa5 (HEAD -> dev, master) Revert "MAIN:+do_something_else() extends analysis"
e1c4fd3 MAIN:+do_something_else() extends analysis
6475df6 DOCS: run instructions

The commit that contains the target version of main.py is e1c4fd3. Next we restore the file, add it to the staging area and commit it to dev.

$ git restore --source e1c4fd3 main.py
$ git add main.py
$ git commit -m "FIX: restore main.py to e1c4fd3"

The file main.py, including the bug, has now been restored, but it only in the dev branch.

'''
main module

'''

def do_something():
    print('Friendly code')

def do_something_else():
    print('This is a major bug!')

if __name__ == '__main__':
    do_something()
    do_something_else()

Step 3: Fix the bug#

The fixed main.py now looks like

'''
main module

Fix issued by TM.
'''

def do_something():
    print('Friendly code')

def do_something_else():
    print('Expected value')

if __name__ == '__main__':
    do_something()
    do_something_else()

It’s the end of the working day. You haven’t had time to test your fix, so you won’t risk merging it with master. But you stage and commit it to dev before you leave.

$ git add main.py
$ git commit -m "FIX: do_something_else() patched."

You can also quickly switch back to master (git switch master) we can confirm the code in main.py that will run overnight is the original version.

Step 4: Test and merge the code.#

The next day you have plenty of time to test the new code works. Switching to the dev branch we can run

$ python3 main.py

Friendly code
Expected value

This confirms everything has worked as expected so we can merge the new version of the code into master.

To complete the merge we need to switch to the master branch and use the merge command.

$ git switch master
$ git merge dev

Updating 73fcaa5..6fcbf0d
Fast-forward
 main.py | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

Just to prove to ourselves that the merge has worked we can check the log.

$ git log -4 --oneline

6fcbf0d (HEAD -> master, dev) FIX: do_something_else() patched.
2e9cfcd FIX: restore main.py to e1c4fd3
73fcaa5 Revert "MAIN:+do_something_else() extends analysis"
e1c4fd3 MAIN:+do_something_else() extends analysis

and that’s it you now have updated your code base.