🔧 Git & GitHub FoundationHands-On · Part 4 of 7
📖
Concept First
Understand the why before you dive in?
Read the Concept Guide →

Running Project: my-notes

Starting state: one commit on main — notes.txt with "Day 1: Learning Git with RR Skillverse." (Part 2 state).

Ending state: my-notes/ with notes.txt and todos.txt, four commits on main including one merge commit, branch feature/add-todos still present.

Step 1 — Create a Branch

Why: The branch gives you an isolated workspace. Changes made on feature/add-todos do not affect main until you explicitly merge them. Main stays at its current commit the entire time you're working on the branch.

Command:

git switch -c feature/add-todos

Expected output:

Switched to a new branch 'feature/add-todos'

Confirm with:

git branch

Expected output:

* feature/add-todos
  main

The * marks your current branch. Main still exists at its current commit, unmodified.

Self-check: Both branches listed. * is on feature/add-todos.

Step 2 — Make Changes on the Branch

Why: You'll make two changes on this branch: adding a new file AND editing the same line in notes.txt that you'll edit differently on main in Step 4. This is deliberate — it manufactures the conflict.

Part A — Edit notes.txt. Open it in your editor. Change line 1 from:

Day 1: Learning Git with RR Skillverse.

to:

Day 1: Git tracks every change you make.

Part B — Create todos.txt. Create a new file named todos.txt in the my-notes folder with this content:

TODO: read Git & GitHub Part 4

Stage and commit both files:

git add notes.txt todos.txt
git commit -m "Add todos list and update Day 1 note"

Expected output:

[feature/add-todos abc1234] Add todos list and update Day 1 note
 2 files changed, 2 insertions(+), 1 deletion(-)
 create mode 100644 todos.txt

Self-check: Two files changed. todos.txt listed as create mode 100644. Your hash will differ.

Step 3 — Switch Back to Main

Why: You need to make a conflicting edit on main. Switching branches restores main's version of every file in your working directory.

Command:

git switch main

Expected output:

Switched to branch 'main'

Verify that notes.txt reverted:

cat notes.txt       # Mac / Linux / Git Bash
type notes.txt      # Windows CMD

Expected output:

Day 1: Learning Git with RR Skillverse.

The original line is back. todos.txt does not exist in this directory — it only exists on feature/add-todos right now. Git manages your working directory to match the current branch's latest commit.

Self-check: notes.txt shows the original line. todos.txt is not present.

Step 4 — Create a Conflicting Edit on Main

Why: For a merge conflict, the same line in the same file must be changed differently on both branches. You changed line 1 on feature/add-todos. Now change it to something different on main.

Edit notes.txt on main. Change line 1 to:

Day 1: Learning Git — version control starts here.

Stage and commit:

git add notes.txt
git commit -m "Update Day 1 note on main"

Expected output:

[main def5678] Update Day 1 note on main
 1 file changed, 1 insertion(+), 1 deletion(-)

State check: main and feature/add-todos have both diverged from the original commit. Each has one new commit on top of the shared ancestor. Line 1 of notes.txt is different on each branch. A conflict is guaranteed on the next merge.

Self-check: git log --oneline shows 2 commits on main (original + this one).

Step 5 — Attempt the Merge

Why: Merging brings the feature/add-todos work — the todos.txt file and the updated note — into main. Git will handle everything it can automatically and flag only what it cannot resolve.

Command:

git merge feature/add-todos

Expected output:

Auto-merging notes.txt
CONFLICT (content): Merge conflict in notes.txt
Automatic merge failed; fix conflicts and then commit the result.

Run git status to see the full picture:

git status

Expected output:

On branch main
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Changes to be committed:
        new file:   todos.txt

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   notes.txt

Read the output: todos.txt appears under "Changes to be committed" — Git added it automatically because it only existed on the feature branch. notes.txt appears under "Unmerged paths" because line 1 was changed differently on both branches.

Escape hatch: If you want to abandon this merge entirely and return to the pre-merge state, run git merge --abort now. Nothing is lost; both branches remain intact.

Self-check: todos.txt under "Changes to be committed." notes.txt under "Unmerged paths."

Step 6 — Read the Conflict Markers

Why: Git has annotated notes.txt with markers showing both versions. You need to understand the structure before you can resolve it correctly.

View the file:

cat notes.txt       # Mac / Linux / Git Bash
type notes.txt      # Windows CMD

Expected content:

<<<<<<< HEAD
Day 1: Learning Git — version control starts here.
=======
Day 1: Git tracks every change you make.
>>>>>>> feature/add-todos

Read the three sections:

  • <<<<<<< HEAD — start of the HEAD version (what's on main right now)
  • Everything between <<<<<<< and ======= — the main version of line 1
  • ======= — the divider
  • Everything between ======= and >>>>>>> — the incoming version from the feature branch
  • >>>>>>> feature/add-todos — end of the incoming version

These three marker lines are Git's annotation. Every single one — <<<<<<<, =======, >>>>>>> — must be deleted before the file is correct again. Leaving even one in place is a bug in your content.

Self-check: You can see both versions of line 1 clearly separated by the markers.

Step 7 — Resolve the Conflict and Complete the Merge

Why: Git cannot decide which version is right — that's your call. Combine both intentions into one line, choose one, or write something new. Then tell Git the conflict is resolved by staging the file.

Edit notes.txt in your text editor. Replace the entire conflict block — all three marker lines and both versions — with your resolved content. Example resolution:

Day 1: Learning Git — version control starts here. Every change tracked.

After editing, notes.txt must contain exactly one line of content with no <<<<<<<, =======, or >>>>>>> anywhere in the file.

Stage the resolved file:

git add notes.txt

Complete the merge commit:

git commit -m "Merge feature/add-todos: combine Day 1 note edits"

Expected output:

[main ghi9012] Merge feature/add-todos: combine Day 1 note edits

Self-check: No error output. git status shows a clean working tree. Both notes.txt and todos.txt are now on main.

Step 8 — View the Merge in the Log

Why: git log --oneline --graph renders the branch structure visually. For the first time in my-notes, the history is non-linear — two threads of work converging into one merge commit.

Command:

git log --oneline --graph

Expected output:

*   ghi9012 (HEAD -> main) Merge feature/add-todos: combine Day 1 note edits
|| * abc1234 (feature/add-todos) Add todos list and update Day 1 note
* | def5678 Update Day 1 note on main
|/
* 1234567 Add initial notes file

Read the graph:

  • * — a commit node
  • | — the point where history diverges into two branches
  • |/ — the point where both threads converge back into one (the merge)
  • Left column — main's path; right column — feature/add-todos

The top commit has | immediately below it, confirming it's a merge commit with two parents.

Self-check: Four commits total. Top commit shows your merge message. The graph branches and reconverges exactly once.

State of my-notes at the End of This Post

my-notes/
├── notes.txt    ← "Day 1: Learning Git — version control starts here. Every change tracked."
└── todos.txt    ← "TODO: read Git & GitHub Part 4"

Git history: 4 commits on main (including 1 merge commit)
Branch feature/add-todos: still present, fully merged
  Safe to delete with: git branch -d feature/add-todos

Part 5 starts exactly here — with this folder, these two files, and this four-commit history. Do not delete or reorganise my-notes/ between parts.

🛠
Next Step
Continue the hands-on series.
Go to Part 5: Remote, Push, and Pull →