1

Let's say I have a project with so many commits that manually rebasing from the beggining is impossible. Let's also say that there are no branches or tags, only master. Let's also say that there are some merge commits, but probably too many to manually merge them or even track them.

My question is: How can I squash all commits from the very first commit up to commit XYZ into a single commit?

Graphical representation of what I want to convert:

             /--R--T--Y---\
A--B--C--D--/--G--H--J--K--\---Q--X--Z---....

should look like:

--<I don't care how you will do it git, just put everything from everywhere in a single commit here>----Q---X---Z.....

Is that possible?

alexandernst
  • 14,352
  • 22
  • 97
  • 197

1 Answers1

1

Checkout a new branch from the desired start point.

git checkout D

git checkout -b myNewBranch

Use git merge --squash K

You can then commit with a new message all of the changes from the merge.

Following that, in Git 1.7.2 and up you can cherry-pick a range to bring across the other commits.

git cherry-pick Q^..Z

Community
  • 1
  • 1
bcmcfc
  • 25,966
  • 29
  • 109
  • 181
  • Should I run the merge on the master or in the branch? – alexandernst Jul 23 '14 at 14:55
  • Is the end result that you want to essentially replace `master` with a new `master`? In which case it doesn't really matter. You can always just delete the master branch and rename the temporary one after you've confirmed that the branch contains what you want it to. – bcmcfc Jul 23 '14 at 14:56
  • Ok, I did it, but now the test branch contains a single commit from A to D/K. Q, X and Z are missing. How do I merge those too? – alexandernst Jul 23 '14 at 15:02
  • How many commits are we talking about here? If there's only a few, `git cherry-pick` is the way to go (specifying each one manually). – bcmcfc Jul 23 '14 at 15:04
  • Well, not sure, but around 50. – alexandernst Jul 23 '14 at 15:04
  • Hmm - http://stackoverflow.com/questions/1670970/how-to-cherry-pick-multiple-commits - depending on the version of Git, you can cherry pick a range. That's pretty neat. `git cherry-pick Q..Z`. – bcmcfc Jul 23 '14 at 15:04
  • So close... one of the commits failed because (I'm guessing) the commit had tons and tons of renames/removes. How can I tell git to take it's time and do it? – alexandernst Jul 23 '14 at 15:11
  • Is it Q that failed? The syntax is a bit odd and doesn't match other git commands using `..` in that it doesn't include the first commit specified, and you instead have to use `Q^..Z`. – bcmcfc Jul 23 '14 at 15:13
  • No, it wasn't Q. It was a commit somewhere between Q and Z (the 7th or so) – alexandernst Jul 23 '14 at 15:14
  • It's not working with the `^` either, but it did got a little bit further! – alexandernst Jul 23 '14 at 15:16
  • I'm guessing it's because the missing commit is in itself a merge. It's a bit complicated this, and for good reason. Messing with history in this way isn't necessarily a good thing. – bcmcfc Jul 23 '14 at 15:17