Skip to main content
another approach that is actually much simpler than using reset soft or rebase.
Source Link
eftshift0
  • 28.8k
  • 4
  • 45
  • 71

My personal favorite is using git reset --soft.

So, say you want to squash from HEAD~1000 up to this point (HEAD~1000 being the last surviving commit that won't be squashed):

git reset --soft HEAD~1000
git commit -m "Squashed a lot of stuff"

That's it. You can use a revision ID instead of using HEAD~n references.

I see that you want to do it like by segments.... so, say.... let's squash HEAD~400 to HEAD~200... then from HEAD~200 to HEAD~100... then from HEAD~100 to HEAD. So, let's create a temp branch where we will do our work.

git checkout -b temp HEAD~200
git reset --soft HEAD~400
git commit -m "squashing first segment"
# next segment
git checkout the-original-branch~100
git reset --soft temp
git commit -m "Second segment"
git branch -f temp #set temp over here
# final segment
git checkout --detach the-original-branch
git reset --soft temp
git commit -m "Final segment"
git branch -f temp #set temp over here
# if you like the result, feel free to move whatever branch over here
git branch -f whatever-branch
# and delete temp if so you want
git branch -D temp

Very easy, I think.

After one day, I just realized (by answering another question) that it can be done in a much simpler way:

git branch -f temp $( git commit-tree -p HEAD~400 -m "first squash" HEAD~200^{tree} )
# that set up temp on the first squash
git branch -f temp $( git commit-tree -p temp -m "second squash" HEAD~100^{tree} )
# temp has move to second squash
git branch -f temp $( git commit-tree -p temp -m "final squash" HEAD^{tree} )

Now temp has the squashed commits the way it was requested in my example. Feel free to do a reset --hard over there (the usual warning when using reset --hard).

My personal favorite is using git reset --soft.

So, say you want to squash from HEAD~1000 up to this point (HEAD~1000 being the last surviving commit that won't be squashed):

git reset --soft HEAD~1000
git commit -m "Squashed a lot of stuff"

That's it. You can use a revision ID instead of using HEAD~n references.

I see that you want to do it like by segments.... so, say.... let's squash HEAD~400 to HEAD~200... then from HEAD~200 to HEAD~100... then from HEAD~100 to HEAD. So, let's create a temp branch where we will do our work.

git checkout -b temp HEAD~200
git reset --soft HEAD~400
git commit -m "squashing first segment"
# next segment
git checkout the-original-branch~100
git reset --soft temp
git commit -m "Second segment"
git branch -f temp #set temp over here
# final segment
git checkout --detach the-original-branch
git reset --soft temp
git commit -m "Final segment"
git branch -f temp #set temp over here
# if you like the result, feel free to move whatever branch over here
git branch -f whatever-branch
# and delete temp if so you want
git branch -D temp

Very easy, I think.

My personal favorite is using git reset --soft.

So, say you want to squash from HEAD~1000 up to this point (HEAD~1000 being the last surviving commit that won't be squashed):

git reset --soft HEAD~1000
git commit -m "Squashed a lot of stuff"

That's it. You can use a revision ID instead of using HEAD~n references.

I see that you want to do it like by segments.... so, say.... let's squash HEAD~400 to HEAD~200... then from HEAD~200 to HEAD~100... then from HEAD~100 to HEAD. So, let's create a temp branch where we will do our work.

git checkout -b temp HEAD~200
git reset --soft HEAD~400
git commit -m "squashing first segment"
# next segment
git checkout the-original-branch~100
git reset --soft temp
git commit -m "Second segment"
git branch -f temp #set temp over here
# final segment
git checkout --detach the-original-branch
git reset --soft temp
git commit -m "Final segment"
git branch -f temp #set temp over here
# if you like the result, feel free to move whatever branch over here
git branch -f whatever-branch
# and delete temp if so you want
git branch -D temp

Very easy, I think.

After one day, I just realized (by answering another question) that it can be done in a much simpler way:

git branch -f temp $( git commit-tree -p HEAD~400 -m "first squash" HEAD~200^{tree} )
# that set up temp on the first squash
git branch -f temp $( git commit-tree -p temp -m "second squash" HEAD~100^{tree} )
# temp has move to second squash
git branch -f temp $( git commit-tree -p temp -m "final squash" HEAD^{tree} )

Now temp has the squashed commits the way it was requested in my example. Feel free to do a reset --hard over there (the usual warning when using reset --hard).

added 856 characters in body
Source Link
eftshift0
  • 28.8k
  • 4
  • 45
  • 71

My personal favorite is using git reset --soft.

So, say you want to squash from HEAD~1000 up to this point (HEAD~1000 being the last surviving commit that won't be squashed):

git reset --soft HEAD~1000
git commit -m "Squashed a lot of stuff"

That's it. You can use a revision ID instead of using HEAD~n references.

I see that you want to do it like by segments.... so, say.... let's squash HEAD~400 to HEAD~200... then from HEAD~200 to HEAD~100... then from HEAD~100 to HEAD. So, let's create a temp branch where we will do our work.

git checkout -b temp HEAD~200
git reset --soft HEAD~400
git commit -m "squashing first segment"
# next segment
git checkout the-original-branch~100
git reset --soft temp
git commit -m "Second segment"
git branch -f temp #set temp over here
# final segment
git checkout --detach the-original-branch
git reset --soft temp
git commit -m "Final segment"
git branch -f temp #set temp over here
# if you like the result, feel free to move whatever branch over here
git branch -f whatever-branch
# and delete temp if so you want
git branch -D temp

Very easy, I think.

My personal favorite is using git reset --soft.

So, say you want to squash from HEAD~1000 up to this point (HEAD~1000 being the last surviving commit that won't be squashed):

git reset --soft HEAD~1000
git commit -m "Squashed a lot of stuff"

That's it. You can use a revision ID instead of using HEAD~n references.

My personal favorite is using git reset --soft.

So, say you want to squash from HEAD~1000 up to this point (HEAD~1000 being the last surviving commit that won't be squashed):

git reset --soft HEAD~1000
git commit -m "Squashed a lot of stuff"

That's it. You can use a revision ID instead of using HEAD~n references.

I see that you want to do it like by segments.... so, say.... let's squash HEAD~400 to HEAD~200... then from HEAD~200 to HEAD~100... then from HEAD~100 to HEAD. So, let's create a temp branch where we will do our work.

git checkout -b temp HEAD~200
git reset --soft HEAD~400
git commit -m "squashing first segment"
# next segment
git checkout the-original-branch~100
git reset --soft temp
git commit -m "Second segment"
git branch -f temp #set temp over here
# final segment
git checkout --detach the-original-branch
git reset --soft temp
git commit -m "Final segment"
git branch -f temp #set temp over here
# if you like the result, feel free to move whatever branch over here
git branch -f whatever-branch
# and delete temp if so you want
git branch -D temp

Very easy, I think.

Source Link
eftshift0
  • 28.8k
  • 4
  • 45
  • 71

My personal favorite is using git reset --soft.

So, say you want to squash from HEAD~1000 up to this point (HEAD~1000 being the last surviving commit that won't be squashed):

git reset --soft HEAD~1000
git commit -m "Squashed a lot of stuff"

That's it. You can use a revision ID instead of using HEAD~n references.