Git Standards followed in our way of Spotify Agile Methodology
For a primer, I would like to say this is the coding stack we have with us (just concentrating on what we need).
- Agile Scrum: Atlassian JIRA
- Version Control: Git (using GitLab Enterprise)
And as per the previous post on My Experience on Spotify Agile Methodology, we follow the same coding and deployment standards, so let's dive deep into each of them.
Update the JIRA ticket status from Backlog or To Do to In Progress.
Whenever you start working on a new issue, make sure the status of the issue is updated accordingly.
This way, the scrum kanban board is always updated and not only that, it also helps to shape the burndown chart well.
Pull the latest code from development branch.
In a team, where multiple people work, it is always hectic to write maintainable code. That's the main reason, we use a version control software such as git. With git, it automatically stores the history of changes and also helps us to revert back to a previous state.
It is important for us as developers to work on the latest change, so it is a less hassle to merge the code and send to the repository. It is always better to pull the latest code from the master
or development
branch before branching out for your feature branch.
Let's say I have three branches:
Praveen: ~/Blog (develop)$ git branch
master
* develop
ppk-10-fixed-branch
Now if I want to create a new feature branch for my current issue PPK-11
, I do the following:
- Pull the latest changes from the repository.
- Check out to the feature branch from the current development branch.
Praveen: ~/Blog (develop)$ git pull origin develop
Already up-to-date.
Create a new feature branch from the updated development branch.
After having the happy feel of the updated branch, check out to the current feature branch. I use a syntax for feature branches this way:
(user name)-(jira ticket)-(summary info)
So, my current issue being PPK-11
and it's about updating the statuses, I check out to the feature branch this way using checkout -b
flag:
Praveen: ~/Blog (develop)$ git checkout -b praveen-ppk-11-update-status
Switched to a new branch 'praveen-ppk-11-update-status'
Praveen: ~/Blog (praveen-ppk-11-update-status)$
Now I am happy to start working on this issue.
Start working on the new feature in your newly created feature branch.
I make all my changes and then check the status.
Praveen: ~/Blog (praveen-ppk-11-update-status)$ git status
On branch praveen-ppk-11-update-status
Your branch is up to date with 'origin/praveen-ppk-11-update-status'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: my-modified-file.txt
no changes added to commit (use "git add" and/or "git commit -a")
Praveen: ~/Blog (praveen-ppk-11-update-status)$
Once I am done changing the files, I would like to make sure if the changes are the same as I expected. So I use the git diff
command.
Praveen: ~/Blog (praveen-ppk-11-update-status)$ git diff
diff --git a/my-modified-file.txt b/my-modified-file.txt
index 6f9eb19..7be967a 100644
--- a/my-modified-file.txt
+++ b/my-modified-file.txt
@@ -1,3 +1,3 @@
<!-- Let me change something for my blog sample. -->
-Original Text Here.
+Changed Text Here.
Other Unchanged Text Here.
Praveen: ~/Blog (praveen-ppk-11-update-status)$
After checking the above output, I am happy with the changes, so I am going to add the changes to the staging using git add
command. Being a lazy guy, I am going to add all the files to the staging by using the wildcard .
:
Praveen: ~/Blog (praveen-ppk-11-update-status)$ git add .
The above command will not give you any output. To check what has happened, let's have a quick look at the status using git status
:
Praveen: ~/Blog (praveen-ppk-11-update-status)$ git status
On branch praveen-ppk-11-update-status
Your branch is up to date with 'origin/praveen-ppk-11-update-status'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: my-modified-file.txt
Praveen: ~/Blog (praveen-ppk-11-update-status)$
Wait! What if I need to check again, the diff of the staged files? The git diff
command works only when the files aren't staged for the commit. So, you need to use the --cached
flag to get the same result:
Praveen: ~/Blog (praveen-ppk-11-update-status)$ git diff --cached
And say, if you want to unstage a file or a set of files, use git reset HEAD <file>...
to unstage. It gets put back to the modified stage (i.e., undoing git add
).
Once everything is done, go ahead and commit using git commit
. Here, I generally suggest the following naming convention. Since all the commits carry the author's name, I would prefer not to include my name in the commit subject.
(jira ticket): (plain sentence case of commit)
And I would suggest detailing the changes that have been made by using simple lists in commit messages. An example would be like:
* Change one.
* Change two.
Good practice would be using a maximum per line of:
- 50 characters for commit subjects.
- 72 characters for commit messages.
For the current task, I have this as the commit message:
PPK-11: Update task status in JIRA.
* Updated the file my-modified-file.txt.
* Changed the original to changed line.
Make sure your code complies with PSR-4 Standards (this is related to the current project, so may or may not apply to other projects).
The standards should be given by your project. Since my project is a PHP based one, we used the PHP FIG PSR-4 Standards. This will be different for each type of the project, so I am not going to brief anything about that here.
Create one or multiple commits, prepending the JIRA ticket.
A branch can have multiple commits and can be merged to another branch. So feel free to add as many as granular branches possible. Make sure each commit serves a single purpose, so that when you don't need a particular feature, you can toggle it off by reverting that particular commit.
My current branch looks this way:
Praveen: ~/Blog (praveen-ppk-11-update-status)$ git log --oneline
ee036e5 PPK-11: Update task status in JIRA.
5b3dac2 PPK-11: Next change made.
e91c527 PPK-11: Created my initial change.
Before pushing the changes...
If the remote branch is already updated in the meantime, do a pull --rebase
from the remote, then you’re supposed to rebase your feature branch with the new commits.
Praveen: ~/Blog (praveen-ppk-11-update-status)$ git pull --rebase origin develop
... ...
... Fast forward happens here ...
... ...
First, rewinding your head to replay your work on top of it...
Applying: PPK-11: Update task status in JIRA.
Applying: PPK-11: Next change made.
Applying: PPK-11: Created my initial change.
This step ensures that there are no merge conflicts in your new feature branch commits. If the remote branch is not updated with new changes, just push new feature branch with the new commits.
Praveen: ~/Blog (praveen-ppk-11-update-status)$ git push origin praveen-ppk-11-update-status
If you like this post, please do support me by buying me a pizza!
Buy me a Pizza
Create a merge request in GitLab, and get votes from every member of the chapter, say UI team.
GitLab provides a feature for a code review process, out of the box to ensure the code quality. The best way to do this is by using Merge Requests Approvals. Merge Requests is similar to Pull Requests in GitHub, which can be approved and merged only by users with developer permission or higher.
You can make GitLab to not allow the merge without the approval of two or three member or specified members:
Approvals will not allow the merging of a merge request until the preset number of approvals has been made. This gives us more power to force a certain amount of people to check all the code that goes into master or development branches in our repository.
We can set the number of required approvals and we can assign specific approvers that need to approve the merge request. If specific approvers were set, only they will be able to approve the merge request. If not, anyone with developer permission or higher will be able to approve the merge request.
Add a comment in the JIRA item with the screenshots and merge request link.
This is generally a better practice, as in our case, GitLab and JIRA aren't connected, we usually add a Merge Request link as one of the comments to the JIRA issue. Generally I would do this way:
This way we can loosely link the JIRA ticket with GitLab repository for a future review.
Merge the branch.
Merge the branch with the development branch, if there are no merge conflicts - mostly this won’t happen if it’s rebased and pushed, or if the branch is not updated in the meantime. Considering the branch has been updated in the mean time, we can follow the instructions given above in the Before pushing the changes section.
Merge the code to development branch in the repository and make sure graph looks straight.
When you don't rebase your current working branch, this is what it looks like in your local - your current working branch is far behind the current master branch in the remote repository:
So, when you create a new branch from the old (then new) master branch and have been working, say with three commits added, it looks something like this:
Your current branch is based off old code and when you merge it as is, there are high chances of merge conflicts coming pre-merge and the merge will not succeed. Also, when you push the branch, it would be difficult or not a good idea to strip off the commits and re-push (this happens in case of a forced push of outdated branches).
After a rebase, even before the push of your current working branch, you could see how your origin/master
and master
are in the same page and your new commits are top of the latest origin/master
:
I quickly follow this set of commands for rebasing:
# Checking out to master branch.
git checkout master
# Pulling to make sure I have the latest code.
git pull origin master
# Branching out feature branch from master.
git checkout -b praveen-ppk-11-feature-branch
# Adding some commits.
git commit -m "New commit 1."
git commit -m "New commit 2."
git commit -m "New commit 3."
# By this time I have three new commits in my local repository.
# At the same time, the remote master has got some new commits as well.
# I need to rebase my current branch, else it will be a disaster while pushing.
# The best way to do is:
git pull --rebase origin master
# My work will be replayed on top of the latest head.
# Now I can safely push the code.
git push origin praveen-ppk-11-feature-branch
Note: I have seen my team members, merge the master branch with their current working branch. Seriously, that's the worst thing I have ever come across. Please never ever do this. Challenge whoever has taught you. Let's take the tutorial or the person down! I am serious!
If you like this post, please do support me by buying me a pizza!
Buy me a Pizza
Now coming to the graph, tell me which graph is good?
Graph A
Graph B
ps: These awesome graphs are done using
GitGraph.js
.
If you have chosen Graph A, I am giving up. If you have chosen Graph B, that's the way to go. Clean and rebased one.
For what it's worth, there are some crazily screwed up git trees:
Think about the merge conflicts happeing in the above scenario?
Update the JIRA ticket status from In Progress to Ready for QA / PO / Done / Release.
Updating JIRA regularly will make sure you are following the best practices. The Scrum Master will be able to understand the velocity of the team and also help to get the burndown chart in the right shape.
Post JIRA Update
- Pull the latest code from remote development branch to your local branch after the push or before you start branching out to create your feature branch.
- Start with the next task by following from the Update the JIRA ticket status from Backlog or To Do to In Progress.
Summary
There are many ways of making git work for you. This is one of the best ways in my personal opinion. You can either use the same method or take inspiration and improve this method in your work place. Either way, let's make the development environment, a better place. Pop in your experiences and your questions in the comments section.