It is a subject I'd like to put on the table because of some attentions points we have to have in our minds.

The Git page gives the definition: The git rebase command allows you to easily change a series of commits, modifying the history of your repository.[1]

That part is ok. I believe all of us is aware about that. My concerns is the WARNING after the definition:

Warning: Because changing your commit history can make things difficult for everyone else using the repository... It's considered bad practice to rebase commits when you've already pushed to a repository.

The alert brings up the risk to lose code. It is a painful part in the developers work.

The fundamental Git workflow use the merge command which brings your work from some feature branch to your target branch. The image below illustrates a merge command. Note that there is a last commit regarding the merge.

The merges preserves the entire history of your repository (even the chronological order). It makes the merges a traceable command. However, they can make a mess on the tree and can be painful to review because of a lot of irrelevant commits. It is one reason to use the rebase. It makes the tree cleaner and reviewer-friendly.

Rebasing changes where you started your branch. The whole branch is lifted up, and transported to the end of the current master branch, where it connects to the end. The master branch is left untouched, and is free to continue receiving commits. The commits aren’t actually moved, however, since commits are immutable. Rather, they’re copied, which results in new commit IDs. The previous commits are left stranded, hiding in your Git files but never to be seen again, since the playhead has moved somewhere else.[3]

In other words, the rebase identify the base of the feature branch and commit again all the commits after the last commit in your main branch (eg. master).

When you run git rebase, Git takes each commit in the branch and moves them, one-by-one, onto the new base. If any of these commits alter the same line(s) of code as the upstream commits, it will result in a conflict. The git merge command lets you resolve all of the branch's conflicts at the end of the merge. In rebase, the process will stop the rebase procedure and display a warning.[2]

After solve the conflicts you just need continue the process (git rebase --continue). The rebase can be done in an iterative way, selecting which commit you want. It's a way to have a clean commit.

The Trick

As we saw in the definition, the rebase command changes the original base commit of a branch. It makes the new commits in the target branch without no context of where those commits come from.

The rebase will not delete the commits or reposition them. The rebase will rewritten the history. Here is the trick: the risk to lose code when you are working with other developers because they are using a part of the tree not used anymore. It seems the code was deleted, but it's just the main part of the tree that was changed. For sure you can rescue the commit, but it's a hard work to do.

The image shows an example where we can fall into a trap. It has a feature branch created from master. The branches and commits are a mirror of remote repository. Then is done a rebase locally and a push. You can see the feature branch is there yet.

Now the next image show an example where the tree can be a messy even using the rebase. The example use a shared feature branch, do a rebase locally and push it. In this case, the rebase was possible doing a pull first (implicit merge). The example do commit in master, rebase again and push.

Use or not to use? That's the question

The rebase create new commits and let the old parts lost in the limbo. It is the issue if you are sharing the work with other developers. The others can use that tree in the limbo. So, how to decide?

  • Avoid use rebase in public branches unless you are sure that anyone is working on that branch.
  • You can use rebase to a local cleanup and commit only what is necessary
  • You can rebase onto a remote branch instead of master to help your collaboration with another developer and incorporate their changes into your repository.
  • Avoid rebase shared branches
  • Prioritize rebase locally
  • Verify the priority of the work: simplicity (rebase) or traceability (merge). Pay attention rebase requires more work when dealing with conflicts
  • Verify if you are in a big project and if everyone knows how to use it in the right way.

Conclusion

The rebase is an excellent resource to work with. However, it requires attention at some points to avoid unnecessary headaches. The decision should be made based on the type of collaboration with other developers and the level of expertise.

Reference