DEV Community

Cover image for Understanding Why `main` and `dev` Diverged
dravid p a
dravid p a

Posted on

Understanding Why `main` and `dev` Diverged

Scenario

You were working on the dev branch.

While you were making commits locally, someone (or you) also made changes directly to the main branch on GitHub.

As a result, both branches moved forward independently.


What Happened?

Initial State

A (common commit)
│
├── main
└── dev
Enter fullscreen mode Exit fullscreen mode

Both branches point to the same commit.


Changes Added to Main

A ── B ── C   (main)
│
└───────────  (dev)
Enter fullscreen mode Exit fullscreen mode

Example:

  • B = README update
  • C = CodeQL update

Changes Added to Dev

A ── B ── C          (main)
│
└── D ── E ── F      (dev)
Enter fullscreen mode Exit fullscreen mode

Example:

  • D = Base crawler
  • E = Class-based crawler
  • F = Concurrency implementation

Now both branches contain unique commits.

This situation is called:

Branches have diverged.


Why git pull main Did Not Work

Many developers think:

git pull main
Enter fullscreen mode Exit fullscreen mode

means:

"Pull changes from main branch"

But Git interprets it differently.

main is only a local branch name.

Git expects:

git pull <remote> <branch>
Enter fullscreen mode Exit fullscreen mode

Example:

git pull origin main
Enter fullscreen mode Exit fullscreen mode

Where:

  • origin = GitHub repository
  • main = branch on GitHub

Correct Way to Update Dev

While on the dev branch:

git fetch origin
git merge origin/main
Enter fullscreen mode Exit fullscreen mode

What Does git fetch Do?

git fetch origin
Enter fullscreen mode Exit fullscreen mode

Downloads the latest information from GitHub.

Before fetch:

Local Git:
main -> C

GitHub:
main -> G
Enter fullscreen mode Exit fullscreen mode

After fetch:

main         -> C
origin/main  -> G
Enter fullscreen mode Exit fullscreen mode

Git now knows about the latest remote commits.

No files are changed yet.


What Does git merge origin/main Do?

git merge origin/main
Enter fullscreen mode Exit fullscreen mode

Git combines:

dev
+
latest main
Enter fullscreen mode Exit fullscreen mode

Before merge:

A ── B ── C          (origin/main)
│
└── D ── E ── F      (dev)
Enter fullscreen mode Exit fullscreen mode

After merge:

A ── B ── C
│         \
│          M      (dev)
│         /
└── D ── E ── F
Enter fullscreen mode Exit fullscreen mode

M = Merge Commit

Now dev contains:

  • All main changes
  • All dev changes

If Merge Conflicts Occur

Git may stop and show:

CONFLICT
Enter fullscreen mode Exit fullscreen mode

Example:

Both branches modified:

README.md
Enter fullscreen mode Exit fullscreen mode

Git cannot decide which version to keep.

You must manually fix the file.

After fixing:

git add .
git commit
Enter fullscreen mode Exit fullscreen mode

Git creates the merge commit.


Push Updated Dev

git push origin dev
Enter fullscreen mode Exit fullscreen mode

Now GitHub receives the merged version.

main -> C

dev -> M
Enter fullscreen mode Exit fullscreen mode

Create Pull Request

dev  --->  main
Enter fullscreen mode Exit fullscreen mode

GitHub PR contains:

  • README updates
  • CodeQL updates
  • Crawler changes
  • Concurrency changes

Everything together.


Alternative Workflow

You may also update your local main first.

git checkout main
git pull origin main

git checkout dev
git merge main

git push origin dev
Enter fullscreen mode Exit fullscreen mode

Result:

latest main
+
latest dev
=
updated dev
Enter fullscreen mode Exit fullscreen mode

Simple Mental Model

Think of branches as two roads.

            main road
          B ── C
         /
A
         \
          D ── E ── F
            dev road
Enter fullscreen mode Exit fullscreen mode

Both roads started from the same place.

Before creating a Pull Request, connect the roads:

            B ── C
           /      \
A                 M
           \      /
            D ── E ── F
Enter fullscreen mode Exit fullscreen mode

Now everything is connected.


Safe Workflow Summary

git checkout dev

git fetch origin
git merge origin/main

# fix conflicts if needed

git add .
git commit

git push origin dev
Enter fullscreen mode Exit fullscreen mode

Create PR:

dev → main
Enter fullscreen mode Exit fullscreen mode

This is the safest and most common workflow when main and dev have diverged.

Top comments (0)