DEV Community

Cover image for Avoid messy git history, use linear history
coyla
coyla

Posted on • Edited on

Avoid messy git history, use linear history

Lost 😰

  • Have you already encountered the same git history ? Maybe you don't if you work alone or work on small project/team, BUT i have already faced this situation on standard projects (>10 members).

The problem here is not to GET many branches, this is a normal situation but the problem is THE WAY we manage these branches.

The problems

  • πŸ˜– Hard to read, Look at the history even if you don't need to find or revert a commit, visually you feel bad, same as you are when you see messy home for example.

  • πŸ” Hard to find/revert to a commit of our history will be also be annoying, this will even can create other conflicts... so a bug fixes and maintenance will be more complicated.

  • πŸ› Filter or create new bugs when merging work to the another branch why ? Take the followed example:

    • branche 'B' pulled from dev branch
    • dev branch keeps moving, meanwhile you work on feature
    • now you finished & you will merge
    • you fix conflicts
    • now it's merge
    • the problem starts here ⚠️

Even if you fixed conflicts you don't even know if the merged (dev branch) is working, but this is to late, you have already mixed the 2 branches.

Ok There is some bugs? I can revert BUT you will create another commit on dev.. SO you are polluting the branch with unnecessary commits and potentially creating bugs if you don't see/test before.

Linear history works well to me, this is one solution.

πŸ€” Do i really need to see old branches ? Maybe not it depends

Linear History πŸ™

This is Angular(google) git history. I don't know exactly which internal rules or tools they use to get this.

But this is a example of what i prefer to see in my projects.

You can also see that the messages are clean. I will write another post about that soon.

How i do to get a linear history

  • avoiding --no-ff option
  • using rebase instead of simple merge

Avoid [merge --no-ff]

You commits are directly following the origin branch ? So GIT will create a linear history without creating a "new merge commit", just by mixing and move HEAD pointer.

πŸ‘‰ This case can change, it depends on:

  • Is the target branch ahead (more changes) ?
  • Gitlab/Github merges configuration (default --no-ff ? )

Result will be this. It created a "new merge commit"

Rebase: my πŸ¦Έβ€β™‚οΈ

Mix branches in order to get linear history needs to following next steps

basically:

  1. update
  2. rebase
  3. merge
  • /feature branch is ready to be mixed ?
  • update (pull from origin) the target branch (dev)
  • rebase on top of /dev branch (for example): now /feature is updated too and ready to test
  • tests, unit, functional and so on.
  • merge, as your /feature is directly following the HEAD of dev branch, you branch will merge without creating "new merge commit" (see first GIF).

Observation

  • Ok rebase, needs a little more steps compared to merge, but this was useful to me, i can improve tests and avoid bugs.
  • This is not THE SOLUTION, sometimes you need to keep track of an old branch, i don't know maybe you need to see when a feature branch was started and finished/merged, it depends of your needs, you should ask yourself do i need to see this branch in my history ? is it meaningful ? YES/NO ?
  • As rebase creates "new commits" than you feature branch, if you team mate has pulled his work from your /feature branch he might have conflicts when he will merge to /dev branch (MAYBE). This is a little bit tricky, see how REBASE work here: https://git-scm.com/book/en/v2/Git-Branching-Rebasing. If you need me to explain it please let me know.

Thank you for reading ! πŸ™‡β€β™‚οΈ

Top comments (8)

Collapse
 
kosich profile image
Kostia Palchyk • Edited

Very important subject! Thank you for the article!

Some additional advices from my experience:

  • use some git methodic teamwide (e.g. git flow) β€” messy history is often a result of messy dev flow

  • ensure everyone in the team is comfortable with git (better git-cli)

  • git pull --ff-only β€” to pull remote branches. By default pull will use merge strategy if there's difference between remote and local branches

  • if previous cmd fails β€” run git pull --rebase to use rebase strategy. You can skip "--ff-only" step, but I prefer run it first to acknowledge there is a difference

  • GitHub (probably others too) has settings to protect branches from direct pushing (under "Branch protection rules") and limit PRs merging strategies: merge | squash | rebase β€” I usually prefer keeping only squash option

  • Github (probably others too) has a setting to enforce linear history in branches (under the same "Branch protection rules") β€” but that's an ultimate weapon I've not used yet πŸ™‚

Collapse
 
bladesensei profile image
coyla

Awesome man . Thanks to share this with use.

I have already used the gitflow of your link. I use this one, from Atlassian atlassian.com/fr/git/tutorials/com... checked quickly.

Total agree with "ensure everyone in the team is comfortable with git", we all already faced the situation of "fear" to brake something.. when i started to use git i was fear of "rebase" and "conflicts".. and we should give more confidence to each developer of the team. Nice point !

Collapse
 
kosich profile image
Kostia Palchyk
Thread Thread
 
bladesensei profile image
coyla

Nice package :)

Collapse
 
paxel profile image
paxel • Edited

well written article. thank you.

  • problem I see with the ff merge: if the merge breaks master, you have to revert all the commits or force push to before-the-merge. and it's not even clear where the merge starts.

  • problem I see with the rebase: if you don't stop after each rebased commit and check that the unit/integration tests still work, nobody knows. so if for some reason you have to go back to a commit there or branch off from one of those, your code might be broken. squash removes that problem, but then you might have mega large commits and it's not clear anymore why some of the changes happened.

the problem of the crazy history is in my opinion a display problem, that can be solved by intelligent display of branches and merges. I used a tool called git-kraken for a while, that had a very beautiful display of the history. (not free for commercial use, tho)

Collapse
 
bladesensei profile image
coyla

Hi ! PAxel

  • You know where the problem has started because before merging and break the master for example, has receive a pull request. So they know WHO, the Branch that has caused the problem.

I used gitkraken for a while, i realized that i don't need it anymore. But the main problem is the maintenance not only the visual. Visual is a secondary problem, developer we should always try to work properly for ourself and team members, for future work even if there is something that we don't see everyday like a git history, a documentations ...

Collapse
 
paxel profile image
paxel

hey coyla,
we don't use github or gitlab pull requests. just plain git. if you fast forward a merge, you don't see any branches or info without diving into the internals. in our company we try to pull with ff and only rebase if it fails to avoid a) pull merges and b) accidental rebases of merged branches. we also merge no ff always to keep the branch name information. for multiple reasons.

sometimes it goes wrong and everything looks shit. most of the time we have clean feature branches.

I guess in the end it's always what the team decides for and if everyone is happy every solution can be the best one.

Thread Thread
 
bladesensei profile image
coyla

Yes. It depends of the team. I remember that some people said in our last team " we need to keep track of the release branch" so must of the time we used rebase and sometimes normal merge (for releases) as you say.. thanks to share your way to do πŸ™‡βœŒοΈβœŒοΈ