Search code examples
gitsquashgit-squash

Squashing history commits in a pushed branch


Background

I have a GitHub project I'm currently working on and at the same time I'm learning Git. Today I've read about squashing with rebase command and wanted to try it on some commits that I've pushed a few days ago.

The commits I want to work with are 2b16710 and 32fef8e. On my local repository master branch log looks like this:

* f49573f - (21 hours ago) [#12] Add durability icons - KamilPacanek (origin/enh/12-durability, enh/12-durability)
* 1c9fec4 - (21 hours ago) [#12] Move reactor parts handling to ReactorPanel - KamilPacanek
*   d68bebe - (2 days ago) Merge branch 'enh/7-introducing-clock-ticks' - KamilPacanek (HEAD -> master, origin/master)
|\
| * 2b16710 - (2 days ago) [#7] Refactors - KamilPacanek
| * 32fef8e - (2 days ago) [#7] Implements game ticks - KamilPacanek
|/
*   f699930 - (2 days ago) Merge branch 'enh/28-oper-icons-rework' - KamilPacanek
|\
| * ffb3672 - (2 days ago) [#28] Reactor icon animates when reactor is working - KamilPacanek

As you can see, after the commits I've made a feature branch (enh/12-durability).

What I was trying to do

I've tried the following approach - checkout the master, did an experimental branch and executed following commands to squash the commits.

git rebase -i f699930

I've marked the 2b16710 with fixup and it resulted in the following tree:

* a7641cc - (2 days ago) [#7] Implements game ticks - KamilPacanek (HEAD -> exp-squash)
| * f49573f - (21 hours ago) [#12] Add durability icons - KamilPacanek (origin/enh/12-durability, enh/12-durability)
| * 1c9fec4 - (21 hours ago) [#12] Move reactor parts handling to ReactorPanel - KamilPacanek
| *   d68bebe - (2 days ago) Merge branch 'enh/7-introducing-clock-ticks' - KamilPacanek (origin/master, master)
| |\
|/ /
| * 2b16710 - (2 days ago) [#7] Refactors - KamilPacanek
| * 32fef8e - (2 days ago) [#7] Implements game ticks - KamilPacanek
|/
*   f699930 - (2 days ago) Merge branch 'enh/28-oper-icons-rework' - KamilPacanek
|\
| * ffb3672 - (2 days ago) [#28] Reactor icon animates when reactor is working - KamilPacanek

After that, I've made some diffs to ensure that a7641cc contains the same changes as these two squashed ones and it did.

Next, I've tried to figure out how to merge these changes to my master and finally push to origin to rewrite the history, BUT:

  1. I'm worried about the enh/12-durability branch - I'm the only contributor so I have full control over the process but first I must know how to apply new history to the branch (or maybe I didn't have to as I'm going to merge it with master after work is done)
  2. I don't know why it keeps showing me the tree in such way - I thought the squashing rewrites the commits so instead of two I will have one. So I think I need an explanation whether my understanding is wrong or it will look like that after some force push.

I wanted to achieve something like this (notice there is no 2b16710 commit):

* f49573f - (21 hours ago) [#12] Add durability icons - KamilPacanek (origin/enh/12-durability, enh/12-durability)
* 1c9fec4 - (21 hours ago) [#12] Move reactor parts handling to ReactorPanel - KamilPacanek
*   d68bebe - (2 days ago) Merge branch 'enh/7-introducing-clock-ticks' - KamilPacanek (HEAD -> master, origin/master)
|\
| * 32fef8e - (2 days ago) [#7] Implements game ticks - KamilPacanek
|/
*   f699930 - (2 days ago) Merge branch 'enh/28-oper-icons-rework' - KamilPacanek
|\
| * ffb3672 - (2 days ago) [#28] Reactor icon animates when reactor is working - KamilPacanek

Am I on the right track? I have feeling that I need to cherrypick some of the commits to make it right.. but I don't know.


Solution

  • You created an experimental branch exp-squash and worked on it. So far, only exp-squash's history has been rewritten. master and enh/12-durability are unchanged.

    If you run git rebase -i f699930 on master, the graph will look almost the same, except that HEAD->master will decorate the newly generated commit, supposing abc1234, like this:

    * abc1234 - (2 days ago) [#7] Implements game ticks - KamilPacanek (HEAD -> master)
    | * f49573f - (21 hours ago) [#12] Add durability icons - KamilPacanek (origin/enh/12-durability, enh/12-durability)
    | * 1c9fec4 - (21 hours ago) [#12] Move reactor parts handling to ReactorPanel - KamilPacanek
    | *   d68bebe - (2 days ago) Merge branch 'enh/7-introducing-clock-ticks' - KamilPacanek (origin/master)
    | |\
    |/ /
    | * 2b16710 - (2 days ago) [#7] Refactors - KamilPacanek
    | * 32fef8e - (2 days ago) [#7] Implements game ticks - KamilPacanek
    |/
    *   f699930 - (2 days ago) Merge branch 'enh/28-oper-icons-rework' - KamilPacanek
    |\
    | * ffb3672 - (2 days ago) [#28] Reactor icon animates when reactor is working - KamilPacanek
    

    This way, the history of master is rewritten. Its head moves from d68bebe to abc1234. abc1234 contains the same changes with the squashed 2b16710 and 32fef8e. d68bebe, as a merge commit and without -p, is removed. You don't need to apply or merge abc1234 to master, because it's already on master.

    As to enh/12-durability or any other branches that are created from a commit newer than d68bebe, you can choose not to merge abc1234 to them because they already contain the equivalent changes to those of abc1234 in the history.

    enh/12-durability still contains some commits that belong to the old history of master, 32fef8e, 2b16710 and d68bebe. If you later merge enh/12-durability to the new master, these commits will be introduced to master again. So it's better to rewrite enh/12-durability too.

    git rebase --onto abc1234 d68bebe enh/12-durability
    

    The graph will be like:

    * abc3333 - (21 hours ago) [#12] Add durability icons - KamilPacanek (HEAD->enh/12-durability)
    * abc2222 - (21 hours ago) [#12] Move reactor parts handling to ReactorPanel - KamilPacanek
    * abc1234 - (2 days ago) [#7] Implements game ticks - KamilPacanek (master)
    *   f699930 - (2 days ago) Merge branch 'enh/28-oper-icons-rework' - KamilPacanek
    |\
    | * ffb3672 - (2 days ago) [#28] Reactor icon animates when reactor is working - KamilPacanek
    

    And then you need to force-push master and enh/12-durability to update their counterparts in the remote repository.

    The last graph you want to achieve is impossible. At least you can't keep the commit hashes unchanged after you rewrite the history. Regardless of hashes, it's possible to construct such a graph, with git rebase, or with git reset --hard and git cherry-pick.