I have an SVN history of some 20000 commits. I moved to Git and kept the history. Now i'm at 26000 commits, and I want to squash all commits from 1 to 20000.
I tried checking out 20000 and rebasing:
git checkout 5a42d81
git rebase squash a4f5d18
But i get:
fatal: Needed a single revision
invalid upstream squash
If I understand correctly, your main branch looks like:
master: 1 -> 2 -> 3 -> .. -> 20000 -> A (First non migrated commit) -> B -> C -> ..
And you'd like to get to:
master: 1' (All your migrated commits) -> A' -> B' -> C' -> ..
I think you could follow the approach of using git rebase HEAD~26000 (first commit hash probably easier)
and changing pick
to squash
, but it might be fiddly/time consuming.
One potentially viable solution would be to create a new commit with the contents of your first 20000. Probably worth testing on a backup branch.
git checkout <last migrated commit hash> -b backup-master
backup-master: 1 -> 2 -> 3 -> .. -> [20000] -> A (First non migrated commit) -> B -> C -> ..
^- you are here.
git reset --soft <first migrated commit hash>
backup-master: [1] -> 2 -> 3 -> .. -> 20000 -> A (First non migrated commit) -> B -> C -> ..
^- you are here ^- the working directory tree/index reflects this commit
Amend your initial commit contents/message (or create a new commit if you'd prefer).
git commit --amend
Now backup-master
should contain your squashed migration commits, let's move the new commits.
git checkout master
git checkout -b master-rebase
(just in case we mess something up).
git rebase backup-master
- I believe this will work because git is aware of the merges required to successfully rebase. If this works, you should be done, master-rebase
will contain your desired result.
If this fails, you might have better success with rebase --onto.
git rebase --onto <destination commit> <parent of first desired commit> <last desired commit>
I.e.
git rebase --onto backup-master <A>~1
master`
If this works it will place you on a commit that isn't currently on any branch, so you'll need to create one:
git checkout -b rebase-success
.
A more thorough explanation of rebase --onto can be found here.