gitgit-mergesquash

Squashing unrelated history merges


I have just been messing around with some other repos and doing some git merge --allow-unrelated-histories:

merge graph

I now want to squash these together such that they are all part of the same history. (specifically merge branch 'temp' to the bottom Initial commit into one commit)

If squashing is not an option, what is the best course of action?

I'm happy to lose parts of the history after this point, but ideally I don't want to have to resort to manually copying the state of the repository at different points and recreating new commits for them.


Solution

  • Assuming that the branch where temp has been merged into is called master, and that what you want is to have temp's history squashed as a single commit and be the root of master, you could:

    1. Create a backup copy of master just for safety (master_backup).

    2. Hard reset master to the commit Add rehype mermaid to void the current unrelated-history merge.

    3. Create a copy of temp (temp_copy), soft reset it to its first commit, and amend the current commit to squash temp_copy's history into a single commit.

    4. Rebase master on top of temp_copy.

    5. Optionally, delete temp_copy.

    # make sure to be on the temp branch
    git checkout temp
    
    # create a backup of the master branch
    git branch master_backup master
    
    # force the master ref to point to the commit "add rehype mermaid"
    git branch --force master <add_rehype_mermaid_commit_id>
    
    # create the branch temp_copy and switch to it
    git checkout -b temp_copy
    
    # soft reset temp_copy to its initial commit. This version of reset, keeps 
    # all changes in both the working directory and the index. Like so, the changes
    # are ready to be committed for the next command.
    git reset --soft <initial_commit_on_temp_copy>
    
    # amend the initial commit to squash all changes in temp_copy's history 
    # into a single commit
    git commit --amend
    
    # rebase master on top of temp_copy
    git rebase master --onto temp_copy --root
    
    # optionally, delete the branch temp_copy
    git branch -d temp_copy