Skip to content

GitHub Engineering

12 min read

Git is a distributed version-control system. It runs on your machine, needs no network, and knows nothing about accounts, permissions, review or automation.

GitHub is an engineering platform built around Git repositories. It adds the parts Git deliberately leaves out: identity, access control, discussion, review, policy, and an API surface that lets all of it be operated by software rather than by hand.

That distinction is not pedantry. It is the single most useful thing to hold in your head while reading this pillar, because almost every confusing GitHub behaviour becomes obvious once you know which of the two systems is responsible for it.

Start GitHub Engineering

A pull request is the clearest example. Nothing in Git knows what a pull request is. There is no pull-request object in .git/, no git pull-request command, and no way to inspect one with plumbing. A pull request is a record on GitHub’s servers that points at two branches and accumulates comments, reviews and check results around the difference between them.

Understanding that explains behaviour that otherwise looks arbitrary:

  • Why a pull request updates when you push. It does not store your changes. It stores a reference to a branch, and recomputes the difference whenever that branch moves.
  • Why closing a pull request does not delete your commits. The commits are Git objects on a branch. The pull request was only a conversation about them.
  • Why you can have a branch with no pull request, and a pull request whose branch was deleted. The two live in different systems with different lifecycles.

Here is the division, stated once, for the whole pillar:

Git ownsGitHub owns
Commits, trees, blobs, tagsPull requests
Branches and other refsIssues and Discussions
Merges and rebasesReviews and approvals
Remotes and transfer protocolsRequired checks and status
Configuration and hooksBranch protection and rulesets
History rewritingMerge queues
Signing (the cryptography)Signature verification badges, CODEOWNERS
Actions, Pages, Releases as a product, Apps, webhooks

The right-hand column is what this pillar teaches. The left-hand column is Git Fundamentals and Modern Git Workflows, and this pillar assumes it.

Why “Engineering” and not “tutorials”

Section titled “Why “Engineering” and not “tutorials””

You can learn to click “New pull request” in about ninety seconds. That is not what this pillar is for.

The interesting question is not how do I open a pull request but what does a team need so that hundreds of pull requests a week merge safely without a human gatekeeper reading every one. That question leads directly to required checks, code ownership, ruleset design, merge queues, and eventually to automation that operates the platform through its API.

That progression — from clicking, to commanding, to scripting, to integrating — is the spine of this pillar.

The automation ladder

A vertical progression of six stages: manual GitHub web interface, then GitHub CLI, then Bash and shell automation, then the REST and GraphQL APIs, then GitHub Apps with webhooks, and finally production integrations.

Manual web interfaceOne person, one action, one repositoryGitHub CLISame actions, from the terminalBash automationRepeatable across many objectsREST / GraphQL APIDirect control, any languageGitHub Apps + webhooksEvent-driven, bounded permissionsProduction integrationsSystems, not scripts

Each rung solves a problem the one below it cannot. The web interface is unbeatable for a single judgement call. The CLI removes the context switch. Shell scripts remove the repetition. The API removes the shell. Apps and webhooks remove the polling, and replace “ask repeatedly whether anything changed” with “be told when it does”.

Most engineers stop at rung two and are perfectly productive. Knowing the whole ladder matters because it tells you which rung a given problem belongs on — and reaching for the wrong one is a common and expensive mistake. Polling the API every minute to see whether a pull request was merged is a webhook problem being solved with a rate limit budget.

By the end of this pillar you should be able to move from operating a repository by hand to operating it programmatically:

  • Explain precisely which parts of your workflow are Git and which are GitHub, and debug accordingly.
  • Set up repositories, forks, Issues, Discussions, Releases and Pages, and choose between them rather than defaulting to whichever you saw first.
  • Run a pull request through its full lifecycle, including review, requested changes, updates and merge — and know what “approved” does and does not permit.
  • Design repository governance as a system: reviews, code ownership, required checks, rulesets and merge queues, understood as layers rather than a pile of switches.
  • Operate GitHub from the terminal with gh, and write shell automation that is safe to run unattended.
  • Call the REST and GraphQL APIs directly, choose between them on evidence, authenticate correctly, and stay inside rate limits.
  • Decide between a personal access token, a GitHub App and a workflow token — and understand why that choice is mostly a security decision.
  1. GitHub Fundamentals

    Repositories, forks, Issues, Discussions, Releases and Pages.

    10 lessons95+ min

  2. Pull Requests

    Review, policy, governance and the mechanics of merging as a team.

    12 lessons120+ min

  3. GitHub CLI

    Operating GitHub from the terminal and scripting it reliably.

    10 lessons100+ min

  4. GitHub API

    REST, GraphQL, authentication, Apps and webhooks.

    10 lessons120+ min

