How to Use Git and GitHub for Version Control Like a Pro

Stop renaming files "final_v2_REALLY_final.py" — Git remembers every change for you. Learn the six commands that cover 90% of daily work, plus why Git and GitHub aren't the same thing.

How to Use Git and GitHub for Version Control Like a Pro

How to use Git and GitHub for version control (without losing your mind in the first week)

Someone asked me last month why their code kept disappearing. Turned out they were saving over the same file, day after day, with names like final_v2_REALLY_final.py. I laughed. Then I remembered I did exactly the same thing for the first two years of my career.

Version control is what happens when you stop renaming files and start letting a tool remember every change for you. Git is that tool. GitHub is where you put those changes so other people (and future-you) can find them. Learning how to use Git and GitHub for version control is less about memorizing commands and more about building one habit: commit often, push when it matters.

Key takeaways

  • Git runs on your machine; GitHub is a remote host for your repositories. They are two different things. Confusing them is the #1 beginner mistake.
  • You only need about six commands for 90% of daily work: init, clone, add, commit, push, pull.
  • Branches are cheap. Use them for every change bigger than a typo fix.
  • Merge conflicts are not errors. They are Git asking you to make a decision.
  • A .gitignore file saves you from committing secrets, logs, and dependency folders you will regret later.
  • If you push something sensitive by accident, rotate the key immediately. Deleting the commit is not enough.

Git vs GitHub: what is actually the difference?

Git is a distributed version control system. It was written by Linus Torvalds in 2005 to manage the Linux kernel, and it has been the default ever since. GitHub launched three years later as a hosting service built on top of Git.

Here is the distinction that matters in practice. Git works offline. Every commit, branch, and history lookup happens locally on your disk. GitHub is a website that stores a copy of your repository and adds collaboration features on top: pull requests, issues, code review, actions.

Is GitHub version control?

No. GitHub is a platform for hosting Git repositories. The version control itself is Git. You can run Git with zero GitHub account and never touch the internet. GitHub just gives your repository a home that other people can reach.

Think of it this way: Git is the engine, GitHub is the garage where you park the car so your teammates can borrow it.

Why the distributed part matters

Older systems like SVN kept one central server. If that server went down, nobody could commit. Git gives every clone a full copy of the history, which means:

  • You can commit on a plane with no wifi
  • Recovering from a corrupted remote is trivial because any clone is a backup
  • Branching is fast enough that you stop thinking about whether it is "worth it"

That last point changed how I work. On SVN, I avoided branches because merging back was a small nightmare. On Git I create one for a single-line fix without hesitating.

Your first repository, step by step

Install Git from the official site, then open a terminal and check it works:

Your first repository, step by step
  • git --version should print something like git version 2.x.x
  • Set your identity once: git config --global user.name "Your Name" and git config --global user.email "[email protected]"

Skip that second step and your commits will be attributed to a ghost. I have seen this trip people up for weeks.

Start local, then connect to GitHub

In an empty project folder:

  1. git init turns the folder into a repository
  2. Create a file, then git add . to stage it
  3. git commit -m "first commit" records the snapshot

Now create an empty repository on GitHub. Do not let it initialize with a README, or you will have two unrelated histories and your first push will be rejected. Connect the two:

  • git remote add origin [email protected]:user/repo.git
  • git branch -M main
  • git push -u origin main

The -u flag links your local branch to the remote one, so future pushes are just git push.

SSH keys versus HTTPS

You have two ways to authenticate. HTTPS asks for a token every so often. SSH uses a key pair you generate on your machine, and after the initial setup, it never asks again.

Generate the key with ssh-keygen -t ed25519 -C "[email protected]", then paste the contents of the public file into GitHub under Settings → SSH and GPG keys. I resisted this for a year because it sounded complicated. In reality it took four minutes and removed a daily friction point.

The daily workflow you will actually use

Most tutorials dump twenty commands on you at once. Here is what day-to-day work looks like in reality:

TaskCommandHow often I run it
See what changedgit statusConstantly
Stage a specific filegit add path/to/fileMost days
Save a snapshotgit commit -m "message"5-15 times a day
Send to GitHubgit pushEnd of each work block
Get teammates' changesgit pullStart of each session
Create a branchgit switch -c feature/xEvery new task

That is roughly it. Everything else is recovery from a mistake or a collision with someone else's work.

Commit messages: short, imperative, honest

Write "fix login redirect loop" not "fixed stuff". Six months from now, when you are hunting for the change that broke a feature, the message is the only clue you have. I read through my own commit history from 2022 last week and could not tell what half of them did. That is a failure of past-me, not of Git.

Set up .gitignore before your first commit

A .gitignore file tells Git which paths to never track. Add it early, because removing a secret from history is painful.

  • Node projects: node_modules/
  • Python: __pycache__/, *.pyc, .venv/
  • Anything holding credentials: .env, *.pem
  • Your editor's junk: .vscode/, .DS_Store

If a file is already tracked, adding it to .gitignore does nothing. You have to git rm --cached it first.

Branches, merges, and the conflict everyone fears

A branch is a movable pointer to a commit. Creating one costs almost nothing, which is why the standard advice is: branch for everything.

Branches, merges, and the conflict everyone fears

A typical flow

  1. git switch -c fix/payment-timeout creates and switches
  2. Make your changes, commit them
  3. git push -u origin fix/payment-timeout
  4. Open a pull request on GitHub
  5. After review and merge, delete the branch locally and remotely

That last cleanup step is easy to forget. I once had a repository with 47 stale branches, most of them from features shipped months earlier. It made the branch list useless.

What a merge conflict really is

Git is not failing. It is refusing to guess. Two branches changed the same lines, and it wants a human decision.

Open the file, and you will see markers:

  • <<<<<<< HEAD marks your version
  • ======= separates the two
  • >>>>>>> branch-name marks the incoming version

Edit the file down to what you actually want, delete the markers, then git add and git commit. The first time feels scary. The tenth time it is just editing a text file.

The thing that made conflicts rare for me was pulling before starting work. Merging a day of divergence is annoying. Merging five minutes of divergence is trivial.

Stashing, undoing, and the mistakes you will make

You will commit to the wrong branch. You will push something you meant to keep local. These are survivable.

The three undo commands worth memorizing

  • git restore file.txt discards uncommitted changes to one file
  • git reset --soft HEAD~1 uncommits the last commit but keeps the changes staged
  • git revert <hash> creates a new commit that undoes an old one, which is the safe option on shared branches

Avoid git reset --hard on anything you have pushed. It rewrites history, and anyone who already pulled will have a bad afternoon.

Stashing what you are not ready to commit

Mid-feature, someone asks for an urgent fix. You are not ready to commit half-finished work. Run git stash, do the fix, commit it, then git stash pop to get your work back.

I learned this the hard way after committing a broken file to keep my work safe, then forgetting about it. The stash is cleaner.

CLI, VS Code, or a GUI: which should you use?

Honestly? Learn the command line first, then use whatever is fastest for you.

CLI, VS Code, or a GUI: which should you use?

The CLI teaches you what is really happening. GUIs hide the mechanism, and when something goes wrong, you will not know how to fix it. But once you understand the model, tools like VS Code's built-in Git panel or a dedicated client will save you real time on routine staging and reviewing diffs.

InterfaceBest forWeakness
Command lineLearning the model, scripting, any serverLess visual feedback
VS Code built-inEveryday editing and stagingOccasional confusing state display
Dedicated GUIReviewing large diffs, history browsingHides the underlying commands

Where most people go wrong

  • Committing everything in one giant blob at the end of the day. Small commits are easier to revert and easier to review.
  • Never pulling from the remote. You will eventually face a merge from hell.
  • Committing .env files. Rotate the credentials immediately if you do.
  • Treating branches as permanent. They are not meant to live forever.
  • Using GitHub as backup without ever reading the diff. Version control only helps if you use it as one.

The habit that stuck for me was pulling first thing every morning. One command, twenty seconds, and it removed almost every painful merge I used to run into. Version control does not make you a better developer on its own. It just records the evidence, in order, so you can figure out what you did wrong and prove it to yourself. That is already worth the price of admission.

Elliot Marsden

Elliot Marsden

Elliot Marsden is a seasoned network security professional with deep expertise in penetration testing and incident response. He has helped organizations across various sectors strengthen their defenses by identifying vulnerabilities and managing critical security breaches. Known for his practical approach and clear communication, Elliot is dedicated to advancing cybersecurity resilience.

See all articles →

Related articles