Tuesday, November 17, 2015

git - demonstrating merge conflict management : Merge conflict - Automatic merge failed

Let us take example of Romeo and Juliet love story. They decided to write their story.


PART-1: Initial draft of Romeo and Juliet story in master branch


--All big Love stories start with a tiny story !

$ git branch
* master


--This is initial short story

$ cat >story.txt
Romeo and Juliet are writting their love story
Love is ever lasting and Life is not
Our soul had been together and will remain always
As we are not Two, we are one ...
^D
$
$ git status
# On branch master
# Untracked files:
#   (use "git add ..." to include in what will be committed)
#
#       story.txt
nothing added to commit but untracked files present (use "git add" to track)
$ git add .
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD ..." to unstage)
#
#       new file:   story.txt
#

$ git commit -m "Romeo and Juliet - our story - first draft"
[master 978e583] Romeo and Juliet - our story - first draft
 1 files changed, 4 insertions(+), 0 deletions(-)
 create mode 100644 story.txt
$ git log
* 978e583 (HEAD, master) Romeo and Juliet - our story - first draft
* 52d4c41 inital repo - commit zero
$ cat -n story.txt
     1  Romeo and Juliet are writting their love story
     2  Love is ever lasting and Life is not
     3  Our soul had been together and will remain always
     4  As we are not Two, we are one ...
$



PART-2: Romeo and Juliet - updated their stories separately


Fact is, no two people think say way, even they Love each other like Romeo and Juliet ! So, both have updated story, in their own way.

--from master branch, Romeo has created a branch

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


--from master branch, Juliet create another branch

$ git checkout master
Switched to branch 'master'
$ git checkout -b juliet_branch
Switched to a new branch 'juliet_branch'
$
$ git branch
* juliet_branch
  master
  romeo_branch


--Juliet did following changes and did commit
  --On line 2, replaced 'not' with 'temporary'
  --Added a line 5 at the end of story 'World see us seprate but we do not feel so ..'

$ vi story.txt
$ git add .
$ git commit -m "Juliet - modified line 2 and added line 5"
[juliet_branch 4ffd429] Juliet - modified line 2 and added line 5
 1 files changed, 2 insertions(+), 1 deletions(-)
$ cat -n story.txt
     1  Romeo and Juliet are writting their love story
     2  Love is ever lasting and Life is temporary
     3  Our soul had been together and will remain always
     4  As we are not Two, we are one ...
     5  World see us seprate but we do not feel so ..
$


--Romeo did following change and did commit

  --On line 2, appended 'permanent' after last word 'not'
  --Added a line 5 at the end of story 'Does life have any meaning without love ?!'

$ git checkout romeo_branch
$ vi story.txt
$ git add .
$ git commit -m "Romeo - modified line 2 and added line 5"
[romeo_branch c990508] Romeo - modified line 2 and added line 5
 1 files changed, 2 insertions(+), 1 deletions(-)
$
$ cat -n story.txt
     1  Romeo and Juliet are writting their love story
     2  Love is ever lasting and Life is not permanent
     3  Our soul had been together and will remain always
     4  As we are not Two, we are one ...
     5  Does life have any meaning without love ?!



PART-3 : Conflict in story - Yep, even lovers need to know how to manage conflict !


--Understand existing commits:

$ git log
* c990508 (HEAD, romeo_branch) Romeo - modified line 2 and added line 5
| * 4ffd429 (juliet_branch) Juliet - modified line 2 and added line 5
|/
* 978e583 (master) Romeo and Juliet - our stries - first draft
* 52d4c41 inital repo - commit zero


978e583 is common ancestor - parent. From this parent, 2 child commits 4ffd429 and c990508.


--Romeo, time to time, merge stories and update master branch. Romeo, merge Juliet story on top of his own story. And, merge failed !!

$ git co romeo_branch
Switched to branch 'romeo_branch'
$ git merge juliet_branch
Auto-merging story.txt
CONFLICT (content): Merge conflict in story.txt
Automatic merge failed; fix conflicts and then commit the result.
$ git s
# On branch romeo_branch
# Unmerged paths:
#   (use "git add/rm ..." as appropriate to mark resolution)
#
#       both modified:      story.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
$
$ cat story.txt
Romeo and Juliet are writting their love story
<<<<<<< HEAD
Love is ever lasting and Life is not permanent
Our soul had been together and will remain always
As we are not Two, we are one ...
Does life have any meaning without love ?!
=======
Love is ever lasting and Life is temporary
Our soul had been together and will remain always
As we are not Two, we are one ...
World see us seprate but we do not feel so ..
>>>>>>> juliet_branch
$


--what does it mean :
   -There is no conflict in line 1 - all good
   -HEAD is pointer to branch where you are. In this care HEAD is pointing to romeo_branch
   -git says that
       --line betweeen <<<<<<< and ======= are from the file in present branch ( HEAD that is romeo_branch)
       --line between ======= and >>>>>>> are from ther branch you are mearging ( that is - juliet_branch)


--Rome dicidess to fix conflicts following way :
  -delete line <<<<<<< , ======= and >>>>>>>
  -Combine feelings of both and update line 2 as
        "Love is ever lasting and Life is not permanent, it is temporary"
   -Keep last line of both - so it will make line 5 and line 6


-- Final story after manually editing file is :

$ cat -n story.txt
     1  Romeo and Juliet are writting their love story
     2  Love is ever lasting and Life is not permanent, it is temporary
     3  Our soul had been together and will remain always
     4  As we are not Two, we are one ...
     5  Does life have any meaning without love ?!
     6  World see us seprate but we do not feel so ..
$


--Finally, commit it - new commit is 9dc72f2 - new commit have ha been created by merging Juliet's commit 4ffd429 on top of Romeo's old commit c990508

$ git status
# On branch romeo_branch
# Unmerged paths:
#   (use "git add/rm ..." as appropriate to mark resolution)
#
#       both modified:      story.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
$
$ git add .
$ git commit -m "Romeo and Juliet combined story"
[romeo_branch 9dc72f2] Romeo and Juliet combined story
$


--how does commit log looks like ?

$ git log
*   9dc72f2 (HEAD, romeo_branch) Romeo and Juliet combined story
|\
| * 4ffd429 (juliet_branch) Juliet - modified line 2 and added line 5
* | c990508 Romeo - modified line 2 and added line 5
|/
* 978e583 (master) Romeo and Juliet - our stries - first draft
* 52d4c41 inital repo - commit zero



PART-4 - Finally merge Romeo branch onto master


$ git checkout master
Switched to branch 'master'
$
$ git merge romeo_branch
Updating 978e583..9dc72f2
Fast-forward
 story.txt |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
$

--It is hassle free, Fast-forward merge
    -Fast-forward - No conflict while mearging - hence move (master) from second last line ( common ancesotor) to top line.

$ git log
*   9dc72f2 (HEAD, romeo_branch, master) Romeo and Juliet combined story
|\
| * 4ffd429 (juliet_branch) Juliet - modified line 2 and added line 5
* | c990508 Romeo - modified line 2 and added line 5
|/
* 978e583 Romeo and Juliet - our stries - first draft
* 52d4c41 inital repo - commit zero
$


--Get rid of romeo_branch and juliet_branch.

$ git branch -D romeo_branch juliet_branch
Deleted branch romeo_branch (was 9dc72f2).
Deleted branch juliet_branch (was 4ffd429).
$ git branch
* master 9dc72f2 Romeo and Juliet combined story



--Love stories have no end - so Romeo and Juliet will create a new branch from master branch and repeat this whole cycle - again and again!



Reference :  https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging

No comments:

Post a Comment