Sitemap

Git and GitHub: The Beginner’s Guide I Wish I Had

11 min readOct 18, 2026

--

Press enter or click to view image in full size

Why you should care

Git tracks every change in your project, and GitHub lets you share that history with the world. Learn both and you can roll back mistakes, work with a team, and contribute to open source projects used by millions.

Imagine you’re building a project. On day one it looks one way. On day two you add a feature. On day three you rewrite a file, and on day four something breaks. Wouldn’t it be nice to see exactly what the project looked like on day two, who changed what, and when?

That’s what Git gives you: a complete history of your project.

Git vs GitHub

People often mix these up, so let’s settle it.

  • Git is a version control system. It runs on your computer and records every change you make to your files — what changed, who changed it, and when.
  • GitHub is a website that hosts Git repositories online, so people around the world can see your code, copy it, and contribute to it.

Think of it like email. Email is the technology; Gmail, Outlook and Yahoo Mail are platforms that let you use it. Git is the technology; GitHub (along with GitLab and Bitbucket) is a platform built on top of it.

A repository (or “repo”) is simply a project folder whose history Git is tracking.

Why version control matters

Now picture an open source project with hundreds of contributors from different countries, all adding features at the same time. Without a system, sharing code would be chaos: emailing zip files, overwriting each other’s work, no idea who broke what.

Git solves this by keeping a full history of every change and every author. GitHub solves the sharing part. Together, they’re the backbone of modern software development.

Step 1: Install Git and learn a few terminal commands

Download Git from git-scm.com for your operating system. There are GUI clients available, but I strongly recommend learning the command line — it’s what you’ll use at work, and it makes everything else click.

Verify the install:

git --version

Before touching Git, get comfortable with a handful of basic terminal commands:

mkdir project      # create a new folder called "project"
cd project # move into that folder
ls # list what's inside the current folder
ls -a # list everything, including hidden files
touch names.txt # create an empty file
cat names.txt # print the contents of a file
rm names.txt # delete a file
cd .. # go back up one folder

That’s genuinely all you need to follow along.

Step 2: Your first repository and your first commit

Initialize a repository

Inside your project folder, run:

git init

This turns the folder into a Git repository. Run ls -a and you'll see a new hidden folder called .git. That's where Git stores your entire history. Don't edit it by hand — just know it exists.

Check what’s changed

Create a file and ask Git what it sees:

touch names.txt
git status

Git reports names.txt as untracked (shown in red). It notices the file, but it isn't saving its history yet.

The wedding photo analogy: staging and committing

This is the part that confuses beginners, so here’s the analogy that makes it stick.

Picture a wedding. Guests arrive and mingle — their photo hasn’t been taken yet. When it’s their turn, they step onto the stage next to the couple. The photographer clicks, and the picture goes into the wedding album forever. Then the next group steps up.

Map that to Git:

  • Guests mingling = files you changed that Git isn’t tracking yet (untracked or modified).
  • Stepping onto the stage = git add. You're telling Git: "these changes are ready to be saved."
  • The photo click = git commit. The changes are permanently recorded.
  • The wedding album = your project’s history.

Stage your changes

git add names.txt   # stage a single file
git add . # stage everything in the current folder

Run git status again — the file turns green. It's on the stage.

Commit them

git commit -m "Add names.txt"

The -m flag attaches a message. Write messages that describe what changed and why; future you will be grateful.

Run git status once more and you'll see nothing to commit, working tree clean. Everyone's had their photo taken.

The core loop of Git is three commands: git status → git add → git commit. You'll run them hundreds of times a week.

Modify, stage, commit — again

Open names.txt, add a few lines, save it, and run git status. Git shows the file as modified. Stage and commit it the same way. Every commit is a new snapshot in the album.

View the history

git log

Each entry shows a unique commit ID (a long hash), the author, the date, and the message. That’s your project’s full story.

Step 3: Undoing things (because you will make mistakes)

Remove a file from the stage

Added something by accident? Step it back off the stage without losing your changes:

git restore --staged names.txt

The changes are still in your file; they just aren’t queued for the next commit.

Remove commits from history

Say you made a few commits you no longer want. Run git log, find the commit you want to go back to, and copy its hash. Then:

git reset <commit-hash>

Every commit after that one is removed from history. Your file changes aren’t deleted, though — they move back to the “unstaged” area, as if the photos were never taken. You can then re-stage and commit them differently, or discard them.

