Reputation: 131
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
Upvotes: 4
Views: 1338
Reputation: 1305
How many commits you want retain, specify that number in the below command
git rebase -i HEAD~6000
or more precisely
git rebase -i a4f5d18
Retain the 6000 commit from below( as pick) and change the rest of the pick
to squash
if rebase succeeded
git log
You can see all your commits squashes to one commit
and better you push the changes to remote, otherwise when you pull again you will see all commits.
git push -f
Upvotes: 3
Reputation: 131
I ran into trouble with whitespaces, in all three scenarios (interactive rebase, soft reset, rebase onto). Git has the possibility of grafting branches, which developed into the replace function:
git replace -f 5a42d81 a4f5d18
git filter-branch
Upvotes: 0
Reputation: 8656
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.
Upvotes: 3