Mastering git, Part 12, git rebase

Combining Git commits with squash

Imagine you have done lots of commits, i.e. several commits for fixing a bug, but you don’t need all of them, and somehow you want to meld them and squash them into a single commit. You can use rebase. Git always squashes a newer commit into an older commit or “upward”. Let’s create some files:

Your tree would be something like this:

But now you would like to squash b-1, b2 and b-3 into one commit. So copy the hash ID of b-3 and execute rebase:

This will open your editor and the first few lines are:

Git will melt new commits into older ones, and we want to squash b-3 and b-2 into b-1 so change it into:

Close all instances of your editor and save them. This will open another editor to write a new commit message.

Write your new commit message and save it. Your new tree should look like this:

Squashing commits in git after push

Squash the commits locally (for the last N commits) :

force push them with + :

Refs: 1

Difference between --force and +:

Note that --force applies to all the refs that are pushed, hence using it with push.default set to matching or with multiple push destinations configured with remote.*.push may overwrite refs other than the current branch (including local refs that are strictly behind their remote counterparts). To force a push to only one branch, use a + in front of the refspec to push (e.g git push origin +master to force a push to the master branch).

Refs: 1

Rebasing branches onto the base

When you create a feature branch and start working on that, your master might grow and also your branch. Let’s create a repository and add “a” and b:

Then let’s create a feature branch for “c”

Now let’s get back to master and “d” and “e”:

 

At a certain point, you will decide to merge with the master branch, and your tree looks like this:

By doing this you will the following tree, which in a big project might become very complicated and difficult to track.

As you can see, the branch feature-c is 2 commits behind of the master branch.  You can rebase your feature branch onto the master branch, so you can make it as your feature branch has just branched from your master.

By doing so, you finally end up with a “linear history”. You can also give tags to your commits so you make your tree more readable:

If you want git to do a rebase instead of a merge when pulling:

or you can set it as the default action in your gitconfig file:

Rebase with a merge conflict

Let’s create a repository:

And create a feature branch and modify some files and add some files:

Now let’s switch back to master and update some files that have been updated in the feature branch:

Now let’s switch back to the feature branch and rebase it on master:

Since you have modified a and b you will get a merge conflict:

Now we have to resolve the merge conflict:

Since you have modified a and b you will get a merge conflict:

Now since you are rebasing on master, the changes from the feature branch are remote and master is local:

since we had a merge conflict on the file “a” git will create a file named “a.orig”, after resolving the conflict, we delete this file and continue by:

 

Rebase remote branch onto master

What if we have had pushed our changes into remote? On that occasion, you should “Rebase remote branch onto master”

This will remove your local feature-c repository, update references, and change to feature-c branch, but because you deleted it, this command will also download the origin/feature-c

Refs: [1]

 

Rebase: rewriting Git history reword, delete, reorder  and Split

Refs 1,2, 3, 4

0 0 votes
Article Rating
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x