GitHub is one of the highest-leverage tools a developer can learn, and one of the easier ones to use poorly. If you're returning to development or coming in from another field, the GitHub mental model can feel arbitrary at first — "why do I need to commit AND push?" "what's the difference between a fork and a branch?" "is this safe to use?" This post answers those from zero.
Goal: by the end, you can clone a repo, make changes, push to a branch, open a pull request, evaluate whether a third-party repo is safe to depend on, and understand what configuration management actually means.
What GitHub actually is
GitHub is a hosting service for code repositories. A repository (or "repo") is a folder of files plus a complete history of every change ever made to those files. GitHub stores that folder and history on its servers, lets you collaborate with others, and provides social features (stars, issues, pull requests, discussions) around your code.
GitHub is owned by Microsoft (since 2018) and is currently the dominant hosting platform for open-source software. Alternatives exist (GitLab, Bitbucket, Codeberg) but GitHub has the largest community by a wide margin — this matters when you're trying to find projects to learn from or use.
Git vs GitHub โ the distinction that confuses everyone
These are two different things:
- Git is a piece of software that runs on your computer. It tracks changes to files in a folder. It was created by Linus Torvalds in 2005. Git works entirely offline — you can commit, branch, and view history without an internet connection.
- GitHub is a website that hosts Git repositories on remote servers. It adds the collaboration layer (sharing, code review, issue tracking) on top of Git.
You can use Git without GitHub (just keep everything local). You can't really use GitHub without Git. Most developer tooling treats them as a unit even though they're technically separate.
Core concepts you need to grasp once
Repository (repo)
A folder of files tracked by Git, plus the full history. Your iOS project is a repo. The Linux kernel source code is a repo. A Markdown file with your shopping list could be a repo.
Commit
A saved snapshot of your repo at a moment in time. Each commit has: a unique ID (a long hex string), an author, a timestamp, a message describing what changed, and the changes themselves. Think of a commit as a save-point in a video game.
Branch
A line of development. The default branch (usually called main or master) is the canonical state. You make a new branch when you want to try changes without affecting the main line. Branches let you experiment safely — if it works, you merge back; if it doesn't, you throw the branch away.
Remote
A copy of the repo hosted somewhere else — usually on GitHub. Your local repo on your Mac and the remote repo on GitHub are linked. You push commits from local to remote, and pull commits from remote to local.
Clone
Downloading a remote repo to your local machine, including its full history. This creates a working copy you can edit.
Fork
A personal copy of someone else's repo on GitHub. You can modify your fork freely. Forks are how open-source contributions work — you fork the original, change your copy, then propose your changes back to the original via a pull request.
Pull request (PR) / Merge request
A proposal to merge changes from one branch (often a fork) into another branch (usually the main branch of the original repo). The PR is the unit of code review.
Issue
A tracked discussion item attached to a repo — usually a bug report, feature request, or question. Anyone can open issues on a public repo.
The daily workflow
The 95% case for a working developer. From an existing project (your RDR2 Companion repo, for instance):
# Get the latest changes from the remote
git pull
# (Edit your files however you normally would โ Xcode, VS Code, Claude Code, etc.)
# See what changed
git status
# Stage the specific files you want to commit
git add Views/HomeView.swift Models/User.swift
# Commit them with a clear message
git commit -m "feat: add user greeting to home view"
# Push the commit to GitHub
git push
That's the core loop. Pull (get latest) โ edit โ status (see what changed) โ add (stage specific files) โ commit (save snapshot with message) โ push (send to GitHub).
Why "add then commit" โ why not just commit?
Git separates "I want to include this file in the next commit" (add / staging) from "save the commit" because you often want to commit only some of your changes. You might have edited 5 files but only want to commit 3 of them in one logical commit, and the other 2 in a separate commit. The staging area is where you assemble the commit you want.
Shortcut: git commit -am "message" stages and commits all tracked files in one step. Skips new files.
Commit messages that don't make you look like an amateur
Bad: "stuff," "fixes," "updates," "wip."
Good: "feat: add freemium gate after 4 AI questions," "fix: prevent crash when user has no network," "refactor: extract ClaudeService from view model."
The convention many teams use (Conventional Commits): type: short description, where type is one of feat, fix, refactor, docs, test, chore, style.
Branches and merging
You don't always work directly on main. When the change is non-trivial or you're not sure it'll work out, create a branch:
# Create a new branch and switch to it
git checkout -b feature/onboarding-redesign
# (Make your changes, commit them as usual)
# Push the branch to GitHub
git push -u origin feature/onboarding-redesign
# When the work is done, switch back to main and merge
git checkout main
git pull
git merge feature/onboarding-redesign
git push
# Optional: delete the branch
git branch -d feature/onboarding-redesign
In practice, you usually don't merge directly — you open a pull request on GitHub, which is a chance for code review (even if you're the only reviewer), CI checks, and a clean record of why the change landed.
Branch naming conventions:
feature/short-name— new functionalityfix/short-name— bug fixrefactor/short-name— restructuring without behavior changedocs/short-name— documentation only
Issues and pull requests
Issues
Use issues for: bug reports, feature ideas, "things I need to fix later." Even on your own personal repos, opening an issue is a great way to externalize a TODO so you don't lose it.
Good issue: title describes the problem in one line. Body says what's broken, how to reproduce, what you expected, what actually happened, environment details (iOS version, Xcode version, etc.). For feature ideas: what problem are you solving, what's the proposed approach.
Pull requests
A PR is the proposed merge of one branch into another, with discussion. The flow:
- You push a branch with your changes.
- You open a PR on GitHub from that branch into
main. - The PR shows a diff (what's changing).
- Reviewers can leave comments on specific lines, request changes, or approve.
- CI (continuous integration) runs automated checks — tests, linters, build verification.
- Once approved and passing, you (or a reviewer) clicks "Merge."
- The PR is now part of
main; the branch can be deleted.
Even solo: opening PRs against your own repos forces a moment of review and gives you a clean changelog of what landed and why.
Finding GitHub projects you can use
This is where most beginners get stuck. GitHub has hundreds of millions of repos — how do you find the good ones?
Search strategies
- GitHub search with filters. Search "swift charts" and filter by stars, language, last-updated date. The search box supports operators:
stars:>1000 language:swift pushed:>2026-01-01finds Swift projects with 1000+ stars updated this year. - Trending page (github.com/trending). Daily/weekly trending repos by language. Good for discovering active projects.
- Awesome lists. Curated topic lists, named "awesome-X." Try awesome-swift for iOS / Swift, "awesome-claude" for Claude tools, "awesome-mcp" for MCP servers. Search GitHub for
awesome [topic]. - Stars from people you trust. Find a developer whose taste you respect, look at what they've starred. Their starred-list is a curated reading list.
- Topic pages.
github.com/topics/swift,github.com/topics/ios, etc. — aggregated by GitHub. - Dependency graphs. If a popular project you use depends on something, that dependency is probably worth looking at.
- Ask Claude. "Find me 5 GitHub repos for iOS chart libraries that are still actively maintained in 2026 and have permissive licenses." Claude will search and summarize.
What "good" looks like
Signals of a healthy project:
- Recent commits (last 30-90 days)
- Many resolved issues, not just open ones
- Maintainer responds to issues within a week or two
- README explains what the project does, how to install it, and shows examples
- License file present (and ideally permissive: MIT, Apache 2.0, BSD)
- CHANGELOG or release notes
- Tests exist
- Documentation beyond the README
- Star count is a vague signal — weight it lower than the others
Evaluating a repo before depending on it
Before you add a library to your iOS project, run this checklist:
- License — MIT, Apache 2.0, BSD: fine. GPL: be careful, can require open-sourcing your app. No license: legally treat as "do not use commercially."
- Last commit date — nothing in the last 18 months on a non-trivial library is a yellow flag.
- Open issues count and tone — high count of stale issues with unanswered urgent bugs is a red flag.
- Dependencies — how many transitive dependencies does this pull in? Each is supply-chain risk.
- Security advisories — GitHub shows known CVEs on the repo's Security tab.
- Maintainer — one named person? Anonymous? A company? Long history of other projects?
- Code quality — spot-check the source. Does it look like code you'd be willing to debug if it broke at 2am?
- Production use — the README or wiki often lists who's using it. Big-name users is a confidence signal.
- Alternatives — is this the dominant choice or one of several? Sometimes a slightly-less-popular alternative is better-maintained.
Using GitHub code in your own project
For Swift / iOS, the canonical way is Swift Package Manager (SPM):
- In Xcode: File → Add Package Dependencies
- Paste the GitHub URL of the package
- Choose a version rule (almost always: "Up to Next Major Version")
- Pick the products / targets you want
- Xcode adds it to your project
For non-Swift code (a useful tool, a reference implementation), you have two paths:
- Read it, don't copy it. Use the GitHub repo as a learning resource and write your own version. Often the cleanest path when the code is small.
- Fork it. Make your own copy under your account so you control your destiny. Then add it as a dependency. Now if the upstream is abandoned, your fork still works.
Don't:
- Copy-paste code from a repo without checking the license.
- Add 5 dependencies for tiny features you could write in 30 minutes — each dependency is forever.
- Pin to
mainbranch (you'll get surprise breaking changes). Always pin to a tagged version.
Configuration management explained
Configuration management is the umbrella term for: tracking what version of every piece of software is in your system, knowing what changed when, and being able to roll back to any previous state. Git + GitHub is a configuration management system for source code.
For your iOS work, configuration management touches several layers:
- Source code: Git + GitHub (what we just covered).
- Dependencies: Swift Package Manager pins specific versions in
Package.resolved. - Build settings: stored in your Xcode project file (
.xcodeproj), tracked in Git. - Secrets and environment: NOT in Git — stored on Railway, in
.envfiles outside the repo, or in Keychain. See next section. - Production state: what app version is on the App Store, what backend version is live on Railway, what config is currently deployed. Tracked via tags / releases on GitHub plus deployment platform records.
The mental model: every change of any kind should be recorded somewhere with a timestamp and a reason. When something breaks, you should be able to ask "what changed?" and get a clear answer.
Useful conventions
- Tag releases. When you ship v1.2.0 to the App Store, tag the commit on GitHub:
git tag v1.2.0 && git push --tags. Now you can always check out the exact code that's running for users. - Write changelogs. A
CHANGELOG.mdfile in your repo, updated each release. Two-sentence "what changed" per version. Five minutes per release; pays back forever. - Keep
maindeployable. Don't commit broken code tomain. If it's broken, it's on a branch. - Pin dependencies. Specific versions, not branches.
- Use
.gitignore. A file that tells Git "don't track these patterns." Standard exclusions for iOS:.DS_Store,xcuserdata/,build/,*.xcuserstate, anything containing secrets.
Secrets and what NEVER goes in GitHub
Critical rule: once a secret is in a Git commit, treat it as compromised forever, even if you delete it. Git history is forever. The internet has scrapers that index public GitHub commits for leaked keys within seconds of you pushing.
NEVER commit:
- API keys (Anthropic, OpenAI, App Store Connect, Railway, etc.)
- Database passwords or connection strings
- OAuth client secrets
- Private keys (SSH, signing keys, JWT signing keys)
- Personal user data
.envfiles (add.envto your.gitignorefirst)
If you accidentally commit a secret:
- Immediately rotate it at the source (generate a new API key on Anthropic console, etc.) and disable the old one.
- For public repos, history rewrites won't help — assume it's compromised. Rotation is the only fix.
- For private repos that haven't been shared, you can use
git filter-repoor BFG to scrub history, but still rotate the secret.
GitHub now offers secret scanning that detects common secret formats in commits and alerts you. Enable it on every repo.
GitHub with Claude Code
You already use Claude Code for development. GitHub integrates cleanly:
- GitHub MCP server — enable this and Claude can read your issues, fetch PR comments, open new issues, view repo activity without leaving the chat.
ghCLI — installghvia Homebrew. Claude Code uses it under the hood for many GitHub operations — opening PRs, viewing issues, downloading release artifacts.- Claude Code can write commits for you. "Commit the current changes with an appropriate message" — it'll write the message, stage the files, and commit. You confirm before push.
- Claude Code can open PRs. "Push this branch and open a PR titled X with this description." Done.
- Claude Code can review PRs. "Review the open PRs on this repo and tell me which need attention." It fetches them via
ghand summarizes.
First-month playbook
- Day 1: Make a GitHub account if you don't have one. Set up SSH or HTTPS auth to GitHub from your Mac.
- Day 2: Create your first repo. Could be a personal notes folder — the project doesn't matter, the practice does. Make 5 commits over a few days, each with a real message.
- Week 1: Use a branch + PR for your next iOS feature. Even if it's just you reviewing your own PR.
- Week 1: Install
ghCLI (brew install gh) and authenticate. - Week 2: Read the issues and discussions on three popular iOS / Swift repos. See how successful open-source projects communicate.
- Week 2: Pick one small library you depend on, fork it. Read the source. See if you can understand it.
- Week 3: Open an issue on a project — either a bug report you actually have, or a thoughtful question. See how the maintainer responds.
- Week 4: Make a small contribution — a typo fix in someone's README counts. Open a PR. Get it merged. You're now an open-source contributor.
The mental jump from "GitHub is intimidating" to "GitHub is normal" usually happens in about three weeks of consistent use. Push through.
For the bigger picture on the development toolchain, see Claude at Maximum Efficiency. For iOS-specific workflow, see Shipping RDR2 From Scratch.
- GitHub โ GitHub Docs
- Git โ Official Git documentation
- GitHub CLI โ gh command-line tool
- Conventional Commits โ Commit message specification