Wednesday, November 11, 2020

git merge: fast-forward


Fast-forward is the simplest scenario for 'git merge', but it is a rare case in reality.

The 'fast forward' required that there is no new commit in the 'master' branch.


For instance, in the beginning, the latest commit of the master branch is c3.

---------------------------------------------------------------------------------

(master branch)

C1  ->  C2  ->  C3


Then create a new branch called bugFix, and it points to the C3 commit.

---------------------------------------------------------------------------------

(master branch)

C1  ->  C2  ->  C3

(bugFix branch)


Then, later on, a new commit, c4, is created in the bugFix branch.

---------------------------------------------------------------------------------

(master branch)

C1  ->  C2  ->  C3

->  C4

(bugFix branch)


After fixing bugs in the bugFix branch, we want to merge our work to the master branch.

There is no new commit in the master branch, and it meets the 'fast forward' requirement.

Then it is the linear path.

---------------------------------------------------------------------------------

C1 ->   C2  ->  C3

->   C4

(bugFix branch)

(master branch)


If it is fast-forward case, then the 'master' branch pointer will move to the last commit of the 'bugfix' branch.


Step 1:


Create a new branch 'bugFix'


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

    $ git log
    commit bfcee5bf315aec756495f18ae100a1c7f0476cd0 (HEAD -> bugfixmaster)
    Author: Frank <frank@demo.com>
    Date:   timestamp

        first commit


Both the 'bugFix' and the 'master' branch point to the same commit 'bfcee5'.


Step 2:


Then create a new commit in the bugFix branch.


    $ echo 'test' > test.txt
    $ git add .
    $ git commit -m 'first commit from bugfix branch'
    [bugfix 2cb50e8] first commit from bugfix branch
    1 file changed, 1 insertion(+)
    create mode 100644 test.txt


 
    $ git log
    commit 2cb50e8d58b5fc5ab4f57efcd7b78d2231bb54e3 (HEAD -> bugfix)
    Author: Frank <frank@demo.com>
    Date:   timestamp

        first commit from bugfix branch

    commit bfcee5bf315aec756495f18ae100a1c7f0476cd0 (master)
    Author: Frank <frank@demo.com>
    Date:   timestamp

        first commit


Now, the bugfix branch is one commit ahead of the master branch.


Step 3:


Switch to the master branch and dump the logs


    $ git checkout master

    $ tree .git/
    .git/
    ├── COMMIT_EDITMSG
    ├── HEAD
    ├── config
    ├── description
    ├── hooks
    ├── index
    ├── info
    │   └── exclude
    ├── logs
    │   ├── HEAD
    │   └── refs
    │       └── heads
    │           ├── bugfix
    │           └── master
    ├── objects
    │   ├── 2c
    │   │   └── b50e8d58b5fc5ab4f57efcd7b78d2231bb54e3
    │   ├── 4d
    │   │   └── 37130db92414cbb28c58a1a0023f9ee23798e1
    │   ├── 9d
    │   │   └── aeafb9864cf43055ae93beb0afd6c7d144bfa4
    │   ├── aa
    │   │   └── a96ced2d9a1c8e72c56b253a0e2fe78393feb7
    │   ├── bf
    │   │   └── cee5bf315aec756495f18ae100a1c7f0476cd0
    │   ├── ce
    │   │   └── 013625030ba8dba906f756967f9e9ca394464a
    │   ├── info
    │   └── pack
    └── refs
        ├── heads
        │   ├── bugfix
        │   └── master
        └── tags

    17 directories, 17 files

    $ git log
    commit bfcee5bf315aec756495f18ae100a1c7f0476cd0 (HEAD -> master)
    Author: Frank <frank@demo.com>
    Date:   timestamp

        first commit


In the master branch, we don't know the new commits from the bugfix branch.


Step 4:


Run the 'git merge' command.


    $ git merge bugfix
    Updating bfcee5b..2cb50e8
    Fast-forward
    test.txt | 1 +
    1 file changed, 1 insertion(+)
    create mode 100644 test.txt



bfcee5b is the latest commit which the master branch pointed to before.
2cb50e8 is the latest commit of the bugfix branch. 
Also, the master branch pointed to this commit after merging.


Step 5:

Check the logs


    $ git log
    commit 2cb50e8d58b5fc5ab4f57efcd7b78d2231bb54e3 (HEAD -> master, bugfix)
    Author: Frank <frank@demo.com>
    Date:   timestamp

        first commit from bugfix branch

    commit bfcee5bf315aec756495f18ae100a1c7f0476cd0
    Author: Frank <frank@demo.com>
    Date:   timestamp

        first commit
  

After merging, both master and bugfix point to the same commit object.


    $ tree .git/
    .git/
    ├── COMMIT_EDITMSG
    ├── HEAD
    ├── ORIG_HEAD (NEW FILE)
    ├── config
    ├── description
    ├── hooks
    ├── index
    ├── info
    │   └── exclude
    ├── logs
    │   ├── HEAD
    │   └── refs
    │       └── heads
    │           ├── bugfix
    │           └── master
    ├── objects
    │   ├── 2c
    │   │   └── b50e8d58b5fc5ab4f57efcd7b78d2231bb54e3
    │   ├── 4d
    │   │   └── 37130db92414cbb28c58a1a0023f9ee23798e1
    │   ├── 9d
    │   │   └── aeafb9864cf43055ae93beb0afd6c7d144bfa4
    │   ├── aa
    │   │   └── a96ced2d9a1c8e72c56b253a0e2fe78393feb7
    │   ├── bf
    │   │   └── cee5bf315aec756495f18ae100a1c7f0476cd0
    │   ├── ce
    │   │   └── 013625030ba8dba906f756967f9e9ca394464a
    │   ├── info
    │   └── pack
    └── refs
        ├── heads
        │   ├── bugfix
        │   └── master
        └── tags

    17 directories, 18 files


There is a new file called 'ORIG_HEAD' under the .git folder.

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


    $ cat .git/refs/heads/master
    2cb50e8d58b5fc5ab4f57efcd7b78d2231bb54e3



'2cb50e' is the commit master branch points to now.
According to the results above, we prove the message 'Updating baab4d2..539e44c' is correct

No comments:

Post a Comment