3

When working with remote repositories, you have the option of merging and rebasing, but after reading about it, I can not figure out why or when I would use rebasing. Seems like merging is the better option overall, even if they both have pros and cons. I can only think about scenarios where merging is the way to go. So I would like to know when is rebasing better.

  • https://stackoverflow.com/q/804115/7976758 , https://stackoverflow.com/search?q=%5Bgit%5D+merge+rebase – phd Jan 08 '22 at 18:34
  • Lots of details in these links, so I won't duplicate, but for what it's worth, I rebase work-in-progress and private branches to clean things up before "publishing" in public branches. I merge otherwise. – joanis Jan 08 '22 at 19:03
  • Does this answer your question? [When do you use Git rebase instead of Git merge?](https://stackoverflow.com/questions/804115/when-do-you-use-git-rebase-instead-of-git-merge) – Pino Jul 26 '23 at 10:36

2 Answers2

1

tl;dr Merge feature branches, rebase updates.

If you're merging a feature branch, merge. In fact, force a merge with --no-ff (no-fast-forward). This leaves the history with a "feature bubble" showing which commits were grouped together in a branch. You can see this with git log --graph.

A - B --------- M - H <-- master
     \         /
      E - F - G

If you rebase, you just get a flat history.

A - B - E - F - G - H <-- master

Some people like this flat history, it is simpler, but it does lose information which cannot be recovered. Some reason some prefer squash merges.

A - B - S - H <-- master

Very tidy, but it loses all that useful commit information.


When updating a branch, rebase. This is because the update merges are of little interest to understanding why the code was written. They just obscure the real merges.

# Updating with `git merge master`
# This can look considerably worse if everyone is doing it.

      E - F   G - H  <-- other people's features
     /     \ /     \
A - B ----- M ----- M <-- master
     \       \       \
      C - D - M - I - M - K - L  <-- your feature
# Updating with `git rebase master`
      E - F   G - H  <-- other people's features
     /     \ /     \
A - B ----- M ----- M
                     \
                      C - D - I - K - L  <-- your feature

Instead of your branch being built on a combination of old and new versions of master, every commit is built on the latest version of master. This makes debugging and review simpler, and also the final merged branch is simpler.

# Merge after updating with `git merge master`
# Again, it can be considerably worse.

      E - F   G - H
     /     \ /     \
A - B ----- M ----- M --------- M <-- master
     \       \       \         /
      C - D - M - I - M - K - L
# Merge after updating with `git rebase master`
      E - F   G - H
     /     \ /     \
A - B ----- M ----- M ----------------- M <-- master
                     \                 /
                      C - D - I - K - L

Similarly, a pull is just a fetch plus a merge. Pulls are just updates, so instead do a fetch and a rebase with --rebase or set it to be the default with pull.rebase = merges.

OfirD
  • 9,442
  • 5
  • 47
  • 90
Schwern
  • 153,029
  • 25
  • 195
  • 336
  • I like this answer bit It misses an important point: never rebase anything you’ve pushed somewhere, see http://www.git-scm.com/book/en/v2/Git-Branching-Rebasing#_rebase_vs_merge – Pino Jul 26 '23 at 10:39
  • @Pino A good rule of thumb, but not to be followed slavishly. So long as everyone is pulling with rebase, there won't be a problem for simple update-via-rebase. – Schwern Aug 07 '23 at 16:01
1

Apart from the technicalities mentioned by @Schwern -

Merging and rebasing are two different things for two different use cases. You cannot compare both of them.

For example -

When you do a git pull, you essentially do a fetch and merge the remote to your local branch.

Rebase is used when remote has moved ahead and so did your local branch, during which you can't directly push your changes to remote. You'll have to do a pull first, not just the pull but pull --rebase to apply each and every commit in the order they were created from both local and remote branch.