Skip to content

Instantly share code, notes, and snippets.

@bartdorsey
Created May 22, 2025 17:51
Show Gist options
  • Select an option

  • Save bartdorsey/35ed93901b6e3259b0828c518bec0897 to your computer and use it in GitHub Desktop.

Select an option

Save bartdorsey/35ed93901b6e3259b0828c518bec0897 to your computer and use it in GitHub Desktop.
Git Conflicts Guide

Git Conflict Resolution Guide for Python/FastAPI & Vite Projects

Introduction

Git conflicts occur when multiple developers make changes to the same parts of a file, and Git cannot automatically determine which changes to keep. This guide will help you understand and resolve common conflict scenarios in your Python/FastAPI backend and Vite frontend projects.

Understanding Git Conflicts

What Causes Conflicts?

  • Two or more developers modify the same line(s) in a file
  • One developer deletes a file while another modifies it
  • Changes are made to files that have been moved or renamed
  • Merging branches that have diverged significantly

How Git Shows Conflicts

When a conflict occurs, Git marks the file with conflict markers:

<<<<<<< HEAD
Your current branch's version
=======
The incoming branch's version
>>>>>>> branch-name

Common Conflict Scenarios

1. Python/FastAPI Backend Conflicts

Scenario A: Import Statement Conflicts

Situation: Two developers add different imports to the same file.

Example:

<<<<<<< HEAD
from fastapi import FastAPI, HTTPException
from datetime import datetime
=======
from fastapi import FastAPI, Depends
from typing import Optional
>>>>>>> feature-branch

Resolution Strategy:

  1. Keep both sets of imports if they're all needed
  2. Remove duplicates
  3. Order imports according to PEP 8 (standard library, third-party, local)

Fixed Version:

from datetime import datetime
from typing import Optional

from fastapi import FastAPI, HTTPException, Depends

Scenario B: Endpoint Route Conflicts

Situation: Two developers add different endpoints with the same route.

Example:

<<<<<<< HEAD
@app.get("/users/{user_id}")
def get_user(user_id: int):
    return {"user_id": user_id, "name": "John"}
=======
@app.get("/users/{user_id}")
def fetch_user_details(user_id: str):
    return {"id": user_id, "username": "johndoe"}
>>>>>>> feature-branch

Resolution Strategy:

  1. Discuss with your team which implementation to keep
  2. Consider if both functionalities are needed (maybe create different endpoints)
  3. Ensure consistent data types and response formats

Scenario C: Database Model Conflicts

Situation: Multiple developers modify the same SQLAlchemy model.

Example:

class User(Base):
    __tablename__ = "users"
    
    id = Column(Integer, primary_key=True)
<<<<<<< HEAD
    email = Column(String, unique=True, nullable=False)
    created_at = Column(DateTime, default=datetime.utcnow)
=======
    username = Column(String, unique=True, nullable=False)
    is_active = Column(Boolean, default=True)
>>>>>>> feature-branch

Resolution Strategy:

  1. Usually, you'll want to keep all fields if they serve different purposes
  2. Check for migration conflicts if using Alembic
  3. Ensure the combined model makes logical sense

2. Vite/Frontend Conflicts

Scenario D: Package.json Conflicts

Situation: Different developers add different dependencies.

Example:

{
  "dependencies": {
    "react": "^18.2.0",
<<<<<<< HEAD
    "axios": "^1.4.0",
    "react-router-dom": "^6.11.0"
=======
    "react-query": "^3.39.0",
    "styled-components": "^5.3.0"
>>>>>>> feature-branch
  }
}

Resolution Strategy:

  1. Keep all dependencies unless they conflict
  2. Run npm install or yarn install after resolving
  3. Check for version compatibility

Scenario E: Component Import Conflicts

Situation: Different component imports or structures.

Example:

<<<<<<< HEAD
import Header from './components/Header'
import Footer from './components/Footer'
import Dashboard from './pages/Dashboard'
=======
import Navigation from './components/Navigation'
import Sidebar from './components/Sidebar'
import Home from './pages/Home'
>>>>>>> feature-branch

Resolution Strategy:

  1. Keep all imports if components are different
  2. Check component usage in the file
  3. Ensure no naming conflicts

Scenario F: CSS/Style Conflicts

Situation: Style modifications to the same element.

Example:

.container {
<<<<<<< HEAD
  max-width: 1200px;
  padding: 20px;
  background-color: #f0f0f0;
=======
  max-width: 1400px;
  margin: 0 auto;
  background-color: #ffffff;
>>>>>>> feature-branch
}

Resolution Strategy:

  1. Discuss design decisions with the team
  2. Consider if different styles are for different breakpoints
  3. Use CSS variables for consistent theming

Scenario G: Package-lock.json Conflicts

Situation: The most common and intimidating conflict for new developers - when package-lock.json has conflicts after different developers install packages.

Example:

{
  "name": "frontend",
  "version": "0.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
<<<<<<< HEAD
    "node_modules/axios": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
=======
    "node_modules/react-query": {
      "version": "3.39.0",
      "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.39.0.tgz",
>>>>>>> feature-branch

Resolution Strategy:

  1. NEVER manually edit package-lock.json to resolve conflicts
  2. Delete the package-lock.json file
  3. Re-run the install command:
    rm package-lock.json
    npm install
  4. This regenerates a fresh lock file with all dependencies
  5. Commit the new package-lock.json

3. Configuration File Conflicts

Scenario H: Environment Configuration (.env)

Situation: Different environment variables added.

Example:

<<<<<<< HEAD
DATABASE_URL=postgresql://user:pass@localhost/mydb
REDIS_URL=redis://localhost:6379
=======
DATABASE_URL=postgresql://user:pass@localhost/testdb
JWT_SECRET=my-secret-key
>>>>>>> feature-branch

Resolution Strategy:

  1. Keep all variables if they serve different purposes
  2. Ensure DATABASE_URL points to the correct database
  3. Never commit sensitive data; use .env.example as a template

Special Scenarios

1. Accidentally Committed Files

Scenario I: pycache Directories Committed

Situation: Python cache files were accidentally committed and now cause conflicts.

Signs of this problem:

Untracked files:
  backend/app/__pycache__/main.cpython-39.pyc
  backend/app/api/__pycache__/users.cpython-39.pyc

Resolution:

  1. Remove all pycache directories:

    # From your project root
    find . -type d -name __pycache__ -exec rm -rf {} +
    # Or on Windows
    for /d /r . %d in (__pycache__) do @if exist "%d" rd /s /q "%d"
  2. Add to .gitignore if not already there:

    # Python
    __pycache__/
    *.py[cod]
    *$py.class
    *.so
    .Python
  3. Remove from Git tracking:

    git rm -r --cached __pycache__
    git rm -r --cached "*.pyc"
    git commit -m "Remove Python cache files"

Scenario J: Virtual Environment Committed (.venv/venv/env)

Situation: Someone accidentally committed the entire virtual environment folder.

Why this is bad:

  • Virtual environments can be hundreds of MB
  • They're platform-specific
  • They should be recreated locally

Resolution:

  1. Remove the virtual environment:

    # If it's called .venv
    git rm -r --cached .venv
    # If it's called venv
    git rm -r --cached venv
  2. Update .gitignore:

    # Virtual environments
    venv/
    .venv/
    env/
    ENV/
    virtualenv/
  3. Commit the changes:

    git commit -m "Remove virtual environment from tracking"
  4. Tell team members to recreate their environments:

    python -m venv .venv
    source .venv/bin/activate  # On Windows: .venv\Scripts\activate
    pip install -r requirements.txt

2. Preventing Future Accidents

Pre-commit Checklist

Before committing, always run:

git status
# Look for files that shouldn't be there

git diff --staged
# Review what you're actually committing

Step-by-Step Conflict Resolution Process

1. Identify Conflicts

git status
# Shows files with conflicts in red

2. Open Conflicted Files

Look for conflict markers (<<<<<<<, =======, >>>>>>>)

3. Understand Both Changes

  • Read the code in both sections
  • Understand the intent of each change
  • Consult with team members if needed

4. Resolve the Conflict

Choose one of these approaches:

  • Keep HEAD (your changes): Delete the incoming changes and markers
  • Keep incoming changes: Delete your changes and markers
  • Keep both: Combine both changes logically
  • Rewrite: Create a new solution that incorporates both intents

5. Remove Conflict Markers

Ensure all <<<<<<<, =======, and >>>>>>> markers are removed

6. Test Your Resolution

  • Run your FastAPI backend: uvicorn main:app --reload
  • Run your Vite frontend: npm run dev
  • Ensure both applications work correctly

7. Stage and Commit

git add <resolved-files>
git commit -m "Resolve merge conflicts in [describe what was resolved]"

Best Practices to Minimize Conflicts

1. Communication

  • Inform team members when working on shared files
  • Use feature branches for isolated development
  • Have clear code ownership areas

2. Frequent Updates

# Update your branch regularly
git fetch origin
git merge origin/main  # or git rebase origin/main

3. Small, Focused Commits

  • Make commits that change one thing at a time
  • Write clear commit messages
  • Avoid large, sweeping changes

4. Code Style Consistency

  • Use formatters (Black for Python, Prettier for JS)
  • Follow agreed-upon conventions
  • Use linters to catch issues early

Common Commands for Conflict Resolution

# Abort a merge if things go wrong
git merge --abort

# View the conflict in a three-way diff
git diff --ours   # Your version
git diff --theirs # Their version

# After resolving, continue with rebase
git rebase --continue

# Check what files have conflicts
git diff --name-only --diff-filter=U

# Use a merge tool
git mergetool

Troubleshooting Tips

"I accidentally committed conflict markers"

# Fix the files, then
git add <fixed-files>
git commit --amend

Note, only do this if you have not yet pushed your changes.

"I'm lost in a complex conflict"

# Start over
git merge --abort

"I want to see what changed"

# See the commit history
git log --oneline --graph --all

# See what a specific commit changed
git show <commit-hash>

Conclusion

Git conflicts are a normal part of collaborative development. With practice, resolving them becomes routine. Remember:

  • Don't panic when you see conflicts
  • Take time to understand both changes
  • Communicate with your team
  • Test thoroughly after resolution
  • Learn from conflicts to prevent future ones

The key is to stay calm, be methodical, and remember that Git always keeps your code safe - you can always recover from mistakes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment