Beginner · 12 min
Git and GitHub, the parts you actually use
Branches, commits, pull requests, and how to not lose your work. Skip the 90% of git you don't need yet.
The mental model
Git is a save-game system for your code. Every commit is a save point — a snapshot of every file in your project at that moment. If you delete something you needed, you rewind to an earlier save. If an experiment blows up, you load the last good save.
Branches are parallel save files. You play out a new idea in one timeline without touching the stable version in another. When the idea works, you merge the timelines. GitHub is just where you upload all of this — cloud storage for your save history, so it survives your laptop dying and other people can see it.
That's the whole mental model. Everything below is just the mechanics.
Why version control, and why right now
Here is what happens to everyone at least once: you spend two hours refactoring something, it gets worse, you want to go back — and you can't. The old code is gone. You're staring at an empty undo history in a text editor that closed and reopened three times since then.
Git solves this permanently. Every commit is a point you can rewind to, no matter how much time has passed or how many times you've opened and closed your editor. It also gives you a full record of what changed and when — useful even when you're working alone, invaluable when you're working with a team.
The mistake is waiting until you "need" it. Set it up on the first day of every project. The overhead is two commands and thirty seconds. Retrofitting version control onto a three-month-old project is annoying. Starting with it costs nothing.
Git vs GitHub — they are not the same thing
Git is a command-line tool that runs on your computer. It tracks changes to files in a folder (called a repository, or repo). It has nothing to do with the internet. It works completely offline.
GitHub is a website that stores your git history in the cloud. It is one of several hosting services — GitLab and Bitbucket are others — but GitHub is by far the most common. When you push your code, you are uploading your local git history to GitHub. When you pull, you are downloading changes from GitHub back to your machine.
You can use Git without GitHub. You cannot use GitHub without Git. Git is the tool. GitHub is the storage.
Creating a repo
There are two ways to start. Either you already have a project folder on your machine, or you're starting fresh on GitHub.
Starting from your machine
Navigate to your project folder in the terminal and run:
git init
That's it — git is now tracking this folder. Next, go to GitHub, create a new repository (the "+" icon in the top right), and copy the URL it gives you. Then connect your local folder to it:
git remote add origin https://github.com/you/your-repo.git git branch -M main git push -u origin main
You only run that three-liner once. After this, a plain git push is enough.
Starting from GitHub
Create the repo on GitHub first, then clone it to your machine:
git clone https://github.com/you/your-repo.git
This downloads the repo and already has the remote configured. Skip the three-liner entirely.
Add, commit, push — your daily loop
This is the sequence you will run dozens of times per week. Get comfortable with it.
First, always check where you stand:
git status
This tells you which files have changed since your last commit. Nothing gets saved until you explicitly tell git what to include. That's what add does — it stages files (marks them for the next commit).
git add . # stage everything that changed git add index.html # or stage a specific file
Now create the save point with a message that describes what you did:
git commit -m "add login form"
That commit lives only on your machine. To upload it to GitHub:
git push
That's the loop. Status, add, commit, push. You'll do it so many times it becomes automatic. The only thing to think about is your commit message — write what you did, not what changed. "add login form" is good. "changes" is useless.
When you need to bring in changes someone else pushed (or that you pushed from a different machine):
git pull
Branches — why and when
Your main branch is your stable code. The thing that works. You protect it by never working directly on it.
Instead, when you start anything new — a feature, a fix, an experiment — you create a branch. It is a copy of main that you can break freely:
git checkout -b add-login-form
Now you are on a separate timeline. Commit as much as you want. If the idea turns out to be wrong, delete the branch and main is untouched. If it works, merge it back. The diagram below shows what that looks like:
In practice, when you're using GitHub you won't run git mergedirectly. You'll push the branch to GitHub and open a pull request — a request to merge your branch into main, with a built-in review interface. Someone (or you) looks at the diff, approves it, and merges it on GitHub.
git push origin add-login-form # then open a pull request on github.com
Three things to know about when to branch:
- New feature.Always branch. Even if you're solo. You want main to stay releasable at all times.
- Experiment or spike.Branch, try it, delete the branch if it doesn't pan out. Zero cost.
- Bug fix. Branch off main, fix it, merge it back. Keeps the fix isolated and easy to track.
The one time you might commit directly to main is when you're early in a project and moving fast alone. But the habit of branching costs almost nothing and pays back every time something goes wrong.
When things break
Git errors are famously intimidating. They are also almost all recoverable. The most common situation: you pulled and git says there are conflicts.
A conflict happens when two branches changed the same line in different ways. Git can't know which version is right — so it marks the collision in the file and asks you to decide:
your-feature branch
const greeting = "Hello"
main branch
const greeting = "Hi"
merged file — git marks the collision, you decide what to keep
<<<<<<< HEAD const greeting = "Hello" ======= const greeting = "Hi" >>>>>>> main
Delete the <<<<<<, =======, and >>>>>>> markers. Keep whichever version is right. Then git add and git commit.
Your job is to delete the markers and keep whichever version (or combination) is correct. Then stage and commit the resolved file. Most editors highlight conflicts in the gutter to make them easier to find.
For everything else: run git statusfirst. It almost always tells you exactly what to do next. If it doesn't, paste the error message into your AI assistant — git errors are well-documented and the fix is almost always one or two commands. Ask for the fix and the explanation. Knowing why something broke means you won't hit it again.