Git Branch Divergence Calculation

Updated 1 year ago by Copado Solutions

Copado Divergence Calculation

A Git branch divergence consists of the difference between the current state of two branches and the list of changes (commits) performed in each branch from the common state to get the current divergence (commits ahead and behind). This definition accepts two different approaches: the common state can be taken as the state where the branches start to differ, that means where the first commit ahead/behind happens, or the last common state where the branches were in sync (known as merge base).

In Copado, the second approach is used, the branch divergence is calculated from the merge base (last common state) including only those commits chronologically placed between that point and the current head as the ahead and behind differences. This approach is, from a performance point of view, much more efficient than the first one, as only the history from the merge base is needed and this means to Copado to execute all the Git operations in a much more efficient way.

Let’s analyze the example above to understand how it works and the difference with the other approach used by Github and other Git providers. 

As we can see in the picture, we have in this case one promotion branch with only one merge commit from a feature branch with 3 commits. The merge base between the promotion branch and the environment branch is A2, while the feature branch is merged from the commit A1 placed before in the Git history. If we execute a Git log command to see the history, all these commits in the graph will be chronologically sorted resulting in the history line to the right of the picture.

With the first approach, A1 will be the common state used to obtain the ahead or behind differences, which means including the commits C1 and C2  in the list of divergence commits. In this case, we would have 5 commits ahead or behind. Note that in order to find the commit A1, the whole Git history is needed, which means time-consumption to retrieve commits that are not needed at all to see a correct state difference. 

On the other hand, if we use the second approach, the merge base A2 will be used to obtain the differences and only the commits C3, B1 and A3 will be included in the list of ahead or behind commits. The result would be then only 3 commits instead of the 5 from the first approach. In this case, only the history until merge base is needed, which means less time for the calculation and working in a more efficient manner. 

The divergence obtained as result is correct in both cases because no matter the way we follow to reach the head from a common state, the resulting divergence will be the same as we can see in the picture. The only difference is that the number of commits will be greater if we take an older common state as point of reference.

How did we do?