Version Control: Git, Git Flow

Wilson Hadi
bisaGo2020
Published in
8 min readOct 21, 2020
Photo by Annie Spratt on Unsplash

An individual review article for PPL UI 2020 Course

Version Control?

Known also as the Version Control System (VCS), Version Control allows organised team management within a development team. Realistically, different team members or developers will be working on different things at the same time and the changes made by each developer may not necessarily be compatible with other versions of the project developed by other developers. VCS will help solve problems like this by tracking individual changes and have a merging system to prevent any conflicts within the project.

Git?

Git is one of a VCS and is probably the most popular. In this article, we will talk more about how to use Git as your VCS choice. Here are the most often used git commands and how my team have implemented it:

  • git init: initialise an existing directory into a git repository
    I use this when I first created the directory where I will store my work for the project:
  • git clone: create a local copy of an existing remote repository (files, branches, commits)
    I use this whenever I want to download the whole remote repository of a project. As seen below, when you clone, an additional folder is created and the repository will be downloaded there:
  • git pull: pull or download all changes and commits to your local repository
    I use this whenever I want to update my local repository to the current remote repository. Additionally, when I move to another branch using git checkout (explained later), I use git pull to make sure I have the newest version or updates of that branch.
    In the example below, I currently have the newest updates of the Staging branch, so it gives me an “Already up to date.” message:
  • git checkout: switch between branches
    I use this to change or make new branches through my terminal. An example can be seen previously in the example for git pull where I did a checkout to the staging branch. But here is when I want to go to a new branch:
  • git status: shows the files where you made changes to in your local repository and gives indication if they have been committed or not.
    I use this to check which files I have made changes to and whether or not I have committed them in my local repository:
new changes in red
  • git commit: save changes and commit them in your local repository before you push your work to the remote repository.
    Everyone will have to use this to push or upload their work to the remote repository. It is best practice to commit with a message to show what kind of update or change you have done with this commit to better document the progress done. However, before doing git commit, you first have to git add:
  • git add: add the changes to your local staging area before committing them
    Everyone will have to use this before committing or pushing their work. I use a dot “.” (git add .) which means I will add all the changes I’ve done:
  • git push: push or upload all the (committed) changes you made in your local repository to the remote repository
    After adding and committing the changes done, you push to the remote repository by also specifying which remote repository and which branch you want to push to. Since I am currently not pushing anything to my remote repository, here is just an example of the syntax:
  • git merge: merge or combine the changes you did with another branch. Conflicts may arise since some parts of the same file may be too different with each other. You can manually fix these conflicts or choose via git which change you want to implement. You can also merge via the git UI, which is how my team merges branches:
example of making a new merge request
  • git stash, git pop: to temporarily stash or keep your changes without committing it. Then use git pop to have the stashed changes loaded back.
  • git remote: connect with remote repositories
    I use this to initialise a connection with the project repository and to see what repositories I already do have:
the additional-origin is just for example purposes
  • git branch: do actions related to branches such as delete, add, and see what branches are there.
    I’ve only ever deleted a branch using this command due to a typo in the name, like so:
  • git revert: undo commits you’ve made and makes a new commit to overwrite the commits you want to undo. You’ll need to specify the parent number and commit id to overwrite
    I have never implemented this in my team yet.
  • git reset: undo the commits up to the last commit of a branch. You’ll need to specify which branch you want to reset to.
    An example of when I’ve used this is when I made a typo in a commit message, so I reset my branch to the last pushed commit and redo the commit message, removing the typo altogether before pushing.
  • git rebase: combine commit branches to a new base commit
    I have also never implemented this in my team yet. However, a situation where you can use rebase is when you are working in a smaller project where commit history does not need to be preserved since rebase regenerates commits on top of the target branch. In this sense, rebase is said to be simpler while merge has better traceability (from commit history).
    An example case of where I would prefer using rebase is when I work on my own project, for example a portfolio website, and I rebase with the master any additional features I have finished implementing. This way, my project history is cleaner than using git merge. It’s safe to use since I am working the project on my own and will not raise confusion with other team members regarding the commit history.

Git Flow

Now that we know the basic commands, let’s dive into the flow of how things work in Git. Git Flow is a pattern that helps the team easily track changes, making the master branch deployment process cleaner.

from PPL 2020 Guide

Branches

As seen in the image above, there are a few main branches with different ‘roles’.

  • Master Branch
    This is where the source code that is ready to deployed located. The version here should be ready to be used by the user. The Scrum Master will be the one that approves merges to this branch.
  • Staging Branch
    The source code here will be the one from every member of the team. Here is where our team merges into from our individual branches once we finish each PBI. This branch is also the base for our Sprint Reviews. Here is an example of our merge with this branch after finishing our individual tasks and PBI:
failed due to backend deployment problem
  • User Story / Individual Branch
    Here are where each member push their work before merging with the others’. Right now, we are naming each of our branches with the following syntax: “dev-<name>”.
  • Hotfix Branch
    This is a branch for fixing errors or bugs coming from the Master branch. We resolve the issues there until pipelines pass and then the Hotfix branch will merge back with Master.
    So far, we have not yet the need to involve this branch.
  • Coldfix Branch
    This has similar purpose like Hotfix, but is used for the Staging branch instead of Master. Cases such as the PO rejecting a user story that has been merged into the staging branch, the staging branch will then be reverted. The naming for this branch should be as so: “coldfix-sprint-<sprint_number>”, such as “coldfix-sprint-2”.
    So far, we have not yet the need to involve this branch.
  • Additionally, we have PBI Branches
    This branch is where we usually merge our individual tasks to, then the PBI branches are merged into Staging once the Sprint backlogs are finished. To make this branch, we make new branch from the Staging branch:
making new PBI branch from staging
example of our PBI branches

Now, we have a better knowledge of Git Flow using the commands and branching methods. Here is how our team implements it. First, we do repository initialisation locally:

  • git init
  • git clone <https.git>/ git remote add <https.git>

Then we make sure there is the staging branch:

  • git branch -v (check which branch you are in, make sure in Master)
  • git checkout -b staging

After staging is there, we make the PBI branches where the origin branch is from staging.

  • git checkout staging
  • git checkout -b <PBI_branch>

Then we initialise our user story / individual branches:

  • git checkout staging
  • git checkout -b dev-<member_name>
  • or use the UI method shown previously in the screenshot

After finishing our work, we commit and push them. Surely, we follow TDD discipline where our commits will start from [RED] to [GREEN] with possibly some [REFACTOR]s and/or [CHORE]s without forgetting to make sure our commit messages are descriptive:

  • git add .
  • git commit -m “[RED/GREEN/REFACTOR/CHORE] <commit_message>”
  • git push origin <user_branch>

Once we make sure tests have passed on our story branches, we merge them into the PBI branches:

Here is an example of my merge request to a PBI branch:

After the PBI is done, we merge into the staging branch in a similar way. However, a couple things to mind before merging is:

  • all tests have passed (GREEN pipeline)
  • rule where at least 2 team members review the code and give their approvals
  • uncheck “Remove source branch”
  • check “Squash commits”

So, far, this is all that our team has been implementing in our (almost) 2 Sprints. In short, an example is as follows:

red: actions | blue: branches

Thank you for reading!

— Wilson

References:

--

--

bisaGo2020
bisaGo2020

Published in bisaGo2020

bisaGo is a mobile app designed as a platform to provide information about public facilities in order to help people with disabilities. Users can access and add information about the availability of public facilities in a location.

Wilson Hadi
Wilson Hadi

Written by Wilson Hadi

3rd year Bachelor’s Degree of Computer Science at University of Indonesia