Story 1: Short living branches

Imagine quite a common situation. You are a part of the development team. There is some kind of user story or a technical task that needs to be implemented. You create a branch for it. Your hard work has just started. After one week of development, you are finished with it. You have been synchronizing your branch with the main one (does not matter if this is development, stage, master, or any other – a shared one) multiple times during your work or you did it just in the end.

Problem number 1: You need to remember to merge changes from the main branch or to rebase quite regularly. If you forget about it for a day or two it may cost you grimace (or two!) on your face.

Problem number 2: If you do it in the end, there is usually a lot of conflicts with other changes that were performed during this period of time. It quite often leads to anger, sweating, and quite a several bad words.

Ok, you finally synchronized your branch and it is ready for a pull request. Now, the reviewer sees something similar to this view:

This branch contains a vertical slice that allows users to download a small file. There are 45 commits that touch 82 files. 4571 lines of code were added, 45 removed.

Problem number 3: The reviewer has now to focus on the entire slice in his code review. He needs to either go commit by commit or through each of 82 files. PR can include changes related to business logic, architecture, code formatting, renaming, and many, many more.

As you can see there are a lot of different areas to focus on. If the reviewer focuses on each file only for a minute, it will take him 82 minutes to finish it. With such an approach, many important issues will be overlooked. What about things like architecture analysis, looking at design patterns, and testing the outcome to see if it works as desired? There is a high chance that in the end, the reviewer will be exhausted and demotivated to handle such an amount of work. Another (really bad) option is that he goes with LGTM (Looks Good To Me) and PR is approved.

The review goes on and after 4 hours you get the response. It looks as below:

There are 53 comments from the reviewer and your pull request is rejected.

Problem number 4: You see 53 comments. That is a lot. You need to go through all the inputs. For sure there will be things like cleanup of namespaces or rename of methods. There will be as well comments that are discussable (here you still need to discuss each of these). But there are also hardcore ones – switch it to this design pattern, refactor quite a lot of code. After several rounds of review & rework, you are ready to merge it! Ooops, look – you need to rebase, again some conflicts. Finally, it is merged after 2 days full of R&R rounds. There is a high chance that in the end, you will be exhausted and demotivated to handle such an amount of work and comments. It might be even worse – am I the right person for this job?

Imagine another situation. Instead of taking a user story or a task into one branch, you analyze it first with your colleagues who will implement it with you. After some time, you decide to split it into small subtasks:

1. Prepare download icon design (approx. 1-2 hours)
2. Integrate download icon into file row without any action connected (approx. 2-3 hours)
3. Handle business rule number 1 required to generate download link (approx. 3-4 hours)
4. Handle business rule number 2 required to generate download link (approx. 3-4 hours)
5. Prepare technical implementation to generate download link (approx. 6-8 hours)
6. Connect technical implementation with business rules (approx. 3-4 hours)
7. Implement endpoints (approx. 3-4 hours)
8. Trigger download action on clicking the download icon (approx. 1-2 hours)

Now, you are ready for short living branches, the ones that live for a short amount of time after the creation. What does a short amount of time mean? You should agree on it with your team and in the beginning try to keep it (after some time you will not try, you just do it :)). Within this period of time, you should make sure that the branch is merged and closed. This way, the speed of change is entering previously unimaginable levels. More and more people start to increase their motivation (“yeah, my code is merged!” or “great, a small number of changes, I will try to rock it!”). The feedback loop is shortened to a minimum.

I tried to sum up my recommendations for a time when you decide to enter this world:

Recommendation number 1: Analyse and split. Divide your work on a user story or a technical task into smaller pieces. From this moment, each subtask can be treated as a separate, short living branch and you can easily parallelize the work with your colleagues – each of them will take one subtask and create its own branch.

Recommendation number 2: New work discovered = new branch created. Whenever you find a new thing to be done after the initial split, treat it as a new, short living branch (add subtask and start your work).

Recommendation number 3: The shorter = the better. Do not go with more than 1-2 days for each branch. Even if you will have to merge changes to or rebase your branch at the end of work, then it will not be as much as it would have been after 1-2 weeks. I try to keep it alive for 4-6 hours. If you follow this recommendation, usually it is easier to get “team willingness” to perform reviews way faster than before.