Stash: put work aside for later

Sometimes you’re halfway through something, and you need a clean project to work on something else — without committing half-finished code.

Think of it as handing your in-progress work to someone backstage: “Hold this, I’ll come back for it.”

git add .
git stash # put your changes aside; working tree is now clean

When you’re ready to continue:

git stash pop      # bring the stashed changes back

And if you decide you don’t need that stashed work at all:

git stash clear    # permanently delete everything in the stash

Be careful with stash clear — there's no getting that work back.

Step 4: Put your project on GitHub

So far everything lives on your laptop. Time to share it.

Create a repository on GitHub

Sign up at github.com, click New repository, give it a name, choose Public or Private, and create it. Don’t add a README yet if you already have a local project.

Connect your local repo to GitHub

Your local repository and the GitHub repository need to know about each other. You do this by adding a remote — a named link to a URL:

git remote add origin https://github.com/<your-username>/<repo-name>.git

origin is just a name, but by convention it always refers to your copy of the repository on GitHub. Check that it worked:

git remote -v

Push your commits

“Pushing” uploads your local commits to the remote:

git push origin main

Read it as: push to origin, on the branch main. (Older repositories call the default branch master; the idea is the same.)

Refresh your GitHub page — your files and full commit history are now online.

Step 5: Branches — work without breaking things

So far every commit has gone in a straight line on the main branch. That's fine when you're alone, but real projects need something better.

Why branches exist

The main branch is the version your users rely on. Code there should be stable and finished. Now imagine you're building a new feature or fixing a bug, and it's half done. If you commit directly to main, users might get broken code.

The rule is simple: whenever you work on a new feature or bug fix, create a separate branch. Your experiments live there, main stays clean, and when the work is ready you merge it back in.

Branches also let many people work at once. You build a login page on one branch while a teammate fixes a payment bug on another, and neither gets in the other’s way.

What is HEAD?

HEAD is a pointer to the branch (and commit) you're currently on. Any new commit you make lands wherever HEAD points.

Create and switch branches

git branch feature        # create a branch called "feature"
git checkout feature # switch to it

Or do both in one step:

git checkout -b feature   # or: git switch -c feature

Now make commits as usual. They’ll live on feature, while main stays exactly where it was. Switch back with git checkout main and you'll see none of the feature work there.

Merge a branch into main

Once the feature is finished and tested:

git checkout main
git merge feature

The feature’s commits now become part of main, and everyone using main gets them. Push the updated branch with git push origin main.

Step 6: Contributing to someone else’s project

This is where Git and GitHub get really exciting: contributing to open source.

Fork: make your own copy

You can’t push directly to a project you don’t own — imagine if anyone in the world could change the code of a popular library! Instead, you fork it.

Get Sarthak Verma’s stories in your inbox

Join Medium for free to get updates from this writer.

Click Fork on the project’s GitHub page. GitHub creates a full copy of the repository under your account. You can do whatever you like with it, and nothing you change affects the original project — until the maintainers approve it.

Clone: download it to your machine

git clone https://github.com/<your-username>/<project>.git
cd <project>

Cloning downloads the repository, its files and its entire history. The URL you cloned from is automatically saved as origin.

Upstream: link to the original project

Your fork is origin. The original project you forked from is, by convention, called upstream. Add it:

git remote add upstream https://github.com/<original-owner>/<project>.git
git remote -v # you'll now see both origin and upstream

You’ll pull new changes from upstream and push your own work to origin.

Open a pull request

A pull request (PR) is you saying to the maintainers: “I’ve made some changes on this branch of my fork — please review them and merge them into your main branch.”

The workflow:

  1. Create a new branch: git checkout -b fix-readme
  2. Make your changes, then git add . and git commit -m "Fix typo in README"
  3. Push the branch to your fork: git push origin fix-readme
  4. On GitHub, click Compare & pull request, describe what you did and why, and submit.

Maintainers review your code, may ask for changes, and discuss it with you in the PR. Once they’re happy, they merge it — and your code becomes part of the project.

Never commit on main

Two rules every contributor learns the hard way:

  • One branch = one pull request. A branch can only have one open PR. Any new commit you push to that branch automatically shows up in that PR.
  • So never work on main. If you commit everything to main, every feature and bug fix piles into the same PR, which makes it impossible to review. Create a fresh branch for every new feature or fix, and open a separate PR for each.

