The first two chapters were about git — the version-control tool that runs entirely on your machine. This chapter is about GitHub — the website and platform built on top of git. Knowing the difference is itself a pro move, so let's start there, then tour the features that turn commits into a real, coordinated project.
Git vs GitHub: Not the Same Thing
People say them interchangeably; they're not.
| Git | GitHub |
|---|---|
| The version-control tool | A website that hosts git repositories |
| Runs locally, no internet needed | The cloud "origin" your repo pushes to |
| Made by Linus Torvalds (2005) | A company (now owned by Microsoft) |
| commits, branches, merge, rebase | issues, pull requests, Actions, releases |
| Has no concept of a "pull request" | Invented the PR as UI on top of git branches |
You could use git with no GitHub at all (push to a USB drive, or GitLab, or Bitbucket). GitHub adds the collaboration and project layer: a place to discuss, review, automate, and ship. Everything below is GitHub, not git.
Issues: Your Project's To-Do List and Bug Tracker
An issue is a tracked unit of "something to do or fix." Each has a number (#42), a title, a description, and a thread of comments. Pros organise them with:
| Tool | What it's for |
|---|---|
| Labels | Categorise: bug, enhancement, good first issue, priority:high |
| Assignees | Who's responsible for it |
| Milestones | Group issues into a release or sprint ("v2.0") |
| Projects | A kanban board (To do / In progress / Done) across many issues |
The magic trick that makes issues worth using: link a PR to an issue and it closes automatically when the PR merges. Put a keyword in your PR description:
Closes #42(Closes, Fixes, and Resolves all work.) When that PR merges into the default branch, GitHub closes issue #42 and links the two forever. This is how teams keep "what we planned" and "what we shipped" in sync without manual bookkeeping.
Branch Protection: Why Nobody Can Push Straight to main
On a serious repo, you can't just git push origin main. That's not git stopping you — it's a branch protection rule the repo owner set in Settings → Branches. This is the feature behind "the recent stuff on your repo," so it's worth understanding exactly.
A protection rule on main can require any of:
| Rule | Effect |
|---|---|
| Require a pull request | No direct pushes — every change must go through a PR. |
| Require approvals | At least N reviewers must approve before merge (see Ch 19: Code Review). |
| Require status checks | CI (tests, lint) must be green first — the merge button greys out until then (see the CI chapter). |
| Require up-to-date branch | Your branch must include the latest main before merging (a rebase, Ch 2). |
| Block force-pushes | Nobody can rewrite main's history (enforces the Golden Rule from Ch 2). |
Figure 1 — A protected main. The merge button stays disabled until every required gate passes. This is what makes "wait for CI / wait for review" a hard rule, not a polite request.
A related file, CODEOWNERS, auto-requests specific people to review changes in specific folders (e.g. "anyone touching /billing needs Alice's approval"). Pros use it so the right expert always sees the right change.
Tags and Releases: Marking a Version
A tag is a permanent label on a specific commit — unlike a branch, it never moves. You use tags to mark releases:
git tag v1.2.0 # tag the current commit
git push origin v1.2.0 # tags don't push automatically — push them explicitlyA GitHub Release is a tag plus a polished page: release notes, a changelog, and optional downloadable files (a .dmg, a .zip, compiled binaries). It's how projects hand finished versions to users. Tag names almost always follow Semantic Versioning — MAJOR.MINOR.PATCH:
| Bump | When | Example |
|---|---|---|
| PATCH | Bug fixes, no new features, nothing breaks | 1.2.0 → 1.2.1 |
| MINOR | New features, backward-compatible | 1.2.1 → 1.3.0 |
| MAJOR | Breaking changes — existing usage may stop working | 1.3.0 → 2.0.0 |
So a user seeing 2.0.0 knows to read the upgrade notes; 1.2.1 is a safe drop-in. Tags also give you anchors for the App Store / changelog tooling — "everything since tag v1.1.0" is a precise, reproducible range.
Forks: Contributing to Code You Don't Own
You can't push to a repo you don't have write access to (say, an open-source library). The fork-and-PR flow solves this:
Figure 2 — Contributing to someone else's project. A fork is your own GitHub copy of their repo. You push to your fork (which you own), then open a PR asking the original maintainers to pull your changes in. This is how virtually every open-source contribution happens.
The gh CLI: GitHub Without Leaving the Terminal
gh is GitHub's official command-line tool. It does from your terminal what you'd otherwise click through the website for — and it's what you've watched get used on your own repo. A few high-value commands:
| Command | What it does |
|---|---|
gh pr create | Open a pull request from your current branch |
gh pr view --web | Open the current branch's PR in the browser |
gh pr checks | See if CI is passing on your PR |
gh issue list | List open issues right in the terminal |
gh run list / gh run watch | See / live-follow GitHub Actions runs |
gh release create v1.2.0 | Cut a release with notes and attached files |
gh api repos/owner/repo/... | Hit any GitHub API endpoint directly |
Once gh is set up (gh auth login), creating a PR is one line instead of: push, open browser, find the repo, click Compare, fill the form. Pros live in gh because it keeps them in the terminal where the rest of their work already is.
A Few More Pro Bits Worth Knowing
.gitignore— a file listing patterns git should never track (node_modules/,.env,build/). The first line of defence against committing secrets or junk.README.md— rendered on the repo home page; the front door of your project.- GitHub Actions — CI/CD that runs on push. Covered in depth in the web CI chapter and the cost/alternatives chapter.
- Stars / Watch — stars are bookmarks/popularity; watching subscribes you to a repo's notifications.
- Gists — single-file snippets with their own git history; handy for sharing one script.
- GitHub Pages — free static-site hosting straight from a repo.
Mental Model — Three Sentences
- Git is the local tool (commits, branches); GitHub is the platform on top that adds issues, pull requests, releases, and automation.
- Branch protection is why you can't push straight to
mainon a real repo — it forces changes through PRs that must pass review and CI, and the merge button stays greyed out until they do. - Tags mark immutable versions (named with semver — MAJOR.MINOR.PATCH), GitHub Releases dress a tag up with notes and downloads, and the
ghCLI drives all of it from your terminal.
Try It Yourself (15 Minutes)
- Install
gh(brew install gh), rungh auth login, thengh issue listandgh pr listin one of your repos. - Create an issue (
gh issue create), then open a tiny PR whose description saysCloses #<that number>. Merge it and watch the issue auto-close. - In a repo's Settings → Branches, add a protection rule on
mainrequiring a PR. Try togit push origin maindirectly — watch it get rejected. - Tag a commit:
git tag v0.1.0 && git push origin v0.1.0. Thengh release create v0.1.0 --generate-notesand look at the Releases page. - Find an open-source repo, click Fork, and read the steps — you now understand the whole fork-and-PR flow in Figure 2.
Where This Lands in the Series
You can now run git history and drive the GitHub platform around it — issues, protected branches, releases, forks, and the gh CLI. That's the collaboration layer.
The final chapter is the one everyone wishes they'd read first: how to undo anything in git safely. Committed to the wrong branch, need to unstage a file, accidentally reset --hard, lost a commit — there's a clean recovery for every one of them, and (thanks to Ch 1's model) none of them are scary once you know the move.
Ship your apps faster
When you're ready to publish your Swift app to the App Store, Simple App Shipper handles metadata, screenshots, TestFlight, and submissions — all in one place.
Try Simple App Shipper