0

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} 
Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • Rebase is not squahsing by default. Maybe you are looking for the -i flag where you can edit the rebase list – frlan Dec 21 '16 at 03:04

1 Answers1

2

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.

Schwern
  • 153,029
  • 25
  • 195
  • 336
  • ughh there has to be a way to automatically squash all commits after the SHA given....? I shouldn't have to do it interactively, right? – Alexander Mills Dec 21 '16 at 03:15
  • @AlexanderMills Like I said, `git merge --squash`. Also like I said, I don't use squash myself and don't encourage it, so I can't say much more about it. – Schwern Dec 21 '16 at 03:15
  • ok, but git merge --squash in what context? Seems to be a different context than the one in the question. and if so, please add any explanation you can muster. – Alexander Mills Dec 21 '16 at 03:16
  • @AlexanderMills I don't understand what you're trying to accomplish in your question or why you're squashing. What you're describing is [remote branches](https://git-scm.com/book/en/v2/Git-Basics-Working-with-Remotes) and you'd update `branch1` with a `git pull` or better yet `git pull --rebase`. So maybe update your question with why you decided to squash? – Schwern Dec 21 '16 at 03:21
  • I am doing a whole bunch of small changes to a branch, but when I merge with master I want to squash all the local meaningless commits into one big meaningful commit; I thought that this was fairly standard practice? – Alexander Mills Dec 21 '16 at 03:27
  • @AlexanderMills Depends on what you mean by "meaningful". – Schwern Dec 21 '16 at 03:28
  • allow me to define that for myself :) – Alexander Mills Dec 21 '16 at 03:28
  • @AlexanderMills No, define it for the person reading your code months or years from now trying to figure out why it's written the way it is. Anyhow, just use `git merge --squash` same as you would any other merge. – Schwern Dec 21 '16 at 03:31
  • well, I wanted to use rebase - git merge often times introduces pointless conflicts. What I am doing would actually be quite clever if it worked. I have two branches like the original question - instead of checking out branch2 and then merging with branch1 and squashing in the process.... Pardon my French, but F that noise - because there will be time-wasting conflicts. Instead, just find the most recent shared commit between the two branches and then delete branch2 and make a copy of branch1 into branch2 and then rebase it, squashing it in the process. But apparently can't squash with rebase? – Alexander Mills Dec 21 '16 at 03:34
  • @AlexanderMills If you're getting so many conflicts, something is wrong. Maybe you should ask a question about that. – Schwern Dec 21 '16 at 03:35
  • It might be JavaScript, but there are a lot of conflicts if you do nothing on branch2 but make changes to branch1 and then try to merge them, seen it a lot, not sure why. Rebase should work as I described, if you can do it interactively, you should be able to do it non-interactively too, no? I might go back and try git merge again but it was causing a lot of headache and I wanted to avoid it, the merge is pointless in this case, I just want to squash, not merge anything. I *just* need to know how far down to squash, that's it! :) – Alexander Mills Dec 21 '16 at 03:36
  • @Schewrn - the most annoying conflicts happen when I delete or rename files in the feature branch and then try to merge that back into development, this seems to always give unncessary conflicts. I am using git rm x, and still conflicts. When you want to continuously deliver, two or three times a day, these are major annoys. – Alexander Mills Dec 21 '16 at 04:45
  • @AlexanderMills Ask it as a question with details and I'll see what I can do. – Schwern Dec 21 '16 at 18:08