Skip to content
LakeBench
ProblemsCommunityPricing
Sign inStart practicing

Infrastructure & Engineering Practices

Progress0/10
x

Git and Linux

  • Git: working tree, index, commit12m
  • Merge conflicts14m
  • PATH, pipes, and exit codes12m

Docker

  • Read a Dockerfile14m
  • Dockerfile bugs: USER root12m

Kubernetes and Terraform

  • Deployment vs CronJob14m
  • Terraform: the missing resource14m

CI/CD

  • CI/CD stages12m
  • CI order on main12m

Capstone

  • Capstone: ship checklist16m
Back to track
  1. Learn
  2. Infrastructure & Engineering Practices
  3. Git and Linux
  4. Merge conflicts

Lesson 2 of 10 · Theory first, then run it

Merge conflicts

pythonbeginner14 min

Overview

Two people edited ingest.py. git pull brings their commit. You edit the markers, git add, then git commit. Still no remote here.

On this page7 sections›
  1. 1The broken result
  2. 2Why this failure matters
  3. 3How to diagnose
  4. 4The fix
  5. 5Common beginner questions
  6. 6What comes next
  7. 7Practice

The broken result

A merge conflict happens when two commits change the same lines in the same file. Git cannot decide which version to keep, so it stops and asks you to resolve the overlap manually. Conflicts are a normal part of teamwork, not an error.

When git pull tries to merge and finds overlapping changes, it writes conflict markers into the file: <<<<<<< marks the start of your version, ======= separates the two sides, and >>>>>>> marks the end of the incoming version. The file is not usable until you remove these markers and keep one coherent version.

Resolution is a human decision, not a magic flag. You read both sides, decide which logic to keep (or combine them), edit the file, then tell Git the conflict is resolved by running git add and git commit.

Why this failure matters

Imagine your team has two engineers working on the same ingest pipeline. One changes the date format, the other changes the column filter. Both push to the same branch. The second push triggers a conflict. If nobody resolves it properly, the pipeline ships with conflict markers in the code and fails at runtime. Production data stops flowing.

Conflict markers are the <<<<<<< / ======= / >>>>>>> lines Git writes into the file. Resolution is not automatic. You edit the file into one coherent version, git add the path so the index drops the conflict state, then git commit to record the merge.

How to diagnose

This tab has no Git remote. The exercise orders four human steps as strings. On your laptop you would run git pull in a clone, open the file, and commit. Do not git commit -a while markers remain; that records the conflict markers as if they were valid code.

Mental model: fetch, merge, edit, record

git fetch downloads commits from the remote. git pull is fetch plus a merge (or rebase, if configured). When both sides changed the same hunk, Git writes markers and leaves the index in a conflicted state. Resolution is: open the file, delete the markers, keep the logic you can defend, git add the path so the conflict flag clears, git commit to record the merge.

Conflict is a stop, not a skip
git pulledit markersgit add ingest.pygit commit

Pull first. Commit last. Add is how the index drops the conflict.

What conflict markers look like

When Git finds overlapping changes, it writes both versions into the file separated by marker lines. Everything between <<<<<<< and ======= is your version. Everything between ======= and >>>>>>> is the incoming version. Your job is to delete the markers and keep the correct logic.

PythonDetecting conflict markers
conflict_file = """
<<<<<<< HEAD
date_col = "order_date"
=======
date_col = "created_at"
>>>>>>> origin/main
"""

def has_markers(text):
    return "<<<<<<<" in text or ">>>>>>>" in text

print(has_markers(conflict_file))

Markers are the product until you delete them

Search the tree for <<<<<<< before you commit.

StepWhy it is hereTrap
git pullBring the other commit onto your branchPushing instead, which rejects or overwrites.
edit conflict markersOne file, no <<<<<<< leftPicking both sides and shipping a syntax error.
git add ingest.pyIndex leaves the unmerged stategit add . of a tree still full of markers.
git commitRecords the mergeCommit while grep still finds the marker.

git status during a conflict lists unmerged paths. That list shrinking to empty is the signal that resolution is complete.

Worked example: unshuffle the four beats