The repository is the unit of everything on GitHub, and most of the platform is features attached to it. This cluster covers creating repositories properly, what visibility actually protects, how forks relate to clones and branches, and the collaboration surfaces: Issues, Discussions, Wikis, Releases and Pages.

It also settles some recurring confusions — forks versus clones, Issues versus Discussions, Wikis versus /docs versus Pages — because choosing the wrong one is cheap to do and expensive to undo.

The largest cluster, and the heart of the pillar. It starts with what a pull request is as a data structure, walks through creating one end to end, then moves into review mechanics and from there into governance: required reviews, branch protection, rulesets, CODEOWNERS and merge queues.

Those last five are usually taught as five unrelated settings pages. They are better understood as one system with layers, which is how this cluster presents them.

gh is not a Git wrapper. Git already has a command line. gh brings the hosted half — pull requests, Issues, runs, releases, the API itself — into the terminal, which is what makes GitHub scriptable without writing an HTTP client.

This cluster covers the command families you will actually use, then turns to writing automation that is robust: structured JSON output instead of parsing human tables, real error handling, and awareness of what happens when a command runs a thousand times instead of once.

Where GitHub becomes programmable infrastructure. REST and GraphQL, authentication as a decision rather than a copied header, fine-grained tokens, GitHub Apps, webhooks, and worked automation for repositories, pull requests and Issues — finishing with a small, honest Python client you could actually maintain.

When something on GitHub behaves unexpectedly, one of these three questions almost always locates the problem.

“Would this still exist if GitHub disappeared tomorrow?” Your commits, branches and tags would. Your pull requests, Issues, reviews and Actions history would not. This is why a git clone is a complete backup of your code and no backup at all of your collaboration. Teams discover this at the worst possible moment, usually during a platform migration.

“Is this changing the repository, or changing a record about the repository?” Merging a pull request changes the repository — it writes a commit. Approving one does not; it writes a review record. Requesting changes does not. Adding a label does not. Only a handful of GitHub actions actually touch Git objects, and knowing which ones do is most of what makes the platform predictable.

“Who is enforcing this rule?” If a push is rejected, Git will tell you it was rejected by the remote — but the reason lives in GitHub’s policy layer. Git has no concept of “this branch requires two approvals”. When a push or merge is blocked, you are looking at branch protection, a ruleset, or an organisation policy, and you debug it in GitHub’s settings rather than in .git/.

Repository governance is where GitHub stops being a convenience and starts being infrastructure. It is also where the platform is most often misunderstood, because the features are presented as separate settings screens rather than as a system.

Repository policy as layers

A hierarchy showing Repository Policy at the top, branching into three components: Rulesets, which contain pull request requirements, review requirements, status check requirements and other repository rules; CODEOWNERS, which maps paths to owners; and Merge Queue, which validates changes against the current base branch before merging.

Repository policyRulesetsCODEOWNERSMerge queuePull request requiredReviews requiredStatus checksCommit rulesMaps paths toowning teamsValidates againstcurrent base

Read as a system, the layers answer different questions. Rulesets answer what must be true before this ref changes. CODEOWNERS answers who is responsible for this part of the codebase. The merge queue answers was this actually tested against what it will land on top of. None substitutes for another, and adding all three to a repository that needs one is its own kind of failure.

The Pull Requests cluster takes these apart one at a time and then puts them back together.

You will get the most from this pillar if you are comfortable with the following. If any are shaky, the linked lesson is the fastest way to fix that.

You should be able toCovered in
Create commits and read historyYour First Git Repository
Explain what a branch actually isGit Branches Explained
Push to and pull from a remoteGit Repository Structure
Describe how a merge differs from a rebaseRebase vs Merge
Work at a terminal without hesitation

You do not need an existing GitHub account to read the pillar, but you will need one to do the exercises. Every exercise uses a disposable repository you create and delete, never a repository anyone depends on.

The clusters are ordered deliberately, and each assumes the one before it. Fundamentals establishes the objects; Pull Requests is the collaboration model built on them; the CLI operates that model from a terminal; the API operates it from code.

That said, they are not all equally urgent for everyone:

  • New to GitHub entirely — read Fundamentals and the first half of Pull Requests, then stop and use them for a while before continuing.
  • Comfortable with pull requests, responsible for a repository — start at Required Reviews and read the governance sequence through to Merge Queues.
  • Automating something specific — the CLI and API clusters stand alone reasonably well, though API Authentication is worth reading before anything else in the API cluster.

How this pillar relates to the previous two

Section titled “How this pillar relates to the previous two”

This pillar leans on the earlier ones rather than repeating them. Where a GitHub feature is a thin layer over a Git mechanism, the Git mechanism is linked, not re-explained.

Some specific connections worth knowing before you start:

These come up constantly, and each one is a boundary confusion in disguise.

“GitHub is a Git backup.” It is a remote, and a remote holds your objects — but pull requests, Issues, review history, Actions logs and release notes live only on the platform. If that history matters to you, it needs exporting through the API, not cloning.

“Forking is how you make a copy.” A fork is a server-side copy that GitHub tracks as related to its upstream, which is what makes cross-repository pull requests possible. If you only want a copy, git clone gives you one. Forks covers when the relationship earns its complexity.

“Approval means it can merge.” Approval is one input. Whether a pull request is mergeable depends on required checks, conversation resolution, code owner requirements, base-branch freshness and any ruleset in force. A pull request can carry five approvals and still be unmergeable, and this surprises people far more often than it should.

“Private repositories keep secrets safe.” Private controls who can read the repository. It does nothing about the fact that a committed credential is now in history, distributed to every clone, and one visibility change or one compromised account away from disclosure. Visibility is access control, not secret management — a point Public vs Private Repositories makes at length because the cost of getting it wrong is unusually high.

“Stars measure quality.” Stars measure attention, at a particular moment, from people who happened to see the repository. They correlate with visibility far more than with correctness, maintenance or fitness for your purpose. Stars treats this honestly rather than pretending the number is meaningless or that it is a ranking.

“The API and the CLI are alternatives.” gh is an API client. Anything the CLI does, the API can do; the CLI is a curated, authenticated, human-shaped front end over it — and gh api gives you the raw surface when the curation gets in the way. Choosing between them is a question about your consumer, not about capability.

Before starting the first cluster, spend ten minutes on this. It costs nothing and it makes the rest of the pillar easier.

Take any repository you have access to and, for each of the following, decide whether it is stored in Git or on GitHub — then verify by looking for it in a fresh clone:

  1. The message of the most recent commit
  2. The description shown at the top of the repository page
  3. The name of the default branch
  4. Who approved the last merged pull request
  5. The contents of .gitignore
  6. The list of open Issues
  7. The tag for the most recent release
  8. The release notes attached to that tag

Clone the repository somewhere temporary and go looking. Anything you can find with git log, git show, git branch or by reading a file is Git’s. Everything else is GitHub’s — and every item in that second group is something this pillar will teach you to read and write programmatically.

Git 2.43 behaves the same today as it did the day it was released. GitHub does not work that way. Features move between plans, interfaces are redesigned, capabilities arrive in preview and occasionally leave again.

This pillar handles that in three ways. It prefers durable explanations over click-by-click instructions, because the concept outlives the button. It states availability constraints explicitly — plan, repository visibility, personal versus organisation ownership — rather than implying every feature is available to everyone. And it links to GitHub’s own documentation for the facts most likely to move, so you can confirm the current position rather than trusting a snapshot.

Where a page documents behaviour GitHub controls, it is marked as platform-sensitive. That is not a disclaimer; it is a maintenance signal, and it tells you which pages to double-check if something on your screen disagrees with something on this one.

Start with GitHub Fundamentals

You’ve learned how GitHub repositories, pull requests, CLI tools and APIs work. Next, automate the engineering lifecycle with builds, tests, workflows, deployments, runners, environments and secure cloud authentication.

Everything in this pillar is what Actions responds to: a push, a pull request opening, a release publishing. The next pillar is what happens automatically when they do.

Continue to GitHub Actions & CI/CD