How to rebase

When working in a shared code repository, it is important to stay up-to-date with what your teammates have done. You don't want to build your feature off of changed or deprecated code. And the longer you work on your branch, the harder it is to incorporate your team's changes.

  • Most developers merge their code into the main branch only after they are done working on a feature, hoping it will work. 🤞 🙏
  • Some developers incorporate their team's changes every so often by merging the main branch into their feature branch.
  • Some merge team changes daily.

Incorporating code daily is a good habit. But merging has drawbacks.

Merge ⛙

git merge works just like a zipper merge on the highway. It allows everyone to get into "one lane" - the main branch - and is time-based.

Developer commits
Dev 1
Dev 2
Dev 3
Dev 1 merge
Dev 3 merge
Dev 2

It looks pretty. But if you need to rewind or undo your commits, it's not easy. Your commits are sprinkled among everyone else's.

Rebase

git rebase is similar to merge, but with an important difference. Rebase "rewinds" the Git history, playing back each remote commit sequentially, until all of your commits are on top.

Developer commits
Dev 1
Dev 1
Dev 1
Dev 2
Dev 3
Dev 3

If each developer does this, the Git history represents chunks of commits that build on the previous developers' commits. Commits are more easily reverted, undone, and tracked.

Soft reset

We mentioned that rebasing "plays back" each past commit, comparing it to your local changes. Conflicts may arise, just like with merge. But this playback can make resolving commits repetitive, and it can be confusing.

One way to make this easier is to combine numerous commits into one.

For example, if you have committed several times while working on one issue, trying different techniques until you reach the best one, you may have a series of commits that do and undo several changes. This Git history can read like an undo/redo log in an application. It may take half a dozen commits to arrive in essentially the same place. This history of trial and error doesn't benefit your teammates.

Instead, you can soft reset to the first commit. All changes you have made will be preserved and staged. You now need only commit and write a new succint message describing the changes.

Example

Back up your current branch before proceeding.

git tag backups/my-backup

Find the hash that you want to "rewind" to.

git reset --soft ${hash}

All of your changes will be staged. Commit them as a single commit.

git commit -m 'feat: add value to our app'

When you push back upstream, use force because you have rewritten the Git history.

git push upstream head --force-with-lease

Resources

How to rebase
Interactive graph
On this page
Merge ⛙
Rebase
Soft reset
Example
Resources