The starter list puts commit first, which is how people accidentally record markers as code. Sorting by a canonical ORDER uses the same rank-map pattern you will see in later lessons. result must be git pull, then edit, then add ingest.py, then commit.

PythonResolve order as data
ORDER = ["git pull", "edit conflict markers", "git add ingest.py", "git commit"]
SHUFFLED = ["git commit", "git add ingest.py", "git pull", "edit conflict markers"]
rank = {name: i for i, name in enumerate(ORDER)}
print(sorted(SHUFFLED, key=lambda name: rank[name]))

Verifying markers are gone

Before committing, always check that no conflict markers remain. This function scans a list of file lines and returns True only when every marker is gone.

PythonCheck before committing
def markers_clean(lines):
    for line in lines:
        if line.strip().startswith("<<<<<<<") or line.strip().startswith(">>>>>>>"):
            return False
    return True

resolved = ["date_col = 'order_date'", "filter_col = 'status'"]
unresolved = ["<<<<<<< HEAD", "date_col = 'order_date'", "=======", "date_col = 'created_at'", ">>>>>>> origin/main"]

print("Resolved:", markers_clean(resolved))
print("Unresolved:", markers_clean(unresolved))

No remote in this tab

A real pull needs an origin remote. Create a repo later, add a remote, and practice a conflict with a second clone. This tab grades the order of steps, not actual Git commands.

git add . during a conflict

Running git add . adds every file, including ones you have not resolved yet. Use git add on specific paths you have actually edited and checked for markers.

Sorting patterns from Core Python

The rank-map sorting pattern (enumerate plus sorted with a key function) appeared in Core Python when you sorted custom data. The same technique applies whenever you need to enforce a canonical order.

How this appears on the job

A PR review that says "fix conflicts" means this four-step sequence, not git push --force onto main. Force-pushing main rewrites history and can erase other people's work. Prefer merge commits or rebase on your feature branch.

  • Pull (or fetch plus merge) before you edit.
  • Markers out, then git add, then git commit.
  • Status and a search for <<<<<<< are the done check.

The fix

When git pull finds overlapping edits, resolution is four human steps in a fixed order. The starter shuffles them; you restore the runbook.

Input: four beats that must not be reordered.

stepactionwhy first/last
git pullbring the other commityou cannot merge what you have not fetched
edit conflict markersone coherent filemarkers are not valid code
git add ingest.pyclear unmerged stateindex must leave conflict mode
git commitrecord the mergeonly after markers are gone
PythonUnshuffle the four beats
ORDER = ["git pull", "edit conflict markers", "git add ingest.py", "git commit"]
SHUFFLED = ["git commit", "git add ingest.py", "git pull", "edit conflict markers"]
rank = {name: i for i, name in enumerate(ORDER)}
print(sorted(SHUFFLED, key=lambda name: rank[name]))

Sorted output is pull, edit, add, commit. Commit first would record conflict markers as if they were valid Python.

Output: the canonical resolution order.

positionstep
1git pull
2edit conflict markers
3git add ingest.py
4git commit

Copy-paste without reading the output

Run Sample first. If the numbers or row count look wrong, stop and re-read the previous section before changing code.

Common beginner questions

Why does Git not just pick one side automatically?

Git cannot know which change is correct. The date format change and the column filter change might both be needed, or one might break the other. Only a human reading the code can decide.

What if I want to keep both sides?

You can. Delete only the marker lines (<<<<<<< , =======, >>>>>>>) and keep both blocks of code. Make sure the combined result is valid syntax and correct logic.

Can I avoid conflicts entirely?

You can reduce them by pulling often, working on separate files, and using short-lived feature branches. But conflicts will happen on any team. Learning to resolve them quickly is more valuable than trying to avoid them.

What comes next

The next lesson covers Linux shell fundamentals: PATH, pipes, and exit codes. These are the building blocks of every CI pipeline and deployment script you will write.

Practice

Run Sample and confirm the four-step order. Then complete Exercise: unshuffle SHUFFLED into that order and store it in result.

Practicals · load into the editor

After you read the theory, run these in the pane on the right. They execute in this tab, no cluster.

Rate:
Was this useful?
Git: working tree, index, commitPATH, pipes, and exit codes