Make Your Timeline Clean: Git Rebase & Git Squash

Version Control is important in software development. A trustworthy version timeline can effectively reduce risks of parallel developing and deploy of new features. Git, as the most popular version control tools adopted by the industry, work together with other derivatives to grant safety of countless products.

When a group grows too large in scale, the timeline of a project could be easily messed-up: multiple feature branches moving forward at same time, frequent merged PRs, rookies trying to merge without a notion of pulling first…

On structure, a git repo couple be consideres as a distributed database while every copy of repo is a duplicate that looking for synchoronization. As many distributed systems expecting, the optimal goal for a git repo timeline should be like a linearizatoin: branches split out to gain new features and bring them back before the next split appeared. Although this is impossible to achieve when there are more than three people in the group, we can use two powerful helpers git rebase and git squash to maintain this harmony.

Functionality

Breiefly, git rebase is to move one or multiple commits after a specific point. It can help to resolve the conflicts while your current branch has un-pulled commits by others or prevent a PR that covered newly merged featrues with older version. git squash is a simple command that compress multiple commits into one. More details about those commads can be found here and here on GeeksforGeeks.

Approach

To achieve the look in the above picture, some situations are worthwhile for an apply:

Git Rebase: a PR that fall behind serval commits on main branch

You can still making a PR with a outdated part of the repo. When PR is reviewed, only modifications contained in the commits of current branch will be highlighted, since the comparison is made with the split point version of repo. Merging without noticing the missing new features would cause a overwrite of old version to the new ones. Using git rebase in this case is similar with git pull origin main that the result timeline will be acceptable for the main branch.

If you are calling the command in terminal, it’s normal to see a coming up error message when you trying to push your update: your local record is diverged from the remote. Since you only rebased your local changes based on local record, the remote side would not be acknowlegded with this update, therefore reject the push. The simplist solution is to complete this rebase with GUI. For example, if your company has adopted the triangle of confluence, jira, bitbucket, you can easily find a rebase option on bitbucket PR. If not, you can still delete the remote branch and push your local as a new branch.

Git Squash: multiple unmerged commits that tangling with pulls from main branch

This is very simple to understand: if the commits are unmerged, the timeplie will have a line piece of the working branch that runs parallel with the main line, with multiple connections between. This makes the timeline hard to interpret. By compress multiple commits into one using git squash, the merged timeline will only have a small diverge of the new feature in developing branch, and the logic are simple as a linearization.

However, git squash will also create a divergence between local and remote. The simplist solution is always delete the remote branch and push the local as a new one. After a PR is proposed, the branch cannot be deleted anymore util it merged into main, thus this move have to be make before the PR request.

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND 4.0) 进行许可。