Git merge, merge-squash and rebase simplified
Starting the repository with basic files
Lets create an empty repository and commit a file to the master branch:
$ git init
$ touch m1
$ git add m1
$ git commit -m "m1"
Now we switch to a new branch named feature:
$ git checkout -b feature
Is time to create a file in the feature branch and commit it:
$ touch f1
$ git add f1
$ git commit -m "f1"
Now let's go back to the master and create another file :
$ git checkout master
$ touch m2
$ git add m2
$ git commit -m "m2"
If we type $ git log
we will see this :
* 60c3a2b - (1 second ago) m2 - Hector (HEAD -> master)
| * 7832858 - (87 seconds ago) f1 - Hector (feature)
|/
* 0a950f5 - (5 minutes ago) m1 - Hector
Integrating changes from master to feature branch
Up to now we have one simple feature branch with a commit and two commits in the master branch, it is a common practice to integrate the commits from the master branch to our feature in order to avoid losing track of master changes, but there are a few ways to do it :
- Git merge
$ git checkout feature
$ git merge master
This is a non-destructive way, branches keep preserved its history and only a merge commit appears :
* fad9250 - (11 seconds ago) Merge branch 'master' into feature - Hector (HEAD -> feature)
|\
| * 60c3a2b - (5 minutes ago) m2 - Hector (master)
* | 7832858 - (7 minutes ago) f1 - Hector
|/
* 0a950f5 - (11 minutes ago) m1 - Hector
- Git merge --squash
$ git checkout feature
$ git merge --squash master
$ git commit -m "Squash"
This is a non-destructive way as well, branches keep preserved its history but now no merge commit appears, all the changes in master are grouped into 1 commit named Squash in my case and appears as as a single commit in the feature branch, as you can see :
* dc4e5b7 - (10 seconds ago) Squash - Hector (HEAD -> feature)
* 7832858 - (19 minutes ago) f1 - Hector
| * 60c3a2b - (18 minutes ago) m2 - Hector (master)
|/
* 0a950f5 - (23 minutes ago) m1 - Hector
- Git rebase
$ git checkout feature
$ git rebase master
With rebase instead, the history will be simpler, what it does in high-level words is to search for the last common commit and add master commits upon it but below our branch commits.
As you can see m2 commit is upon m1 (last common commit in both branches) and below f1 (our feature branch commit)
* 6074794 - (11 minutes ago) f1 - Hector (HEAD -> feature)
* 60c3a2b - (10 minutes ago) m2 - Hector (master)
* 0a950f5 - (15 minutes ago) m1 - Hector
Integrating changes from feature branch to master
Let's suppose we integrate master changes to feature branch with merge and we add some few changes to both branches, m3 and f2 resulting to this log :
* 83c98e1 - (1 second ago) m3 - Hector (HEAD -> master)
| * 0a3663c - (2 minutes ago) f2 - Hector (feature)
| * edfda02 - (2 minutes ago) Merge branch 'master' into feature - Hector
| |\
| |/
|/|
* | 60c3a2b - (29 minutes ago) m2 - Hector
| * 490a167 - (3 minutes ago) f1 - Hector
|/
* 0a950f5 - (35 minutes ago) m1 - Hector
As before, we have the same 3 options :
- Git merge
If we do a $ git merge feature
it will result as it follows :
* d6b643b - (4 seconds ago) Merge branch 'feature' - Hector (HEAD -> master)
|\
| * 0a3663c - (4 minutes ago) f2 - Hector (feature)
| * edfda02 - (4 minutes ago) Merge branch 'master' into feature - Hector
| |\
| * | 490a167 - (4 minutes ago) f1 - Hector
* | | 83c98e1 - (2 minutes ago) m3 - Hector
| |/
|/|
* | 60c3a2b - (31 minutes ago) m2 - Hector
|/
* 0a950f5 - (36 minutes ago) m1 - Hector
- Git merge --squash
If we do a squash :
$ git merge --squash feature
$ git commit -m "Squash"
With the behaviour expected, not a merge commit and non-destructive history we get :
* 63f7387 - (10 seconds ago) Squash - Hector (HEAD -> master)
* 83c98e1 - (3 minutes ago) m3 - Hector
| * 0a3663c - (5 minutes ago) f2 - Hector (feature)
| * edfda02 - (5 minutes ago) Merge branch 'master' into feature - Hector
| |\
| |/
|/|
* | 60c3a2b - (32 minutes ago) m2 - Hector
| * 490a167 - (5 minutes ago) f1 - Hector
|/
* 0a950f5 - (37 minutes ago) m1 - Hector
- Git rebase
Finally, let's test what would happen with $ git rebase feature
we obtain the following log :
* 6c6ba0e - (5 minutes ago) m3 - Hector (HEAD -> master)
* 0a3663c - (7 minutes ago) f2 - Hector (feature)
* edfda02 - (7 minutes ago) Merge branch 'master' into feature - Hector
|\
| * 60c3a2b - (35 minutes ago) m2 - Hector
* | 490a167 - (8 minutes ago) f1 - Hector
|/
* 0a950f5 - (40 minutes ago) m1 - Hector
Rebase takes the last common commit, which is the merge commit and add places the f2 commit upon it, but below the m3 commit from master.
Top comments (0)