Recommendation number 4: The less = the better. Try to keep your pull requests as small as possible. This way, the reviewer who looks at your code where there are 4 files changed and 8 commits, will be motivated to deeply look at changes. On the other hand, you will see e.g. 5-10 comments that can be quickly solved. This will not demotivate you in comparison to 53! Observation from my side – the fewer files are in PR, the faster feedback I get – sometimes it is ready after 10 minutes from the request to review and I am able to merge.

Recommendation number 5: Try to start from the bottom. Whenever you divide your stories or technical tasks, try to start from the work that is not visible to a user. When you implement a new feature, make sure that the trigger between the user and a code is implemented as the last step (e.g. the icon that the user can click in a view or endpoints that can be called by any type of client).

Recommendation number 6 (advanced): One area of change = one branch. This is usually achievable after some time. An example – during your work on short living branch which is responsible to add an icon to a file row, you discovered that it would make sense to move 20 files to another namespace and another 15 files to a different one (not directly related to the change you make). Of course, it can be handled within separate commits in the current branch but I suggest creating another short living branch that will include only these commits that touches the structure of namespaces. Another example – the first branch creates a UI component, the second branch integrates it.

In my experience, changing your thinking to short leaving branches, brings much good and benefit – both for a product (increased quality because of deep focus during code reviews) and for team members (increased motivation).

However, be careful – if done incorrectly, it can decrease product stability (when changes are not well thought out, especially in continuous deployment environments) and decrease the motivation of several guys (when the team is used to working separately for 1-2 weeks, this will be quite a long process to convince all of them).

And you? What do you think about it?

4 responses to “Story 1: Short living branches”

  1. Thanks. This is an interesting approach. But sometimes in a project, we can only have one instance (person) to do a review and this is the deadlock for this solution. He can’t handle too much PR. Of course, this problem is located in a different area.

    Like

    1. Hi Krzysztof,

      I cannot agree – even if there is one person, it makes not a big difference if this person has to take a look at your PRs twice a day, 15 mins each (or even half an hour) or after 2 weeks with extremely large PR, spending a couple of hours or more than 1 day. Based on my experience, this person will give you way more valuable feedback within 15 mins of review than a day on a huge amount of code changes.

      Give it a try and you will probably never go back to long ones 😉

      Like

  2. Thanks for the story. What if there is a user story with two tasks: “Implement a new feature” and “Create unit tests for the new feature”. Then, following the principle of “short-lived branches”, should we create a branch to implement only the new feature, and later another branch to create the unit tests (or the other way around)? It seems to me that this should be done in a single branch. Unless we can follow TDD and create (empty) unit tests first, followed by actual implementation.

    Like

    1. Hi Jacob,

      Thank you for your comment!

      Here the problem lies somewhere else – this user story should be divided in a way that each subtask covers part of functionality including unit tests. It is very important to make sure that whenever code is merged, it is merged with its unit tests and does not affect negatively your codebase. This way you make sure you will not forget it in the future.

      So, instead of having:

      – Implement a new feature
      – create unit tests for the new feature

      you can start from the bottom (below example assumes clean architecture and DDD – but it can always be done, no matter what architecture or circumstances you have – so first is the domain, then application, then infrastructure and API):
      – add first business logic rule and its tests (branch 1)
      – add second business logic rule and its tests (branch 2)
      – add aggregate with its methods (branch 3)
      – integrate both business rules in this aggregate methods (branch 4)
      – add the command (branch 5)
      – add aggregate repository (branch 6)
      – the last step is to add an entry point to it, so API (branch 7)

      The above can differ based on the current state – if you modify existing functionality and you follow short living branches, you have to ensure that it will not break the current codebase and will not affect the current feature if you are not fully ready (other branches are not yet done). But for such cases, you can e.g. use feature triggers.

      In general, this will take you some time to get familiar with the above approach but it is really worth it. In the beginning, try to shorten your current branches – instead of having 2, try to have 4 and move on 🙂

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: