Friday, June 30, 2023

git merge: three-way merging

  

Currently, I am curious to find out what Git will do for us behind the scene if we run the 'git merge' commands. Below are the logs coming from my experiment. 


Reference: Git Book


Introduction


If it is not the linear relationship of the commit history, we cannot use the fast-forward approach.

We need to use the three-way merging.


Take the following as an example, both branches 'master' and 'hotfix' have commits which other branch don't have.


Use the 'git merge' command to merge the hotfix branch to the master branch.


The 'git merge' command will help to create a new merging commit C6, and the parents of C6 are C4 and C5.


Preparation


Create a brand new folder and run the 'git init' command.


Step 1:


Run the following commands to create c1, c2, and c3 commits.


    $ echo 'c1' > test.txt
$ git add .
$ git commit -m 'c1'
[master (root-commit) 09c1658] c1 1 file changed, 1 insertion(+) create mode 100644 test.txt

    $ echo 'c2' > test.txt
$ git add .
$ git commit -m 'c2'
[master f3333e2] c2 1 file changed, 1 insertion(+), 1 deletion(-)

    $ echo 'c3' > test.txt
$ git add .
$ git commit -m 'c3'
[master c9368a3] c3 1 file changed, 1 insertion(+), 1 deletion(-)


Check the git status.


    $ git status
On branch master nothing to commit, working tree clean


Check the .git tree structure.


    $ tree .git/
.git/ ├── COMMIT_EDITMSG ├── HEAD ├── branches ├── config ├── description ├── hooks │   ├── applypatch-msg.sample │   ├── commit-msg.sample │   ├── fsmonitor-watchman.sample │   ├── post-update.sample │   ├── pre-applypatch.sample │   ├── pre-commit.sample │   ├── pre-merge-commit.sample │   ├── pre-push.sample │   ├── pre-rebase.sample │   ├── pre-receive.sample │   ├── prepare-commit-msg.sample │   ├── push-to-checkout.sample │   └── update.sample ├── index ├── info │   └── exclude ├── logs │   ├── HEAD │   └── refs │   └── heads
│   └── master ├── objects     │   ├── 07 
    │   │   └── 71aea884dd394a7b12783d049f05b5599f41a4 (git blob object for c3)
    │   ├── 09 
    │   │   └── c165883d0a25f729d9a7c69fa02efd6c87c618 (git commit object for c1)
    │   ├── 16 
    │   │   └── f9ec009e5568c435f473ba3a1df732d49ce8c3  (git blob object for c2)
    │   ├── ae 
    │   │   └── 9304576a6ec3419b231b2b9c8e33a06f97f9fb (git blob object for c1)
    │   ├── b5 
    │   │   └── fab02de1c1f88003afeb7e98cf84a141bff039 (git tree object for c3)
    │   ├── c0 
    │   │   └── b072a3d368667939677b9315360631a100ecde (git tree object for c2)
    │   ├── c9 
    │   │   └── 368a318142494f31acd9c83a9763ed9f395a3b (git commit object for c3)
    │   ├── f1 
    │   │   └── 8c7b882bf09e79d96b692c31450cf59344fbf4 (git tree object for c1)
    │   ├── f3 
    │   │   └── 333e2df7930fa29ef8fb7ee177388f4a02b039 (git commit object for c2)
│   ├── info │   └── pack └── refs ├── heads
│   └── master └── tags 21 directories, 31 files


Check more info.


    $ cat .git/HEAD
ref: refs/heads/master

$ cat .git/refs/heads/master
c9368a318142494f31acd9c83a9763ed9f395a3b

$ git ls-files -s
100644 0771aea884dd394a7b12783d049f05b5599f41a4 0 test.txt

$ git log --oneline --decorate --graph --all
* c9368a3 (HEAD -> master) c3 * f3333e2 c2 * 09c1658 c1


Step 2:


Create and checkout a new branch 'hotfix'.


    $ git checkout -b hotfix
Switched to a new branch 'hotfix'


Check the git status.


    $ git status
On branch hotfix nothing to commit, working tree clean


Check the .git tree structure.


    $ tree .git/
.git/ ├── COMMIT_EDITMSG ├── HEAD ├── branches ├── config ├── description ├── hooks │   ├── applypatch-msg.sample │   ├── commit-msg.sample │   ├── fsmonitor-watchman.sample │   ├── post-update.sample │   ├── pre-applypatch.sample │   ├── pre-commit.sample │   ├── pre-merge-commit.sample │   ├── pre-push.sample │   ├── pre-rebase.sample │   ├── pre-receive.sample │   ├── prepare-commit-msg.sample │   ├── push-to-checkout.sample │   └── update.sample ├── index ├── info │   └── exclude ├── logs │   ├── HEAD │   └── refs │   └── heads
│   ├── hotfix
│   └── master ├── objects     │   ├── 07 
    │   │   └── 71aea884dd394a7b12783d049f05b5599f41a4 (git blob object for c3)
    │   ├── 09 
    │   │   └── c165883d0a25f729d9a7c69fa02efd6c87c618 (git commit object for c1)
    │   ├── 16 
    │   │   └── f9ec009e5568c435f473ba3a1df732d49ce8c3  (git blob object for c2)
    │   ├── ae 
    │   │   └── 9304576a6ec3419b231b2b9c8e33a06f97f9fb (git blob object for c1)
    │   ├── b5 
    │   │   └── fab02de1c1f88003afeb7e98cf84a141bff039 (git tree object for c3)
    │   ├── c0 
    │   │   └── b072a3d368667939677b9315360631a100ecde (git tree object for c2)
    │   ├── c9 
    │   │   └── 368a318142494f31acd9c83a9763ed9f395a3b (git commit object for c3)
    │   ├── f1 
    │   │   └── 8c7b882bf09e79d96b692c31450cf59344fbf4 (git tree object for c1)
    │   ├── f3 
    │   │   └── 333e2df7930fa29ef8fb7ee177388f4a02b039 (git commit object for c2)
│   ├── info │   └── pack └── refs ├── heads
│   ├── hotfix
│   └── master └── tags 21 directories, 33 files


Check more info.


    $ cat .git/HEAD
ref: refs/heads/hotfix

$ cat .git/refs/heads/master
c9368a318142494f31acd9c83a9763ed9f395a3b

$ cat .git/refs/heads/hotfix
c9368a318142494f31acd9c83a9763ed9f395a3b

$ git ls-files -s
100644 0771aea884dd394a7b12783d049f05b5599f41a4 0 test.txt

$ git log --oneline --decorate --graph --all
* c9368a3 (HEAD -> hotfix, master) c3
* f3333e2 c2 * 09c1658 c1

Both the hotfix branch and the master branch point to the c3 commit.


Step 3:


Create a new commit 'c4' on the hotfix branch.


    $ echo 'c4' > test.txt
    $ git add .
    $ git commit -m 'c4'
[hotfix 85ad7e6] c4
 1 file changed, 1 insertion(+), 1 deletion(-)


Check the git status.


    $ git status
On branch hotfix nothing to commit, working tree clean


Check the .git tree structure.


    $ tree .git/
.git/ ├── COMMIT_EDITMSG ├── HEAD ├── branches ├── config ├── description ├── hooks │   ├── applypatch-msg.sample │   ├── commit-msg.sample │   ├── fsmonitor-watchman.sample │   ├── post-update.sample │   ├── pre-applypatch.sample │   ├── pre-commit.sample │   ├── pre-merge-commit.sample │   ├── pre-push.sample │   ├── pre-rebase.sample │   ├── pre-receive.sample │   ├── prepare-commit-msg.sample │   ├── push-to-checkout.sample │   └── update.sample ├── index ├── info │   └── exclude ├── logs │   ├── HEAD │   └── refs │   └── heads
│   ├── hotfix
│   └── master ├── objects     │   ├── 07 
    │   │   └── 71aea884dd394a7b12783d049f05b5599f41a4 (git blob object for c3)
    │   ├── 09 
    │   │   └── c165883d0a25f729d9a7c69fa02efd6c87c618 (git commit object for c1)
    │   ├── 16 
    │   │   └── f9ec009e5568c435f473ba3a1df732d49ce8c3  (git blob object for c2)
    │   ├── 3d
    │   │   └── 3095743da8025788f376069d9c07b9d867d5c1 (git tree object for c4)
    │   ├── 85
    │   │   └── ad7e6b045bfc28bf4546a86f1e9b0b669fc034 (git commit object for c4)
    │   ├── a1
    │   │   └── 03f673dd1b7c5727aa0ae0100419adc50e1b76 (git blob object for c4)
    │   ├── ae 
    │   │   └── 9304576a6ec3419b231b2b9c8e33a06f97f9fb (git blob object for c1)
    │   ├── b5 
    │   │   └── fab02de1c1f88003afeb7e98cf84a141bff039 (git tree object for c3)
    │   ├── c0 
    │   │   └── b072a3d368667939677b9315360631a100ecde (git tree object for c2)
    │   ├── c9 
    │   │   └── 368a318142494f31acd9c83a9763ed9f395a3b (git commit object for c3)
    │   ├── f1 
    │   │   └── 8c7b882bf09e79d96b692c31450cf59344fbf4 (git tree object for c1)
    │   ├── f3 
    │   │   └── 333e2df7930fa29ef8fb7ee177388f4a02b039 (git commit object for c2)
│   ├── info │   └── pack └── refs ├── heads
│   ├── hotfix
│   └── master └── tags 24 directories, 36 files


Check more info.


    $ cat .git/HEAD
ref: refs/heads/hotfix

$ cat .git/refs/heads/master
c9368a318142494f31acd9c83a9763ed9f395a3b

$ cat .git/refs/heads/hotfix
85ad7e6b045bfc28bf4546a86f1e9b0b669fc034

$ git ls-files -s
100644 a103f673dd1b7c5727aa0ae0100419adc50e1b76 0 test.txt

$ git log --oneline --decorate --graph --all
* 85ad7e6 (HEAD -> hotfix) c4 * c9368a3 (master) c3 
* f3333e2 c2 * 09c1658 c1

Now the hotfix branch has one more commit ahead the master branch.


Step 4:


Switch to the master branch. 

Create a commit c5 (make sure to avoid conflict).


    $ git checkout master
Switched to branch 'master'

    $ echo 'c5' > c5.txt
$ git add .
$ git commit -m 'c5'
[master 25e3699] c5 1 file changed, 1 insertion(+) create mode 100644 c5.txt


Check the git status.


    $ git status
On branch master nothing to commit, working tree clean


Check the .git tree structure.


    $ tree .git/
.git/ ├── COMMIT_EDITMSG ├── HEAD ├── branches ├── config ├── description ├── hooks │   ├── applypatch-msg.sample │   ├── commit-msg.sample │   ├── fsmonitor-watchman.sample │   ├── post-update.sample │   ├── pre-applypatch.sample │   ├── pre-commit.sample │   ├── pre-merge-commit.sample │   ├── pre-push.sample │   ├── pre-rebase.sample │   ├── pre-receive.sample │   ├── prepare-commit-msg.sample │   ├── push-to-checkout.sample │   └── update.sample ├── index ├── info │   └── exclude ├── logs │   ├── HEAD │   └── refs │   └── heads
│   ├── hotfix
│   └── master ├── objects     │   ├── 07 
    │   │   └── 71aea884dd394a7b12783d049f05b5599f41a4 (git blob object for c3)
    │   ├── 09 
    │   │   └── c165883d0a25f729d9a7c69fa02efd6c87c618 (git commit object for c1)
    │   ├── 16 
    │   │   └── f9ec009e5568c435f473ba3a1df732d49ce8c3  (git blob object for c2)
    │   ├── 25
    │   │   └── e3699293eeeb9b6f4e33e5873171b6aba01e80 (git commit object for c5)
    │   ├── 3d
    │   │   └── 3095743da8025788f376069d9c07b9d867d5c1 (git tree object for c4)
    │   ├── 85
    │   │   └── ad7e6b045bfc28bf4546a86f1e9b0b669fc034 (git commit object for c4)
    │   ├── 9a
    │   │   └── ed71345f7f6af10cf15445dcc767b5f3433ae7 (git tree object for c5)
    │   ├── a1
    │   │   └── 03f673dd1b7c5727aa0ae0100419adc50e1b76 (git blob object for c4)
    │   ├── ae 
    │   │   └── 9304576a6ec3419b231b2b9c8e33a06f97f9fb (git blob object for c1)
    │   ├── b5 
    │   │   └── fab02de1c1f88003afeb7e98cf84a141bff039 (git tree object for c3)
    │   ├── c0 
    │   │   └── b072a3d368667939677b9315360631a100ecde (git tree object for c2)
    │   ├── c3
    │   │   └── 6357109ce20af8f90df3c0dd0784e89408d707 (git blob object for c5)
    │   ├── c9 
    │   │   └── 368a318142494f31acd9c83a9763ed9f395a3b (git commit object for c3)
    │   ├── f1 
    │   │   └── 8c7b882bf09e79d96b692c31450cf59344fbf4 (git tree object for c1)
    │   ├── f3 
    │   │   └── 333e2df7930fa29ef8fb7ee177388f4a02b039 (git commit object for c2)
│   ├── info │   └── pack └── refs ├── heads
│   ├── hotfix
│   └── master └── tags 27 directories, 39 files


Check more info.


    $ cat .git/HEAD
ref: refs/heads/master

$ cat .git/refs/heads/master
25e3699293eeeb9b6f4e33e5873171b6aba01e80

$ cat .git/refs/heads/hotfix
85ad7e6b045bfc28bf4546a86f1e9b0b669fc034

$ git ls-files -s
100644 c36357109ce20af8f90df3c0dd0784e89408d707 0 c5.txt 100644 0771aea884dd394a7b12783d049f05b5599f41a4 0 test.txt

$ git log --oneline --decorate --graph --all
* 25e3699 (HEAD -> master) c5 | * 85ad7e6 (hotfix) c4 |/ * c9368a3 c3
* f3333e2 c2 * 09c1658 c1

Now the commit history is diverged.


Step 5:


Run the 'git merge' command to merge the work from the hotfix branch.


    $ git merge hotfix

Below is a prompt message:
----------------------------------------
Merge branch 'hotfix' # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
    ----------------------------------------

Merge made by the 'ort' strategy. test.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)

Then the auto-generated merging commit was created.


Check the git status.


    $ git status
On branch master nothing to commit, working tree clean


Check the .git tree structure.


    $ tree .git/
.git/ ├── COMMIT_EDITMSG ├── HEAD ├── ORIG_HEAD
├── branches ├── config ├── description ├── hooks │   ├── applypatch-msg.sample │   ├── commit-msg.sample │   ├── fsmonitor-watchman.sample │   ├── post-update.sample │   ├── pre-applypatch.sample │   ├── pre-commit.sample │   ├── pre-merge-commit.sample │   ├── pre-push.sample │   ├── pre-rebase.sample │   ├── pre-receive.sample │   ├── prepare-commit-msg.sample │   ├── push-to-checkout.sample │   └── update.sample ├── index ├── info │   └── exclude ├── logs │   ├── HEAD │   └── refs │   └── heads
│   ├── hotfix
│   └── master ├── objects     │   ├── 07 
    │   │   └── 71aea884dd394a7b12783d049f05b5599f41a4 (git blob object for c3)
    │   ├── 09 
    │   │   └── c165883d0a25f729d9a7c69fa02efd6c87c618 (git commit object for c1)
    │   ├── 16 
    │   │   └── f9ec009e5568c435f473ba3a1df732d49ce8c3  (git blob object for c2)
    │   ├── 25
    │   │   └── e3699293eeeb9b6f4e33e5873171b6aba01e80 (git commit object for c5)
    │   ├── 3d
    │   │   └── 3095743da8025788f376069d9c07b9d867d5c1 (git tree object for c4)
    │   ├── 60
    │   │   └── 0188dcf6aa195ed51c91212610f0ab42b29f43 (git tree object for merge commit)
    │   ├── 71
    │   │   └── a62be3c4950898a454f6057f353678b542b920 (git commit object for merge commit)
    │   ├── 85
    │   │   └── ad7e6b045bfc28bf4546a86f1e9b0b669fc034 (git commit object for c4)
    │   ├── 9a
    │   │   └── ed71345f7f6af10cf15445dcc767b5f3433ae7 (git tree object for c5)
    │   ├── a1
    │   │   └── 03f673dd1b7c5727aa0ae0100419adc50e1b76 (git blob object for c4)
    │   ├── ae 
    │   │   └── 9304576a6ec3419b231b2b9c8e33a06f97f9fb (git blob object for c1)
    │   ├── b5 
    │   │   └── fab02de1c1f88003afeb7e98cf84a141bff039 (git tree object for c3)
    │   ├── c0 
    │   │   └── b072a3d368667939677b9315360631a100ecde (git tree object for c2)
    │   ├── c3
    │   │   └── 6357109ce20af8f90df3c0dd0784e89408d707 (git blob object for c5)
    │   ├── c9 
    │   │   └── 368a318142494f31acd9c83a9763ed9f395a3b (git commit object for c3)
    │   ├── f1 
    │   │   └── 8c7b882bf09e79d96b692c31450cf59344fbf4 (git tree object for c1)
    │   ├── f3 
    │   │   └── 333e2df7930fa29ef8fb7ee177388f4a02b039 (git commit object for c2)
│   ├── info │   └── pack └── refs ├── heads
│   ├── hotfix
│   └── master └── tags 29 directories, 42 files


Check the content of the git commit object '71a62be'


    $ git cat-file -p 71a62be
tree 600188dcf6aa195ed51c91212610f0ab42b29f43
parent 25e3699293eeeb9b6f4e33e5873171b6aba01e80
parent 85ad7e6b045bfc28bf4546a86f1e9b0b669fc034
author Frank <frank@demo.com> datetime
committer Frank <frank@demo.com> datetime

Merge branch 'hotfix'

This merge commit has two parents: commit c4 and c5.


Check more info.


    $ cat .git/HEAD
ref: refs/heads/master

    $ cat .git/ORIG_HEAD
25e3699293eeeb9b6f4e33e5873171b6aba01e80

$ cat .git/refs/heads/master
71a62be3c4950898a454f6057f353678b542b920

$ cat .git/refs/heads/hotfix
85ad7e6b045bfc28bf4546a86f1e9b0b669fc034

$ git ls-files -s
100644 c36357109ce20af8f90df3c0dd0784e89408d707 0 c5.txt 100644 a103f673dd1b7c5727aa0ae0100419adc50e1b76 0 test.txt

$ git log --oneline --decorate --graph --all
* 71a62be (HEAD -> master) Merge branch 'hotfix' |\ | * 85ad7e6 (hotfix) c4 * | 25e3699 c5 |/ * c9368a3 c3 * f3333e2 c2 * 09c1658 c1


git merge: fast-forward merging

 

Currently, I am curious to find out what Git will do for us behind the scene if we run the 'git merge' commands. Below are the logs coming from my experiment. 


Reference: Git Book


Introduction


"Fast-forward merging" is the simplest scenario for the 'git merge'. But it is a rare case in reality.

The 'fast forward merging' required no new commit in the 'master' branch.


For instance, there are two branches 'master' and 'hotfix', and hotfix is one commit ahead from the master branch.

After fixing bugs C4 in the 'hotfix' branch, we want to merge our work to the master branch. And there is no new commit in the master branch, and it meets the 'fast forward merging' requirement. If it is fast-forward merging case, then the 'master' branch pointer will move to the last commit of the 'hotfix' branch.


Preparation


Create a brand new folder and run the 'git init' command.


Step 1:


Run the following commands to create c1, c2, and c3 commits.


    $ echo 'c1' > test.txt
$ git add .
$ git commit -m 'c1'
[master (root-commit) 09c1658] c1 1 file changed, 1 insertion(+) create mode 100644 test.txt

    $ echo 'c2' > test.txt
$ git add .
$ git commit -m 'c2'
[master f3333e2] c2 1 file changed, 1 insertion(+), 1 deletion(-)

    $ echo 'c3' > test.txt
$ git add .
$ git commit -m 'c3'
[master c9368a3] c3 1 file changed, 1 insertion(+), 1 deletion(-)


Check the git status.


    $ git status
On branch master nothing to commit, working tree clean


Check the .git tree structure.


    $ tree .git/
.git/ ├── COMMIT_EDITMSG ├── HEAD ├── branches ├── config ├── description ├── hooks │   ├── applypatch-msg.sample │   ├── commit-msg.sample │   ├── fsmonitor-watchman.sample │   ├── post-update.sample │   ├── pre-applypatch.sample │   ├── pre-commit.sample │   ├── pre-merge-commit.sample │   ├── pre-push.sample │   ├── pre-rebase.sample │   ├── pre-receive.sample │   ├── prepare-commit-msg.sample │   ├── push-to-checkout.sample │   └── update.sample ├── index ├── info │   └── exclude ├── logs │   ├── HEAD │   └── refs │   └── heads
│   └── master ├── objects     │   ├── 07 
    │   │   └── 71aea884dd394a7b12783d049f05b5599f41a4 (git blob object for c3)
    │   ├── 09 
    │   │   └── c165883d0a25f729d9a7c69fa02efd6c87c618 (git commit object for c1)
    │   ├── 16 
    │   │   └── f9ec009e5568c435f473ba3a1df732d49ce8c3  (git blob object for c2)
    │   ├── ae 
    │   │   └── 9304576a6ec3419b231b2b9c8e33a06f97f9fb (git blob object for c1)
    │   ├── b5 
    │   │   └── fab02de1c1f88003afeb7e98cf84a141bff039 (git tree object for c3)
    │   ├── c0 
    │   │   └── b072a3d368667939677b9315360631a100ecde (git tree object for c2)
    │   ├── c9 
    │   │   └── 368a318142494f31acd9c83a9763ed9f395a3b (git commit object for c3)
    │   ├── f1 
    │   │   └── 8c7b882bf09e79d96b692c31450cf59344fbf4 (git tree object for c1)
    │   ├── f3 
    │   │   └── 333e2df7930fa29ef8fb7ee177388f4a02b039 (git commit object for c2)
│   ├── info │   └── pack └── refs ├── heads
│   └── master └── tags 21 directories, 31 files


Check more info.


    $ cat .git/HEAD
ref: refs/heads/master

$ cat .git/refs/heads/master
c9368a318142494f31acd9c83a9763ed9f395a3b

$ git ls-files -s
100644 0771aea884dd394a7b12783d049f05b5599f41a4 0 test.txt

$ git log --oneline --decorate --graph --all
* c9368a3 (HEAD -> master) c3 * f3333e2 c2 * 09c1658 c1


Step 2:


Create and checkout a new branch 'hotfix'.


    $ git checkout -b hotfix
Switched to a new branch 'hotfix'


Check the git status.


    $ git status
On branch hotfix nothing to commit, working tree clean


Check the .git tree structure.


    $ tree .git/
.git/ ├── COMMIT_EDITMSG ├── HEAD ├── branches ├── config ├── description ├── hooks │   ├── applypatch-msg.sample │   ├── commit-msg.sample │   ├── fsmonitor-watchman.sample │   ├── post-update.sample │   ├── pre-applypatch.sample │   ├── pre-commit.sample │   ├── pre-merge-commit.sample │   ├── pre-push.sample │   ├── pre-rebase.sample │   ├── pre-receive.sample │   ├── prepare-commit-msg.sample │   ├── push-to-checkout.sample │   └── update.sample ├── index ├── info │   └── exclude ├── logs │   ├── HEAD │   └── refs │   └── heads
│   ├── hotfix
│   └── master ├── objects     │   ├── 07 
    │   │   └── 71aea884dd394a7b12783d049f05b5599f41a4 (git blob object for c3)
    │   ├── 09 
    │   │   └── c165883d0a25f729d9a7c69fa02efd6c87c618 (git commit object for c1)
    │   ├── 16 
    │   │   └── f9ec009e5568c435f473ba3a1df732d49ce8c3  (git blob object for c2)
    │   ├── ae 
    │   │   └── 9304576a6ec3419b231b2b9c8e33a06f97f9fb (git blob object for c1)
    │   ├── b5 
    │   │   └── fab02de1c1f88003afeb7e98cf84a141bff039 (git tree object for c3)
    │   ├── c0 
    │   │   └── b072a3d368667939677b9315360631a100ecde (git tree object for c2)
    │   ├── c9 
    │   │   └── 368a318142494f31acd9c83a9763ed9f395a3b (git commit object for c3)
    │   ├── f1 
    │   │   └── 8c7b882bf09e79d96b692c31450cf59344fbf4 (git tree object for c1)
    │   ├── f3 
    │   │   └── 333e2df7930fa29ef8fb7ee177388f4a02b039 (git commit object for c2)
│   ├── info │   └── pack └── refs ├── heads
│   ├── hotfix
│   └── master └── tags 21 directories, 33 files


Check more info.


    $ cat .git/HEAD
ref: refs/heads/hotfix

$ cat .git/refs/heads/master
c9368a318142494f31acd9c83a9763ed9f395a3b

$ cat .git/refs/heads/hotfix
c9368a318142494f31acd9c83a9763ed9f395a3b

$ git ls-files -s
100644 0771aea884dd394a7b12783d049f05b5599f41a4 0 test.txt

$ git log --oneline --decorate --graph --all
* c9368a3 (HEAD -> hotfix, master) c3
* f3333e2 c2 * 09c1658 c1

Both the hotfix branch and the master branch point to the c3 commit.


Step 3:


Create a new commit 'c4' on the hotfix branch.


    $ echo 'c4' > test.txt
    $ git add .
    $ git commit -m 'c4'
[hotfix 85ad7e6] c4
 1 file changed, 1 insertion(+), 1 deletion(-)


Check the git status.


    $ git status
On branch hotfix nothing to commit, working tree clean


Check the .git tree structure.


    $ tree .git/
.git/ ├── COMMIT_EDITMSG ├── HEAD ├── branches ├── config ├── description ├── hooks │   ├── applypatch-msg.sample │   ├── commit-msg.sample │   ├── fsmonitor-watchman.sample │   ├── post-update.sample │   ├── pre-applypatch.sample │   ├── pre-commit.sample │   ├── pre-merge-commit.sample │   ├── pre-push.sample │   ├── pre-rebase.sample │   ├── pre-receive.sample │   ├── prepare-commit-msg.sample │   ├── push-to-checkout.sample │   └── update.sample ├── index ├── info │   └── exclude ├── logs │   ├── HEAD │   └── refs │   └── heads
│   ├── hotfix
│   └── master ├── objects     │   ├── 07 
    │   │   └── 71aea884dd394a7b12783d049f05b5599f41a4 (git blob object for c3)
    │   ├── 09 
    │   │   └── c165883d0a25f729d9a7c69fa02efd6c87c618 (git commit object for c1)
    │   ├── 16 
    │   │   └── f9ec009e5568c435f473ba3a1df732d49ce8c3  (git blob object for c2)
    │   ├── 3d
    │   │   └── 3095743da8025788f376069d9c07b9d867d5c1 (git tree object for c4)
    │   ├── 85
    │   │   └── ad7e6b045bfc28bf4546a86f1e9b0b669fc034 (git commit object for c4)
    │   ├── a1
    │   │   └── 03f673dd1b7c5727aa0ae0100419adc50e1b76 (git blob object for c4)
    │   ├── ae 
    │   │   └── 9304576a6ec3419b231b2b9c8e33a06f97f9fb (git blob object for c1)
    │   ├── b5 
    │   │   └── fab02de1c1f88003afeb7e98cf84a141bff039 (git tree object for c3)
    │   ├── c0 
    │   │   └── b072a3d368667939677b9315360631a100ecde (git tree object for c2)
    │   ├── c9 
    │   │   └── 368a318142494f31acd9c83a9763ed9f395a3b (git commit object for c3)
    │   ├── f1 
    │   │   └── 8c7b882bf09e79d96b692c31450cf59344fbf4 (git tree object for c1)
    │   ├── f3 
    │   │   └── 333e2df7930fa29ef8fb7ee177388f4a02b039 (git commit object for c2)
│   ├── info │   └── pack └── refs ├── heads
│   ├── hotfix
│   └── master └── tags 24 directories, 36 files


Check more info.


    $ cat .git/HEAD
ref: refs/heads/hotfix

$ cat .git/refs/heads/master
c9368a318142494f31acd9c83a9763ed9f395a3b

$ cat .git/refs/heads/hotfix
85ad7e6b045bfc28bf4546a86f1e9b0b669fc034

$ git ls-files -s
100644 a103f673dd1b7c5727aa0ae0100419adc50e1b76 0 test.txt

$ git log --oneline --decorate --graph --all
* 85ad7e6 (HEAD -> hotfix) c4 * c9368a3 (master) c3 
* f3333e2 c2 * 09c1658 c1

Now the hotfix branch has one more commit ahead the master branch.


Step 4:


Switch to the master branch. 

Run the 'git merge' command to merge the work from the hotfix branch.


    $ git checkout master
Switched to branch 'master'

    $ git merge hotfix
Updating c9368a3..85ad7e6
Fast-forward
 test.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

c9368a3 is the last commit from the master branch.

85ad7e6 is the last commit from the hotfix branch, and the master branch will point to it after merging.


Check the git status.


    $ git status
On branch master nothing to commit, working tree clean


Check the .git tree structure.


    $ tree .git/
.git/ ├── COMMIT_EDITMSG ├── HEAD 
├── ORIG_HEAD
├── branches ├── config ├── description ├── hooks │   ├── applypatch-msg.sample │   ├── commit-msg.sample │   ├── fsmonitor-watchman.sample │   ├── post-update.sample │   ├── pre-applypatch.sample │   ├── pre-commit.sample │   ├── pre-merge-commit.sample │   ├── pre-push.sample │   ├── pre-rebase.sample │   ├── pre-receive.sample │   ├── prepare-commit-msg.sample │   ├── push-to-checkout.sample │   └── update.sample ├── index ├── info │   └── exclude ├── logs │   ├── HEAD │   └── refs │   └── heads
│   ├── hotfix
│   └── master ├── objects     │   ├── 07 
    │   │   └── 71aea884dd394a7b12783d049f05b5599f41a4 (git blob object for c3)
    │   ├── 09 
    │   │   └── c165883d0a25f729d9a7c69fa02efd6c87c618 (git commit object for c1)
    │   ├── 16 
    │   │   └── f9ec009e5568c435f473ba3a1df732d49ce8c3  (git blob object for c2)
    │   ├── 3d
    │   │   └── 3095743da8025788f376069d9c07b9d867d5c1 (git tree object for c4)
    │   ├── 85
    │   │   └── ad7e6b045bfc28bf4546a86f1e9b0b669fc034 (git commit object for c4)
    │   ├── a1
    │   │   └── 03f673dd1b7c5727aa0ae0100419adc50e1b76 (git blob object for c4)
    │   ├── ae 
    │   │   └── 9304576a6ec3419b231b2b9c8e33a06f97f9fb (git blob object for c1)
    │   ├── b5 
    │   │   └── fab02de1c1f88003afeb7e98cf84a141bff039 (git tree object for c3)
    │   ├── c0 
    │   │   └── b072a3d368667939677b9315360631a100ecde (git tree object for c2)
    │   ├── c9 
    │   │   └── 368a318142494f31acd9c83a9763ed9f395a3b (git commit object for c3)
    │   ├── f1 
    │   │   └── 8c7b882bf09e79d96b692c31450cf59344fbf4 (git tree object for c1)
    │   ├── f3 
    │   │   └── 333e2df7930fa29ef8fb7ee177388f4a02b039 (git commit object for c2)
│   ├── info │   └── pack └── refs ├── heads
│   ├── hotfix
│   └── master └── tags 24 directories, 37 files


Check more info.


    $ cat .git/HEAD
ref: refs/heads/master

    $ cat .git/ORIG_HEAD
c9368a318142494f31acd9c83a9763ed9f395a3b

$ cat .git/refs/heads/master
85ad7e6b045bfc28bf4546a86f1e9b0b669fc034

$ cat .git/refs/heads/hotfix
85ad7e6b045bfc28bf4546a86f1e9b0b669fc034

$ git ls-files -s
100644 a103f673dd1b7c5727aa0ae0100419adc50e1b76 0 test.txt

$ git log --oneline --decorate --graph --all
* 85ad7e6 (HEAD -> master, hotfix) c4 * c9368a3 c3 * f3333e2 c2 * 09c1658 c1


ORIG_HEAD was created after running the 'git merge' command.

It is used to revert the merge commit singe git thinks that the 'merge command' is dangerous and easy to make a mistake.