⬅️ Phase 1: Beginners • Phase 2: Intermediate • Phase 3: Advanced ➡️ • ⚡ Cheat Sheet
Welcome to Phase 2! When you work alone, committing to a single main branch works for simple scripts. But in real-world software engineering, teams build multiple features simultaneously without breaking production code.
This phase is all about Branches, Merging, Resolving Conflicts, Stashing, and the GitHub Pull Request (PR) workflow.
In Git, a branch is simply a lightweight, movable pointer to a specific commit. When you create a branch, you fork off the main line of development to test ideas, build features, or fix bugs in complete isolation.
gitGraph
commit id: "Initial Commit"
commit id: "Add Navbar"
branch feature-auth
checkout feature-auth
commit id: "Add Login UI"
commit id: "Add Auth Middleware"
checkout main
commit id: "Hotfix: Security Patch"
merge feature-auth
commit id: "Release v1.1"
Modern Git uses the intuitive git switch command (introduced in Git 2.23 as a cleaner alternative to git checkout):
# List all local branches (the * indicates your active branch)
git branch
# List both local AND remote-tracking branches
git branch -a
# Create a new branch (stays on current branch)
git branch feature-login
# Switch to the existing branch
git switch feature-login
# CREATE and SWITCH in one single step (Recommended!)
git switch -c feature-login(Legacy alternative: git checkout -b feature-login)
# Rename current active branch
git branch -m new-branch-name
# Safely delete a local branch (only if already merged)
git branch -d feature-login
# Force delete a local branch (discards unmerged commits)
git branch -D feature-login
# Delete a branch on GitHub remote
git push origin --delete feature-login
# Clean up local references to deleted remote branches
git fetch --pruneOnce your feature branch is tested and ready, merge it back into main.
# 1. Switch to the target branch that receives the changes
git switch main
# 2. Pull the latest changes from GitHub just in case
git pull origin main
# 3. Merge the feature branch into main
git merge feature-login- Fast-Forward Merge: If
mainhas not had any new commits since you branched off, Git simply slides themainpointer forward. No new merge commit is created. - 3-Way Merge (Recursive / ORT): If
mainhas progressed with new commits while you were working onfeature-login, Git combines both histories and creates a Merge Commit tying the two branches together.
flowchart TD
subgraph "Fast-Forward Merge"
FF1["main: A -> B"] --> FF2["feature: C -> D"]
FF2 -.-> FF3["Merged: main moves to D (No extra commit)"]
end
subgraph "3-Way Merge"
M1["Commit A"] --> M2["Commit B (main)"]
M1 --> F1["Commit C (feature)"]
M2 --> MC["Merge Commit M (main)"]
F1 --> MC
end
When you and a teammate edit the exact same line of code in the same file on different branches, Git cannot guess whose code is correct. It will pause the merge and flag a Merge Conflict.
Auto-merging app.js
CONFLICT (content): Merge conflict in app.js
Automatic merge failed; fix conflicts and then commit the result.
Open the conflicted file in your text editor. You will see markers inserted by Git:
<<<<<<< HEAD
// Code on your current branch (e.g. main)
const API_URL = "https://api.production.com";
=======
// Code on the branch you are merging in (e.g. feature-login)
const API_URL = "https://auth.production.com/v2";
>>>>>>> feature-login- Locate the markers: Search for
<<<<<<<in your files (or use VS Code's built-in "Accept Current", "Accept Incoming", or "Accept Both" buttons). - Edit the file: Delete the marker lines (
<<<<<<<,=======,>>>>>>>) and keep the desired code.const API_URL = "https://auth.production.com/v2";
- Stage the resolved file:
git add app.js
- Finalize the merge:
git commit -m "merge: resolve API_URL conflict between main and feature-login"
Tip
Want to cancel a scary merge?
If a merge goes haywire and you want to return to where you started:
git merge --abortImagine you are in the middle of writing unfinished code on feature-cart, and your manager asks you to immediately hotfix a bug on main. You don't want to make an ugly "half-done" commit.
Use git stash to temporarily shelve your uncommitted work:
# 1. Stash your dirty working directory with a helpful label
git stash push -m "WIP: cart checkout redesign"
# 2. Your directory is now clean! Switch to main and fix bug
git switch main
# ... fix bug, commit, push ...
# 3. Return to your feature branch
git switch feature-cart
# 4. View your saved stashes
git stash list
# 5. Restore your stashed changes and remove from stash list
git stash pop# Apply stash changes without deleting from the stash list
git stash apply
# Stash including untracked / newly created files
git stash -u
# Delete the most recent stash
git stash drop
# Clear all stashes completely
git stash clearIn professional teams and open-source projects, developers almost never push directly to main. Instead, they follow the GitHub Flow:
sequenceDiagram
autonumber
actor Dev as Developer
participant Local as Local Repo
participant Remote as GitHub Repo (Origin)
actor Team as Team / Reviewer
Dev->>Local: git switch -c feat/user-profile
Dev->>Local: [Code, git add, git commit]
Dev->>Remote: git push -u origin feat/user-profile
Dev->>Remote: Open Pull Request (PR) on GitHub
Team->>Remote: Review code, leave comments
Dev->>Local: Make requested adjustments & push
Team->>Remote: Approve & Merge PR into main
Dev->>Local: git switch main && git pull origin main
- Pull the latest
main:git switch main && git pull origin main - Create a descriptive feature branch:
git switch -c feat/darkmode-toggle
- Write code, stage, and commit:
git add src/theme.js git commit -m "feat: add dark mode theme switch" - Push branch to GitHub:
git push -u origin feat/darkmode-toggle
- Open Pull Request on GitHub:
- GitHub will show a banner with a "Compare & pull request" button.
- Write a clear description of what changed, why, and how to test.
- Merge & Clean Up:
- Once approved and CI tests pass, merge the PR via the GitHub UI.
- Delete the feature branch locally and remotely.
Before stepping into Advanced Phase 3, make sure you can:
- Create, switch, and delete branches using
git switchandgit branch. - Merge branches and resolve merge conflicts cleanly.
- Use
git stashto shelve and retrieve unfinished work. - Push feature branches to GitHub and open Pull Requests (PRs).