Tutorials Git & GitHub Pro Series Chapter 3

GitHub Like a Pro — Issues, Branch Protection, Releases & the gh CLI

Git + GitHubChapter 3 of the Git & GitHub Pro Series28 minMay 28, 2026Beginner

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.

GitGitHub
The version-control toolA website that hosts git repositories
Runs locally, no internet neededThe cloud "origin" your repo pushes to
Made by Linus Torvalds (2005)A company (now owned by Microsoft)
commits, branches, merge, rebaseissues, 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:

ToolWhat it's for
LabelsCategorise: bug, enhancement, good first issue, priority:high
AssigneesWho's responsible for it
MilestonesGroup issues into a release or sprint ("v2.0")
ProjectsA 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:

RuleEffect
Require a pull requestNo direct pushes — every change must go through a PR.
Require approvalsAt least N reviewers must approve before merge (see Ch 19: Code Review).
Require status checksCI (tests, lint) must be green first — the merge button greys out until then (see the CI chapter).
Require up-to-date branchYour branch must include the latest main before merging (a rebase, Ch 2).
Block force-pushesNobody can rewrite main's history (enforces the Golden Rule from Ch 2).
Loading diagram…

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 explicitly

A 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 VersioningMAJOR.MINOR.PATCH:

BumpWhenExample
PATCHBug fixes, no new features, nothing breaks1.2.0 → 1.2.1
MINORNew features, backward-compatible1.2.1 → 1.3.0
MAJORBreaking changes — existing usage may stop working1.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:

Loading diagram…

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:

CommandWhat it does
gh pr createOpen a pull request from your current branch
gh pr view --webOpen the current branch's PR in the browser
gh pr checksSee if CI is passing on your PR
gh issue listList open issues right in the terminal
gh run list / gh run watchSee / live-follow GitHub Actions runs
gh release create v1.2.0Cut 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

Mental Model — Three Sentences

  1. Git is the local tool (commits, branches); GitHub is the platform on top that adds issues, pull requests, releases, and automation.
  2. Branch protection is why you can't push straight to main on a real repo — it forces changes through PRs that must pass review and CI, and the merge button stays greyed out until they do.
  3. Tags mark immutable versions (named with semver — MAJOR.MINOR.PATCH), GitHub Releases dress a tag up with notes and downloads, and the gh CLI drives all of it from your terminal.

Try It Yourself (15 Minutes)

  1. Install gh (brew install gh), run gh auth login, then gh issue list and gh pr list in one of your repos.
  2. Create an issue (gh issue create), then open a tiny PR whose description says Closes #<that number>. Merge it and watch the issue auto-close.
  3. In a repo's Settings → Branches, add a protection rule on main requiring a PR. Try to git push origin main directly — watch it get rejected.
  4. Tag a commit: git tag v0.1.0 && git push origin v0.1.0. Then gh release create v0.1.0 --generate-notes and look at the Releases page.
  5. 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.

Ch 2: Merge, Rebase, or Squash?Ch 4: Undo Anything in Git
DeliveryModern Delivery PipelineCI/CD, review, runner, and deploy workflows for teams shipping apps and websites safely.Production WebProduction Web Apps SeriesProduction patterns for web apps: caching, rate limiting, webhooks, queues, cron jobs, and idempotency.WebUltimate Web Development SeriesWeb development tutorials for HTML, CSS, JavaScript, Next.js, Workers, databases, and production shipping.

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
5 free articles remainingSubscribe for unlimited access