steprobe
steprobe

Reputation: 1699

Git rebasing interactive not squashing when fast forward available

I have a branch from master with three changes and want to rebase it back on to master. For example:

$git checkout master
$git branch dev && git checkout dev
$<do 3 commits>
$git checkout master
$git rebase dev -i

Normally -i would give me the 3 commits and allow me to squash. In this case however it is just "noop" and when the rebase completes I see the three commits moved over to master. I guess here though, as the ancestor had not diverged, a fast forward was possible and so this is what happened. But I want to squash the commits.

I tried using --no-ff but it does exactly the same as in my original case (noop + no squashing).

I tried also doing (while on the dev branch)

$git rebase -i HEAD~3
$git checkout master
$git rebase dev

But this is a pain really and I have to know how many commits to squash for the HEAD~X part.

Footnote: The reason this is important to me is that it is this squashed changeset that will be reviewed in gerrit. If they are separate, it makes reviewing impossible.

Upvotes: 2

Views: 1657

Answers (1)

Mark Longair
Mark Longair

Reputation: 467741

I'm not quite sure why you're doing some of the things in your question, e.g. don't you really mean $git branch dev && git checkout dev before you do the commits? With your version you're just creating them on master anyway. (Incidentally, if I'm right, you can do git checkout -b dev as a shortcut.)

The reason you just get a noop is that git rebase tries to reapply all the commits in the current branch that aren't in the branch that you supply as the <upstream> argument. So, when you do git rebase -i dev while on master, there are no commits in master that aren't on dev. Essentially, you want to do it the other way round. I would do the following:

git checkout dev
git rebase -i master
[... change to 'squash' all but the first of the actions ...]

Then your dev branch will just have one squashed commit and you can merge that into master if you like.

Alternatively, you could use git merge --squash:

git checkout master
git merge --squash dev
git commit -m "The changes from dev squashed into one commit"

Then master will have a single new commit, which represents the result of merging dev into master squashed into one commit, and that new commit will only have one parent, rather than being a merge commit.

Upvotes: 3

Related Questions