GitHub Fundamentals
Topic 32

Repositories on GitHub

GitHub

A GitHub repository is a hosted Git repo plus its settings — visibility, default branch, access, and automation. The Git part is the history you already understand; the settings part is where most of the decisions that bite you later actually get made.

The pattern to internalize is that the settings tab governs behavior the code never reveals. A repo can look identical in two organizations and behave completely differently because one allows force-pushes to main and the other does not, so reading the settings is part of reading the repo.

Visibility

A repository is public, private, or — for organizations owned by a GitHub Enterprise Cloud account — internal, which means readable by every member of the enterprise (across all its organizations) but no one outside it. Public exposes the full history to the world; private restricts it to people you grant access; internal is the enterprise-wide middle ground.

Flipping a private repo to public is effectively irreversible in its consequences. The entire commit history becomes world-readable the instant you switch, including any secret ever committed, and crawlers and forks can capture it before you switch back. Treat the toggle as a one-way door.

The Default Branch

main is more than the branch you see first. It is the base for new pull requests, the branch a fresh git clone checks out, and the target that branch protection rules attach to. Change it and several of those bindings move with it — but only if you update everything that named the old branch.

Renaming the default branch through the settings tab updates open PR bases and redirects, but it does not update your CI config files, external integrations, or branch protection rules that pin a branch name. Those have to be edited by hand, or protection silently stops applying to the new default.

Repository Settings That Matter

The settings that shape day-to-day work are the merge button options (which of merge commit, squash, and rebase are allowed), automatic deletion of head branches after merge, whether force-push to protected branches is permitted, and the archive switch that freezes a repo read-only.

Leaving all three merge methods enabled with no team agreement is how a history becomes an unreadable mix of merge commits, squashes, and rebases. Restricting the button to one method keeps the log uniform enough to reason about.

Templates and Generation

A template repository lets anyone generate a new repo pre-seeded with its files, and the .github/ directory holds special files — issue templates, CODEOWNERS, workflows — that GitHub reads automatically. Cloning with --template copies the tree but strips the history, giving a clean starting point.

Generating from a template is not forking. There is no upstream link, no shared history, and no way to pull later template changes — the new repo is fully independent from the moment it is created.

Forking and Mirroring Settings

Repository settings also control who may fork. For private and internal repos this matters because a fork is a server-side copy outside the original's access controls, and internal visibility specifically governs whether org members can fork into their own namespace. Decide the fork policy before granting broad access, not after a copy already exists.

Common Mistakes
  • Flipping a private repo to public to share it quickly, exposing the entire commit history — including any secret ever committed — to the world instantly.
  • Leaving all three merge methods enabled with no team agreement, so the history becomes a mix of merge commits, squashes, and rebases no one can reason about.
  • Not enabling "automatically delete head branches," letting the branch list accumulate hundreds of stale merged branches.
  • Renaming the default branch without updating CI configs, branch protection, and open PR bases, so protection rules silently stop applying.
  • Using a template repo expecting a fork relationship, when generating from a template severs history and any upstream link entirely.
Best Practices
  • Set the default branch to main and configure branch protection on it before the first collaborator joins.
  • Enable "automatically delete head branches" so the branch list stays clean after every merge.
  • Restrict the merge button to a single method — squash for most teams — so history stays uniform.
  • Build a template repository with a populated .github/ directory for any repo type you create more than twice.
  • Keep secret scanning and Dependabot alerts on in organization-level repository defaults so new repos inherit them.
Comparable toolsGitLab projects with public, internal, and private visibilityBitbucket repositories with workspace-level accessAzure DevOps Repos project-scoped Git repositoriesGitea repositories with template generation

Knowledge Check

Why is switching a private repo to public effectively irreversible?

  • The full history, including any committed secret, becomes world-readable instantly and can be cloned or forked before you switch back
  • GitHub permanently disables the visibility toggle in the repository settings the moment you make the first public-facing change, so the switch can never be flipped a second time
  • Every single commit hash in the entire repository is regenerated on the switch and can never afterward be restored
  • Going public silently deletes all of the private repo's existing branch protection rules with no undo

What is the difference between forking and generating from a template?

  • A fork keeps a link to the upstream and its history; a template-generated repo copies the tree with no history and no upstream link
  • They are identical operations; "generate from template" is just GitHub's newer name for forking
  • A fork strips out the entire commit history, while a template-generated repo is the one that keeps it fully intact
  • A template can only ever generate new repositories inside the exact same organization that owns it, whereas a fork is free to cross organization boundaries

What does the default branch setting actually govern?

  • The base for new PRs, the branch a fresh clone checks out, and the target branch protection attaches to
  • Purely which branch happens to appear at the very top of the branch selector dropdown, with no other effect whatsoever
  • The one single branch that CI workflows are permitted to run on at all, and absolutely nothing else besides that
  • Which single branch is the one permitted to receive force-pushes directly from collaborators

What is the cost of enabling all three merge methods with no team convention?

  • The history becomes a mix of merge commits, squashes, and rebases that is hard to reason about
  • Pull requests take noticeably longer to merge because GitHub recomputes the diff for each enabled method
  • Branch protection rules stop applying to the default branch once all three are on
  • Only the repo owner is allowed to merge once more than one method is enabled

You got correct