Step 7: Keeping things clean

Remove an unwanted commit from a pull request

Pushed a commit to your PR that you didn’t mean to? Reset it away locally, then force-push:

git reset <hash-of-last-good-commit>
git stash # optional: keep the changes for later
git push origin fix-readme -f # -f = force

A normal push would be rejected, because your local branch now has fewer commits than the online one. The -f flag tells GitHub to overwrite the remote branch with your local version. The PR updates automatically.

Use force-push only on your own branches — never on a shared main.

Keep your fork in sync with the original project

While you work, other people’s PRs are getting merged into the original project. Your fork falls behind — GitHub will tell you something like “This branch is 2 commits behind.”

You can click Sync fork on GitHub, but it’s worth knowing how to do it yourself:

git checkout main
git fetch --all --prune # get all changes, including from upstream
git reset --hard upstream/main # make local main match the original exactly
git push origin main # update your fork on GitHub

Or the shorter version that does the fetch-and-merge in one go:

git pull upstream main
git push origin main

Make this a habit before starting any new branch, so your work is always based on the latest code.

Squash several commits into one

Sometimes you end up with a messy trail — “add file”, “fix typo”, “fix typo again”, “actually fix it”. Before a PR is merged, it’s nice to combine them into a single clean commit. That’s called squashing.

Use an interactive rebase, pointing at the commit before the ones you want to combine:

git rebase -i <hash-of-commit-before-them>

An editor opens listing your commits, each starting with pick. Keep pick on the first one and change the others to s (squash):

pick a1b2c3 Add file 1
s d4e5f6 Add file 2
s g7h8i9 Add file 3

Save and close. Git will ask for a commit message for the combined commit; write one, save, and you’re done. git log now shows one commit instead of three.

Hard reset: throw away changes completely

Remember that git reset keeps your changes as unstaged files? Adding --hard deletes them for good:

git reset --hard <commit-hash>

Your project goes back exactly to that commit. Anything after it is gone. Use with care.

Step 8: Merge conflicts (and why they’re not scary)

A merge conflict happens when two people change the same line of the same file in different ways, and Git can’t decide which version to keep.

Say Rahul and you both edit line 4 of names.txt. Rahul's pull request gets merged first. When yours comes up for merging, Git says: "I have two different versions of line 4 — which one is right?"

Git marks the conflict right inside the file:

<<<<<<< HEAD
Rahul's version of line 4
=======
Your version of line 4
>>>>>>> your-branch

To resolve it:

  1. Open the file and decide what the line should be: Rahul’s, yours, or a combination of both.
  2. Delete the <<<<<<<, ======= and >>>>>>> markers.
  3. Stage and commit the result: git add names.txt then git commit.

GitHub also lets you resolve simple conflicts directly in the browser with a Resolve conflicts button on the pull request. Either way, it’s just a conversation between two versions — you pick the winner.

Cheat sheet

Command

What it does

git init

Start tracking a folder with Git

git status

See what’s changed, staged or untracked

git add .

Stage all changes

git commit -m "msg"

Save staged changes to history

git restore --staged <file>

Unstage a file

git log

View commit history

git reset <hash>

Remove commits after <hash>, keep changes

git reset --hard <hash>

Remove commits and discard changes

git stash / pop / clear

Shelve, restore or delete in-progress work

git remote add origin <url>

Link local repo to GitHub

git push origin <branch>

Upload commits to GitHub

git checkout -b <branch>

Create and switch to a new branch

git merge <branch>

Merge a branch into the current one

git clone <url>

Download a repository

git pull upstream main

Get the latest changes from the original project

git rebase -i <hash>

Squash or reorder commits

What next?

You now know enough to make your first open source contribution. But no amount of reading replaces practice. If you don’t actually run these commands, you’ll get stuck the first time something unexpected happens.

So here’s your homework:

  • Create a repo on your own machine and practice add, commit, reset and stash until they feel boring.
  • Push it to GitHub.
  • Find a beginner-friendly open source project (search GitHub for the good first issue label), fork it, and open your first pull request — even if it's just fixing a typo in the README.
  • Try creating a merge conflict on purpose with a friend, and resolve it.

Once Git stops feeling like magic and starts feeling like a tool, you’re ready for the advanced stuff: cherry-picking, rebasing workflows, and Git hooks.

Happy committing!

If this helped you, give it a clap and share it with a friend who’s just starting out.

--

--