What is Git?
Git is a distributed version control system created by Linus Torvalds in 2005. It tracks changes to files over time, lets multiple people work on the same project without overwriting each other's work, and keeps a complete history of every change ever made.
Unlike older, centralised version control systems, every Git user has a full copy of the project's entire history on their own machine. There is no single point of failure, and almost every operation — browsing history, committing, branching — works entirely offline.
Git vs. GitHub
Git is the tool itself. GitHub (along with GitLab, Bitbucket, and similar services) is a website that hosts Git repositories online and adds collaboration features on top — pull requests, issue tracking, code review. Git works perfectly well with no hosting service at all.
Installing and Configuring Git
git --version
Set your identity — this is attached to every commit you make:
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
Useful one-time settings:
git config --global init.defaultBranch main
git config --global core.editor "code --wait"
git config --list
The Three States
Understanding Git means understanding three areas a file can live in:
| Area | What it holds |
|---|---|
| Working directory | The actual files on disk, as you're editing them |
| Staging area (index) | Changes marked to be included in the next commit |
| Repository (.git) | The permanent, committed history |
A typical change moves through all three: you edit a file in the working
directory, git add it to stage the change, then git commit
to record it permanently in the repository.
Starting a Repository
git init
Or copy an existing remote repository:
git clone https://github.com/user/repo.git
The Basic Workflow
git status
Check what's changed, staged, or untracked. This is the command you'll run most often — get comfortable reading its output.
git add file.txt
git add .
Stage a specific file, or stage everything that's changed.
git commit -m "Add login form validation"
Record the staged changes as a new commit with a message describing what changed.
git log
git log --oneline
git log --oneline --graph --all
View commit history — the last form is especially useful for visualising branches.
Viewing Changes
git diff
Shows unstaged changes — what's different between the working directory and the last commit.
git diff --staged
Shows staged changes — what will actually go into the next commit.
git show HEAD
git show a1b2c3d
Shows the full changes introduced by a specific commit.
Branching
A branch is simply a movable pointer to a commit. Branching lets you work on a new feature or fix without touching the main line of development.
git branch
git branch feature-login
List branches, or create a new one.
git switch feature-login
git checkout feature-login
Switch to a branch. switch is the newer, clearer command; checkout is the older one that still works everywhere.
git switch -c feature-login
Create and switch to a new branch in one step.
git branch -d feature-login
Delete a branch once it's no longer needed (use -D to force-delete an unmerged branch).
Merging
git switch main
git merge feature-login
Merges the changes from feature-login into the branch you're
currently on. If both branches changed the same lines, Git will report a
merge conflict and mark the conflicting sections directly
in the affected files:
<<<<<<< HEAD
your version of the line
=======
their version of the line
>>>>>>> feature-login
Edit the file to resolve the conflict, remove the markers, then:
git add file.txt
git commit
Rebasing
git switch feature-login
git rebase main
Rebasing replays your branch's commits on top of another branch's latest state, producing a cleaner, linear history than a merge would. It rewrites commit history, though, so the golden rule is:
Working with Remotes
git remote -v
List the remotes (usually origin) a local repository is connected to.
git remote add origin https://github.com/user/repo.git
Connect a local repository to a remote one.
git push origin main
Upload local commits to the remote.
git pull origin main
Download and merge remote changes into the current branch. Equivalent to git fetch followed by git merge.
git fetch origin
Download remote changes without merging them — a safer way to see what's new before integrating it.
Undoing Changes
| Situation | Command |
|---|---|
| Discard unstaged changes to a file | git restore file.txt |
| Unstage a file (keep the edits) | git restore --staged file.txt |
| Edit the most recent commit message | git commit --amend |
| Undo a commit, keep the changes staged | git reset --soft HEAD~1 |
| Undo a commit, discard the changes entirely | git reset --hard HEAD~1 |
| Reverse a public commit safely with a new commit | git revert a1b2c3d |
reset --hard permanently discards work with no confirmation. revert is the safer choice for anything already pushed or shared, since it undoes a commit's effect by adding a new commit rather than erasing history.Stashing
Need to switch branches but aren't ready to commit? Stash your changes temporarily:
git stash
git stash list
git stash pop
stash shelves your uncommitted changes and reverts the working directory to the last commit; pop reapplies the most recent stash and removes it from the stash list.
.gitignore
A .gitignore file tells Git which files and folders to never
track — build artefacts, dependency folders, secrets, and local
configuration:
node_modules/
*.log
.env
dist/
__pycache__/
Patterns can use wildcards, target specific paths, or be negated with ! to re-include something an earlier pattern excluded.
Tags
git tag v1.0.0
git tag -a v1.0.0 -m "First stable release"
git push origin v1.0.0
Tags mark a specific commit as significant — most commonly used for release versions.
A Typical Feature Workflow
git switch main
git pull origin main
git switch -c feature-login
# ...make changes...
git add .
git commit -m "Add login form validation"
git push -u origin feature-login
# open a pull request, get it reviewed and merged
git switch main
git pull origin main
git branch -d feature-login
Common Commands at a Glance
| Command | Purpose |
|---|---|
git status | Show working directory and staging state |
git add | Stage changes |
git commit | Record staged changes |
git log | View commit history |
git diff | Show unstaged/staged changes |
git branch | List, create, or delete branches |
git switch / checkout | Change branches |
git merge | Combine branch histories |
git rebase | Replay commits on a new base |
git pull | Fetch and merge from a remote |
git push | Upload commits to a remote |
git stash | Temporarily shelve changes |
git restore | Discard or unstage changes |
git revert | Undo a commit with a new commit |
git reset | Move HEAD, optionally discarding changes |
Best Practices
- Commit small, logical changes rather than one huge commit at the end of the day.
- Write commit messages that explain why, not just what changed.
- Pull before you start new work to avoid unnecessary conflicts.
- Never rewrite (rebase, force-push, amend) history that others have already pulled.
- Use branches for features and fixes — keep
maindeployable at all times. - Add a
.gitignorebefore your first commit, not after secrets have already been committed. - Review
git diff --stagedbefore committing to catch accidental changes.
Learning Roadmap
- Learn the three states: working directory, staging area, repository.
- Master the core loop: status, add, commit, log.
- Get comfortable branching and switching between branches.
- Practice merging and resolving conflicts.
- Learn to work with a remote: push, pull, fetch.
- Understand the difference between reset, revert, and restore.
- Explore rebasing, stashing, and tagging once the basics feel automatic.