Git workflow for beginners — branches, commits, and pull requests
There is one Git workflow that 95% of professional engineering teams use. Universities don't teach it. Bootcamps gloss over it. This guide is the practical version — the exact commands, in the exact order, with the exact reasoning behind each one.
Why workflows exist at all
Git lets a hundred engineers work on the same codebase without overwriting each other's changes. The "workflow" is the agreement they make so this actually works in practice. There are several flavors (Git Flow, GitHub Flow, Trunk-Based Development), but for small-to-medium teams — including every internship you'll ever do — there's only one you need to learn first: feature branch workflow.
The rules are simple:
- main is sacred. It always works. Nothing gets pushed directly to it.
- Every change starts as a feature branch off of main.
- You commit changes to your branch.
- You open a pull request when ready.
- A teammate reviews it. CI runs. Once both pass, it merges into main.
That's the whole thing. Everything below is mechanics.
Step 1: Start from a clean main
Before you write a single line of code, sync your local main with the remote.
git checkout main
git pull origin main
Why this matters: if you start a branch from a stale main, you'll have merge conflicts when you try to merge back. Easier to start fresh than fix it later.
Step 2: Create a feature branch
git checkout -b fix/null-email-crash
The -b flag both creates and switches to the branch. The name should describe what you're doing. Most teams use prefixes:
feat/for new features (feat/add-password-reset)fix/for bug fixes (fix/null-email-crash)chore/for tooling, config, or refactor work (chore/upgrade-react-19)docs/for documentation-only changes (docs/update-readme)
Match whatever convention your team uses. If they don't have one, copy this one.
Step 3: Make your changes, then commit
Edit your code. Save. Then check what you changed:
git status
git diff
git status tells you which files changed. git diff shows the actual line-by-line changes. Always run both before committing. You will catch a debug console.log or a hardcoded password roughly once a week, and your reviewers will thank you.
Stage and commit:
git add src/api/users.py
git commit -m "fix: return 400 instead of 500 when email is null"
Notice the commit message format. That's conventional commits — a small format that makes your Git history readable. It's the standard at most professional teams.
Don't git add . blindly — you'll commit junk files. Be specific about what you're staging.
Step 4: Push your branch to the remote
git push -u origin fix/null-email-crash
The -u flag (short for --set-upstream) tells Git "this local branch tracks this remote branch." After the first push, you can just type git push for future updates to this branch.
Step 5: Open a pull request
Go to GitHub. You'll see a yellow banner: "Compare & pull request." Click it. Write a description. Click "Create pull request."
What goes in the PR description matters more than most beginners think. We have a whole guide on writing pull requests, but the short version: explain what changed, why, and how to verify it. Three sentences is plenty for small PRs.
Step 6: Respond to review feedback
A reviewer leaves comments. You read them. For each one, you either:
- Make the change. Edit the file, commit, push to the same branch. The PR updates automatically.
- Discuss. Reply explaining your reasoning. Don't argue — explain.
- Ask for clarification if you don't understand the comment.
When you commit fixes during review, the convention is to use a clear commit message: fix: address review — handle empty string case. Some teams squash all PR commits at merge time, so it doesn't matter how messy your in-PR commits are. Other teams keep them all. Ask your team which convention applies.
Practice the whole loop, end to end
InternQuest gives you real tickets, an in-browser IDE, and an automated PR reviewer. Branch, commit, push, get feedback, fix it, merge — same flow as a real internship. Free.
Try a mission →Step 7: Merge and clean up
Once your PR is approved and CI is green, merge it. Most teams use "Squash and merge" on GitHub, which collapses all your commits into one clean entry on main. Then delete the feature branch — both on GitHub (one click) and locally:
git checkout main
git pull origin main
git branch -d fix/null-email-crash
Done. You shipped.
Common pitfalls (and how to fix them)
"I forgot to branch and committed straight to main"
Don't push. While your changes are still local-only, fix it:
# Create a branch from current state (your commits come with it)
git checkout -b fix/my-thing
# Reset main back to where the remote is
git checkout main
git reset --hard origin/main
# Switch back to your branch and continue
git checkout fix/my-thing
If you already pushed to main directly — talk to your team lead. Don't try to fix it solo.
"main has new commits and my branch is behind"
This happens when someone else merges while your PR is open. Sync your branch:
git checkout main
git pull origin main
git checkout fix/your-branch
git merge main # or: git rebase main
Resolve any conflicts that come up, commit, push. The PR updates.
"I committed something I didn't mean to"
If it's the most recent commit and you haven't pushed:
# Undo the commit but keep the changes staged
git reset --soft HEAD~1
# OR undo the commit AND discard the changes (careful!)
git reset --hard HEAD~1
If you already pushed: don't --force push to a shared branch. Instead, make a new commit that reverses the bad change (git revert <commit-hash>).
"Merge conflict, no idea what to do"
Git marks the conflicting sections in the file with <<<<<<<, =======, and >>>>>>>. Open the file, decide which version to keep (or write a hybrid), delete the marker lines, save. Then:
git add <file>
git commit # message is auto-filled
The 12 commands you'll use 99% of the time
| Command | What it does |
|---|---|
git status | Show what's changed and what's staged |
git diff | Show line-by-line changes |
git checkout main | Switch to main |
git pull | Get latest changes from remote |
git checkout -b <name> | Create and switch to new branch |
git add <file> | Stage a file for commit |
git commit -m "<msg>" | Commit staged changes |
git push -u origin <branch> | Push branch first time |
git push | Push subsequent updates |
git log --oneline | Show commit history compactly |
git merge <branch> | Merge another branch into yours |
git branch -d <name> | Delete a local branch (after merge) |
Memorize these. The rest you can Google when you need them.
What to do next
Reading about Git is the worst way to learn Git. The only way to get fluent is to do the workflow on real codebases — not toy tutorials.
- Clone an open-source project and try to fix one "good first issue."
- Set up a personal repo and use the full workflow even when you're working alone.
- Or use InternQuest's missions, which simulate the entire flow with realistic codebases and an automated reviewer.
Practice on real, broken code
InternQuest gives you 150+ pre-broken codebases — each with a real bug to find and fix. You branch, commit, open a PR, get reviewed, merge. The full Git loop, no setup, free.
Start your first mission →