Skip to content

Git, Linux & DevOps

Git and GitHub

Git is a distributed version control system that records the history of a project as a series of snapshots, letting you undo mistakes, work on features in isolation, and merge changes from multiple people without overwriting each other's work. GitHub is a hosting service for Git repositories that adds a web interface, pull requests, issue tracking and automation on top of Git itself. The two are often mentioned together, but Git works with no GitHub account at all, and GitHub is only one of several places to host a Git repository - GitLab and Bitbucket are others.

Why it matters

It is the baseline expectation on any software team
Almost every professional codebase, open-source or private, is tracked in Git; not knowing basic Git commands is a hard blocker in most interviews and onboarding.
It lets multiple people change the same files without stepping on each other
Branching and merging mean two people can each rewrite the same function in parallel and reconcile the result later instead of taking turns.
It is a safety net for your own mistakes
Every committed snapshot is recoverable, so deleting a file, breaking a working feature, or a bad refactor can be undone by going back to an earlier commit.
Pull requests are where code review actually happens
On GitHub, a pull request is the unit of review: it groups a set of commits, shows a diff, and gives teammates a place to comment before the change reaches the main branch.

Commits are snapshots, not diffs

Git stores a project's history as a series of complete snapshots, not as a chain of incremental differences the way some older tools did. Work happens in three places: the working directory (the files you're editing), the staging area (what you've marked with git add, ready to be committed), and the repository itself (what you've committed with git commit). Splitting 'edit' from 'stage' from 'commit' feels like an extra step at first, but it means a commit can be built deliberately from exactly the changes that belong together, rather than everything that happens to be different at that moment.

Branching and merging

A branch in Git is a lightweight, movable pointer to a commit, which is why creating one is close to instant and costs almost nothing. The usual pattern is to create a branch for a feature or fix, commit to it in isolation from main, and merge it back once it's ready and reviewed. When two branches have changed the same lines, Git can't guess which version is correct and produces a merge conflict, which has to be resolved by a person reading both versions and deciding what the result should be.

Shell
git checkout -b feature/login
# ...edit files...
git add src/login.js
git commit -m "Add email/password validation to login form"
git checkout main
git merge feature/login

The GitHub workflow: pull requests

GitHub adds a review and collaboration layer on top of plain Git. A pull request bundles a branch's commits into a single reviewable unit: it shows the diff against the target branch, lets teammates comment on specific lines, and runs any automated checks (tests, linting) before the change is allowed to merge. Contributors without write access to a repository typically fork it first, creating their own copy, branch and commit there, and open a pull request back to the original.

Shell
git checkout -b fix/typo-readme
# ...edit README.md...
git add README.md
git commit -m "Fix broken install link in README"
git push -u origin fix/typo-readme
# open a pull request from this branch on github.com

Undoing things

Which undo command is right depends on whether the change is still local or already shared with others. git restore can discard uncommitted edits; git revert creates a new commit that undoes an earlier one, which is safe on shared history because it only adds a commit rather than removing one; git reset moves a branch pointer backward and can rewrite history, which is fine on a private branch but risky on one other people have already pulled from.

Mistakes people make here

Committing directly to main on a shared repository
it bypasses review, and if anyone else has already pulled that history, later rewriting it causes conflicts for everyone rather than just the person who made the mistake.
Writing commit messages like 'fix' or 'update'
a message like that is worthless months later when someone (often the same person) needs to know why a change was made, not just that something changed.
Running git add . without checking what's staged first
it can commit secrets, build artifacts, or unrelated debug output; running git status or git diff --staged before committing catches this before it becomes part of the history.
Confusing git pull with git fetch
pull fetches and immediately merges (or rebases), which can create a merge you didn't intend or a conflict at an inconvenient moment; fetch alone lets you look at what changed before deciding to merge.
Force-pushing to a shared branch
git push --force rewrites the remote history other people's clones assume is fixed, silently discarding their view of history and potentially their own commits.

Strengths and trade-offs

Where it is strong

  • Fully distributed: every clone has the complete history, so most operations (log, diff, commit) work offline and don't depend on a server being up.
  • Branching is cheap - a branch is a movable pointer, not a copy of the codebase, so creating dozens of them costs almost nothing.
  • The content-addressed model makes history tamper-evident: changing an old commit changes its hash and every hash after it.
  • GitHub adds review, discussion and automation on top of Git without changing how Git itself works, so the skills transfer to GitLab, Bitbucket or a self-hosted server.

The trade-offs

  • The staging-area model and its vocabulary (rebase, cherry-pick, reflog) is genuinely more to learn than a simpler 'save a version' tool.
  • Rewriting history (rebase, amend, force-push) is powerful but dangerous on branches other people have already pulled.
  • Git tracks line-oriented text well but handles large binary files (images, video, datasets) poorly, since each version is stored in full.
  • A merge conflict has to be resolved by a person reading both versions; Git cannot know which change was intended.

Who needs this

Every developer, on any team of more than one, sooner rather than later. It's reasonable to learn it minimally at first (add, commit, push, pull, branch) and pick up rebasing, cherry-picking and the reflog only when a real situation calls for them.

Questions about git and github

Do I need GitHub to use Git?
No. Git is a standalone tool that works entirely on your own machine; GitHub is a hosting service for Git repositories that adds a web interface, pull requests and automation. You can use Git with no remote at all, or push to GitLab, Bitbucket, or a private server instead.
What's the difference between a fork and a branch?
A branch is a line of development inside one repository, usually used by people with write access to it. A fork is a full copy of a repository under your own account, used when you don't have write access to the original - it's how most open-source contributions start: fork, branch, commit, then open a pull request back to the original repository.
What's the difference between merge and rebase?
Merge creates a new commit that joins two branches' histories together, preserving exactly what happened. Rebase replays one branch's commits on top of another, producing a straight-line history as if they'd been written afterward. Both are legitimate; teams differ on which they prefer, but rebasing commits that are already shared with others rewrites history out from under them and should be avoided.
What does 'main' vs 'master' mean?
They're just names for the default branch; GitHub and most new repositories default to 'main' now, but older repositories and some tools still use 'master'. Neither name has special behavior in Git itself - it's a convention, configurable per repository.

The primary source

Related concepts

← All concept guides