Git: Interactive Rebasing II

Adding on the things we saw in the last article, let us look at an example with an unwantedly complicated repository as usual.

As usual the tree of the repository is

*   fd45d7b (HEAD -> bugfix) merged...
|\  
| * 86f0dc2 (bugfix2) changed line 4
* | 21a556e changed line 4
|/  
*   88d5446 Merge branch 'bugfix2' into bugfix
|\  
| * 57658fe added line 3
* | 621d9f9 added line 4
|/  
*   7b9cd5e merged
|\  
| * aa43a83 added 1 line
* | 00f07af added 2 lines
|/  
* ad9631e commit 13
* ebc508e commit 12
* 0e180e8 commit 9
* 79d8019 commit 8
* 75d11f0 commit 7
* f6338e0 (master) Sixth commit
* 5c0595d fifth file
* b4798cb Fourth commit
* 71764ed fajfgj
* 677358d second file
* d6ed37b first file

Let us try all of the options that we saw in the previous article during an interactive rebase.

$ git rebase -i 0e180e8


pick ebc508e commit 12
reword ad9631e commit 13
edit 00f07af added 2 lines
squash aa43a83 added 1 line
fixup 621d9f9 added line 4
exec git log --oneline --graph --decorate
drop 57658fe added line 3
pick 21a556e changed line 4
pick 86f0dc2 changed line 4

So let us go through what we expect from this ,

  1. pick ebc508e commit 12

    This line does not change anything, it picks the commit as is. So no worries

  2. reword ad9631e commit 13

    This line tells git to stop for changing the commit message. So it should provide an interface to change the commit message

  3. edit 00f07af added 2 lines

    This line tells git to stop for editing the commit.

  4. squash aa43a83 added 1 line

    We saw what squashing a commit is ! This should tell git to merge this commit’s changes with the previous commit.

  5. fixup 621d9f9 added line 4

    Similar to squashing , let us see what different happens..

  6. exec git log –oneline –graph –decorate

    This line should print the graph at that particular instant and move on

  7. drop 57658fe added line 3

    This commit will be removed.

So lets get ready to see what happens, when we try this. ( Save and exitting vim after changing those lines )

Immediately after i save and exit, git starts processing all the requests from the top.

* Pick happens in an instant without even giving us time to notice that ( mostly ).

* Git now stops for reword and opens up an editor ( in my case vim ).
Reword
Renamed

* After the previous step, as we expected git processes the edit line now and shows these messages now.

[detached HEAD 7600aba] commit 13 ___ renamed
 Date: Sun May 27 12:25:42 2018 +0530
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file10
Stopped at 00f07afc1f72421bf6c98293813d57509b5b3744... added 2 lines
You can amend the commit now, with

	git commit --amend 

Once you are satisfied with your changes, run

	git rebase --continue

The first 4 output lines are for reword operation ( previous one ). The lines that follow are for editing the commit. As we see, edit can not only change the message but can also be used to change the contents of the commit. We can even add additional commits inbetween. Let me add a file and amend this commit and also add a new commit inbetween , just to see what are the possibilities. 😛

On doing these

$ touch file11
$ git commit --amend

Commit amend

Further let us add a commit

$ touch file12
$ git add file12
$ git commit -m "on the middle commit"
[detached HEAD 75b9697] on the middle commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file12

So after tampering/changing the repository to our heart’s content, when we decide to stop the editing we should do what git said us when it stopped for editing..

Once you are satisfied with your changes, run `git rebase –continue`

So lets do that.

$ git rebase --continue
error: could not apply aa43a83... added 1 line

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

Could not apply aa43a83b74d0d025efff8229481a3b09a9f7cc7e... added 1 line

scared

Oh oh ! Something wrong happened … By reading we can understand that, git has completed the edit operation and now is stuck with squash operation somehow… Lets see what it is.. When some problem arises like this, our first tool should be `git mergetool` ( atleast mine ), because during rebase, it is normal for git to endup in a dilemma . So in those situations, git asks us to take control.

$ git mergetool

This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc codecompare emerge vimdiff
Merging:
file6

Normal merge conflict for 'file6':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (meld):

Picture of mergetool in action

The problem was commit to be squashed i.e. aa43a83 , has a different version of the file6 , so while squashing git got confused whether to use the file6 of 00f07af or from aa43a83 . As we as we solve this using mergetool , we can use git rebase –continue to proceed.

$ git rebase --continue

So now squash takes control …

Squash - Before changing commit message

We can choose to modify it or leave it alone.. I am going to change it..

$ git rebase --continue
[detached HEAD ec8e633] squashing.... on the middle commit|----|added 1 line
 Date: Sun Jun 24 19:48:52 2018 +0530
 2 files changed, 2 deletions(-)
 create mode 100644 file12

error: could not apply 621d9f9... added line 4

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

Could not apply 621d9f9365ab058022495da4640baad2009a8571... added line 4

Next comes fixup.. Again a conflict 😦

The same way i am going to solve it through git mergetool…

After , ‘git rebase –continue’

Fixup

Now , what is the difference ? During squash, it showed us both the messages uncommented.. But now it has only the first one uncommented, while the other messages are commented. So based on the requirement, we can use these.. I am not going to alter this time..

After saving,

$ git rebase --continue
[detached HEAD dbb3365] squashing.... on the middle commit|----|added 1 line
 Date: Sun Jun 24 19:48:52 2018 +0530
 2 files changed, 2 insertions(+), 1 deletion(-)
 create mode 100644 file12
Executing: git log --oneline --graph --decorate
* dbb3365 (HEAD) squashing.... on the middle commit|----|added 1 line
* 417745f added 2 lines
* 7600aba commit 13 ___ renamed
* ebc508e commit 12
* 0e180e8 commit 9
* 79d8019 commit 8
* 75d11f0 commit 7
* f6338e0 (master) Sixth commit
* 5c0595d fifth file
* b4798cb Fourth commit
* 71764ed fajfgj
* 677358d second file
* d6ed37b first file
error: could not apply 86f0dc2... changed line 4

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
Could not apply 86f0dc2ed82ab8f6568f190890ed69af293baabd... changed line 4

So fixup worked… Next in line is exec…

exec should execute ‘git log –oneline –graph –decorate’. Well it happened.. And then drop … It happened ( where is the message ?? )..
And yet another conflict…

As we solve the conflict yet another time, git converts pick into edit as we can see here.. It asks for a new message for the commit now

Pick turning into edit

As we save this… All good now… 🙂 . Git finished the other “pick”s and successfully completed this rebase..

$ git rebase --continue
[detached HEAD f1c2315] changed line 4
 1 file changed, 2 insertions(+), 2 deletions(-)
Successfully rebased and updated refs/heads/bugfix.
$ gl
* f1c2315 (HEAD -> bugfix) changed line 4
* 88a195f changed line 4
* dbb3365 squashing.... on the middle commit|----|added 1 line
* 417745f added 2 lines
* 7600aba commit 13 ___ renamed
* ebc508e commit 12
* 0e180e8 commit 9
* 79d8019 commit 8
* 75d11f0 commit 7
* f6338e0 (master) Sixth commit
* 5c0595d fifth file
* b4798cb Fourth commit
* 71764ed fajfgj
* 677358d second file
* d6ed37b first file

Now as we can see the tree has completely changed…it has straightened out with the changes that we made. Although it is one of the biggest dangers of git rebase , because any branch diverging from this branch will forever lose its reference and it cant be merged into this branch again . This is one of the problems of using rebase aggressively. We will discuss more problems in future posts. ‘git rebase’ can be used effectively inorder to maintain a straight and clean commit structure.

Moving on

In the future article, let us move on to the dangers of rebase and how not to use rebase in a shared repository.

1 thought on “Git: Interactive Rebasing II”

Leave a reply to Git – The Swiss Army Knife of Version Control – An Introduction – Linux from a newbie Cancel reply