2

So I fork, then branch, and commit code. Now I have 15 commits of my work I need to squash into one.

So first I pull in a merge the upstream code.

git fetch upstream master
git merge upstream/master master

Then I try an squash the last 15 commits on the branch I'm on (not on master)

git rebase -i HEAD~15

Now I have hundreds of commits show up that are completely unrelated to my branch. All the tutorials online are very basic and I'm assume it should be doing it slightly differently in the forked workflow.

What am I missing?

3
  • Would you mind doing three things so I can help you: 1.) On your current branch grab output of "git log --date-order --pretty="%h|%p|%d" HEAD~15..HEAD". 2.) Paste said output into the tool here bit-booster.com/graph.html 3.) Attach a screenshot of the generated graph to your question. Commented Aug 17, 2016 at 22:55
  • Here is the graph imgur.com/a/384R3 Commented Aug 23, 2016 at 21:24
  • Is that really coming from "git log --date-order --pretty="%h|%p|%d" HEAD~15..HEAD"? That might make sense if the highest green dot was HEAD on your forked branch. Is it? Commented Aug 24, 2016 at 4:58

2 Answers 2

1

I think you would want to squash on the way into the destination branch, not within it (generally). So if you have a branch of changes and are looking to squash them into master, there are a couple of options depending on your workflow.

CLI

# while on master
$ git merge my-feature-branch --squash

Github

In Github you have the choice to squash merge when you merge the PR https://github.com/blog/2141-squash-your-commits

Bitbucket / Stash

They do this automatically for you.

0

The behavior of git rebase -i is different when you have merges in the subset of commits under rebase and if you don't have. In your case, you first merged, and then you want to rebase on a subset of commits which contains merges.

Generally, I avoid rebasing merge commits to keep things simple.

As @thescientist said, in you case, it's better to squash commits at merge time than after the merge.

One remark that might be helpful:

Normally when you invoke git rebase -i on a linear history, you see your list of commits, and you don't change anything (just keep pick), no operation will happen, and no history will be rewritten

However, when you find yourself accidentally running git rebase -i on a too big subset of commits, which involves merge commits, you will often see a big list of commits, and if you don't change anything (keep pick), git will start rewriting those commits, which is most often not something you wanted. To escape from this situation, delete all the lines; normally when some lines are deleted during rebase, git removes the commits corresponding to those lines, but if you remove all lines, git will do nothing - which is a helpful way to abort when you messed up something - because if you wanted to drop all commits, you'd use git reset --hard <desired_commit>.

Not the answer you're looking for? Browse other questions tagged or ask your own question.