0

Let's say I have several consecutive commits, we name them A0..A99 for simplicity, pushed by the same author to the main branch: these commits are not the last commits pushed to the main branch as other commits were pushed on top of those by other authors.

I wish to alter the main branch history such as A0..A99 commits are condensed into one single commit, hence, from A0..A99 to just A, essentially similar to a git squash and merge if these commits were to be squashed and merged on top of my main branch, but with the added complexity that all commits and changes pushed after A0..A99 still need to be preserved.

The intent is to cleanup the branch history as these A0..A99 commits were supposed to be squashed and merged, but they were just all merged to the main branch.

As an additional factor to consider, this Git repository is hosted on GitHub and we use GitHub Releases, meaning that each release/tag is associated to the commit hash it was created from, therefore I need to make sure this doesn't break my existing releases or at least find a way to fix them in the event that commit hashes are regenerated: not sure that is actually the case, just considering the possibility and the impact it would have on my releases in GitHub.
Anyhow, it is safe to assume that no release was ever done in between commits A0..A99.

How can I do that?
Thanks.

1
  • 2
    in the event that commit hashes are regenerated -> They will be if you rewrite history as you describe, no doubt. No way to change older history but keep children commits with their hashes. Commented Mar 29, 2023 at 13:05

1 Answer 1

2

I am not going to care for other things than modifying history of the branch to match your request... other considerations, you will have to dig on your side.

This can be done with a rebase... but I would not like to modify 100 lines saying pick for squash so I would use restore:

git checkout -b temp A0~ # I am standing on the commit before the one where I would like to start to squash
git restore --staged --worktree --source=A99 -- . # get the project as it is in commit A99
git commit -m "Here is the squash commit for A0..A99"
# now let's apply all the things that are on top of A99
git rebase A99 some-branch --onto HEAD # some-branch might be master or main or well, the branch you care about
# now you have a history like the one you want

You might take temp and force-push it into the branch you want to replace:

git push origin -f temp:main # supposing you want to replace main

Warning: this is rewriting history.... it's very simple to do but if other people are already using stuff from the old branch, it will be a PAIN to get people to jump on the new branch (it's actually very simple to do that as well, but people complain about it so I am just leaving the warning).

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