Friday, 7 November 2025

Git - Conflict management

When two developers update the same file and raise pull requests (PRs), the key factor is who gets merged first and if the changes overlap.

Get the latest code change first.

[root@devopsvm01 html]# pwd

/var/www/html

[root@devopsvm01 html]# git branch

  feature-1/branch-1

* main

[root@devopsvm01 html]# git status

On branch main

Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

[root@devopsvm01 html]# git pull

remote: Enumerating objects: 1, done.

remote: Counting objects: 100% (1/1), done.

Unpacking objects: 100% (1/1), 905 bytes | 905.00 KiB/s, done.

remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)

From github.com:mahekarthya/devops-demo-pvt

   0de658f..2f6b922  main       -> origin/main

Updating 0de658f..2f6b922

Fast-forward

 offer.html | 4 ++--

 1 file changed, 2 insertions(+), 2 deletions(-)

[root@devopsvm01 html]#

[root@devopsvm01 html]#


Make the changes as Developer1 and Developer2

Developer1 (D1)

[root@devopsvm01 html]# git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
[root@devopsvm01 html]#
[root@devopsvm01 html]# git checkout -b D1
Switched to a new branch 'D1'
[root@devopsvm01 html]#


Before edit















Then D1 opened offer.html file and edited  line number 71 and 78.

















[root@devopsvm01 html]# git status
On branch D1
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   offer.html

no changes added to commit (use "git add" and/or "git commit -a")
[root@devopsvm01 html]# git add .
[root@devopsvm01 html]#
[root@devopsvm01 html]# git commit -m "Change made on offer.html by Developer1 on D1"
[D1 dde4d9f] Change made on offer.html by Developer1 on D1
 1 file changed, 2 insertions(+), 2 deletions(-)
[root@devopsvm01 html]#
[root@devopsvm01 html]# git push origin D1

Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 318 bytes | 318.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote:
remote: Create a pull request for 'D1' on GitHub by visiting:
remote:      https://github.com/mahekarthya/devops-demo-pvt/pull/new/D1
remote:
To github.com:mahekarthya/devops-demo-pvt.git
 * [new branch]      D1 -> D1
[root@devopsvm01 html]#
[root@devopsvm01 html]#


Now create a pull request from github

Select D1 branch and initiate pull request
























The code change is 

















Click Create Pull request



























At this stage there is no conflict
































Now Developer2 (D2) came and he spin off a new branch and edited same file and same line

[root@devopsvm01 html]# git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean
[root@devopsvm01 html]#
[root@devopsvm01 html]# git checkout -b D2
Switched to a new branch 'D2'
[root@devopsvm01 html]#

[root@devopsvm01 html]# vi offer.html

After edit :-

















[root@devopsvm01 html]# git status
On branch D2
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   offer.html

no changes added to commit (use "git add" and/or "git commit -a")
[root@devopsvm01 html]#
[root@devopsvm01 html]# git add .
[root@devopsvm01 html]#
[root@devopsvm01 html]# git commit -m "Change made on offer.html by Developer2 on D2"
[D2 626ef13] Change made on offer.html by Developer2 on D2
 1 file changed, 2 insertions(+), 2 deletions(-)
[root@devopsvm01 html]#
[root@devopsvm01 html]# git push origin D2

Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 327 bytes | 163.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
remote:
remote: Create a pull request for 'D2' on GitHub by visiting:
remote:      https://github.com/mahekarthya/devops-demo-pvt/pull/new/D2
remote:
To github.com:mahekarthya/devops-demo-pvt.git
 * [new branch]      D2 -> D2
[root@devopsvm01 html]#
[root@devopsvm01 html]#


Now login to github and initiate pull request 
























Code change made in D2 is below 
















Raise a pull request now 



























No conflict at this stage as well 

































There are two pull request now 


















Let's merge the pull request from D2, simultaneously open the pull request from D1





























Pull request successfully merged and closed from D2































And offer.html in the main branch is updated with D2's pull request




























Now if you look at the Pull request from D1, you could see a conflict detected there 






























So what happened here is,

D1 created a PR → from D1 branch → to main  (At that time, main was at commit A)

D2 also created a PR → from D2 branch → to main (At that time, same base commit A)

Both showed “No conflict” initially, because both started from the same base.

Then :

D2’s PR got merged first, so main moved from commit A → B.
 
Now D1’s PR is still open — but its base (main) has changed and it reports conflict. 


Now we can resolve the conflict either from the UI or from command line 


To fix the conflict from UI, Click on resolve conflict and make necessary changes manually, like removing the unnecessary/unintended code change .






























And manually make the changes.



























Suppose if you want to keep the changes from D1 , edit file like below and click and mark as resolved 

























Resolving the conflict from command line

Update the main branch first.

[root@devopsvm01 html]# git status
On branch D2
nothing to commit, working tree clean
[root@devopsvm01 html]#
[root@devopsvm01 html]# git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
[root@devopsvm01 html]#
[root@devopsvm01 html]# git pull
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (1/1), 904 bytes | 904.00 KiB/s, done.
From github.com:mahekarthya/devops-demo-pvt
   2f6b922..c3f57f8  main       -> origin/main
Updating 2f6b922..c3f57f8
Fast-forward
 offer.html | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
[root@devopsvm01 html]#
[root@devopsvm01 html]# cat offer.html | grep -i 500
        <p class="price">**Your Price Today: $500** (50% Off!)</p>
[root@devopsvm01 html]#

Now you can see the changes from D2 in your main branch 


[root@devopsvm01 html]# git checkout D1
Switched to branch 'D1'
[root@devopsvm01 html]# cat offer.html | grep -i 500
[root@devopsvm01 html]#
[root@devopsvm01 html]# git rebase main
Auto-merging offer.html
CONFLICT (content): Merge conflict in offer.html
error: could not apply dde4d9f... Change made on offer.html by Developer1 on D1
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
hint: Disable this message with "git config advice.mergeConflict false"
Could not apply dde4d9f... Change made on offer.html by Developer1 on D1
[root@devopsvm01 html]#
[root@devopsvm01 html]#
[root@devopsvm01 html]#  cat offer.html | grep -i 500
        <p class="price">**Your Price Today: $500** (50% Off!)</p>
[root@devopsvm01 html]#
[root@devopsvm01 html]#  cat offer.html | grep -i 1000
        <p class="price">**Your Price Today: $1000** (50% Off!)</p>
[root@devopsvm01 html]#
[root@devopsvm01 html]#


Now edit offer.html and remove conflict or modify the file all together as per your wish. 

[root@devopsvm01 html]# vi offer.html

[root@devopsvm01 html]# cat offer.html  | grep -i 'Price Today'
        <p class="price">**Your Price Today: $1000** (50% Off!)</p>
[root@devopsvm01 html]#

[root@devopsvm01 html]# git status
interactive rebase in progress; onto c3f57f8
Last command done (1 command done):
   pick dde4d9f Change made on offer.html by Developer1 on D1
No commands remaining.
You are currently rebasing branch 'D1' on 'c3f57f8'.
  (fix conflicts and then run "git rebase --continue")
  (use "git rebase --skip" to skip this patch)
  (use "git rebase --abort" to check out the original branch)

Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
        both modified:   offer.html

no changes added to commit (use "git add" and/or "git commit -a")
[root@devopsvm01 html]#


We can also use git diff to see the difference  at his stage 

[root@devopsvm01 html]# git add .
[root@devopsvm01 html]#
[root@devopsvm01 html]# git rebase --continue

it will open up a vi editor , we need to save it 























[root@devopsvm01 html]# git rebase --continue
[detached HEAD 930b148] Change made on offer.html by Developer1 on D1
 1 file changed, 5 insertions(+), 5 deletions(-)
Successfully rebased and updated refs/heads/D1.
[root@devopsvm01 html]#

Let's try to push to remote D1

[root@devopsvm01 html]# git push origin D1

To github.com:mahekarthya/devops-demo-pvt.git
 ! [rejected]        D1 -> D1 (non-fast-forward)
error: failed to push some refs to 'github.com:mahekarthya/devops-demo-pvt.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. If you want to integrate the remote changes,
hint: use 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
[root@devopsvm01 html]#
[root@devopsvm01 html]#

The error message: ! [rejected] D1 -> D1 (non-fast-forward) means that the remote branch D1 has commits that your local D1 branch does not have (or, more accurately, your local branch's history has diverged from the remote). After a rebase, this is expected because rebase rewrites the history of your local branch.

Since your local branch D1 now has a completely different history than the remote D1 (even if the final file content is similar), a standard git push is rejected.

To overcome this we needs to use git push with -f option.

[root@devopsvm01 html]# git push origin D1 -f
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 374 bytes | 187.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:mahekarthya/devops-demo-pvt.git
 + dde4d9f...930b148 D1 -> D1 (forced update)
[root@devopsvm01 html]#
[root@devopsvm01 html]#

Now the D1's pull request is no longer reported conflict




























Finally merge the pull request

































And code is reflected in the main branch






















































`









 


No comments:

Post a Comment

Building a Safer PostgreSQL CI/CD Pipeline with GitHub Actions: Dev → PR Review → Test Promotion

In my previous post, we explored a simple push-to-main deployment strategy . While functional, that model is not considered an industry best...