git rebase <SHA1> does not seem to squash commits

655 views Asked by At

I have two branches. branch1 has the latest changes, the other (branch2) contains the most recent changes that are on the remote.

So what I do is I get the most recent shared commit like so:

SHA=$(git merge-base branch1 branch2)

then I run rebase

git checkout branch1
git rebase ${SHA} 

the problem I am having is that this doesn't appear to be squashing commits on branch1. Should it be squashing commits and my synopsis is wrong?

When you use rebase with the interactive option, you specify whether or not to squash a commit.

I am wondering if maybe I need to use some option like so with the rebase command

git rebase -s ${SHA} 

or maybe

git rebase --autosquash ${SHA} 
1

There are 1 answers

13
Schwern On BEST ANSWER

Should it be squashing commits and my synopsis is wrong?

No, by default it does not.

Conceptually, rebasing is like pretending a branch was always on top of another commit. For example, here we have a feature branch that's fallen out of date.

A - B - C - D - E [master]
         \
          F - G - H [feature]

We could git merge master but then there will be messy merge commits. Instead, we can rewrite feature as if it were always on the tip of `master.

  • git checkout feature
  • git rebase master

Now we have...

                  F1 - G1 - H1 [feature]
                 /
A - B - C - D - E [master]
         \
          F - G - H

Note that the old branch is still there, it will eventually be cleaned up.


Instead what you're looking for is git merge --squash.

I do not recommend squashing branches as it loses important history that is useful for code archeology (ie. figuring out why thing were written that way). Keep squashing only for removing trivial commits like typo fixes.

Instead, I'd recommend "feature bubbles". Rebase the branch as above, then git merge --no-ff (this forces Git to merge rather than fast-forward). This results in...

                  F1 - G1 - H1
                 /            \
A - B - C - D - E ------------ I [master]

You get linear history (git log will show I, H1, G1, F1, E, D, ...), you retain detailed commit information, that F1, G1, and H1 are related, and the commit message of I can be used to describe what the branch was about.