# GitHub ## What GitHub is (context) - Largest host for Git repositories - Central collaboration hub for millions of developers and projects - Commonly used for - Git hosting - Issue tracking - Code review - Other collaboration features - Not part of the Git open source project itself - But very likely you’ll need to interact with it professionally ## Chapter scope (what you’ll learn) - Use GitHub effectively: - Sign up for and manage an account - Create and use Git repositories on GitHub - Contribute to other projects (and accept contributions to yours) - Use GitHub’s programmatic interface (API) - Tips and small features that make workflows easier - If you don’t plan to use GitHub for hosting/collaboration - You can skip ahead to **Git Tools** ## Note: Interfaces change (UI disclaimer) - GitHub UI and screenshots change over time - The *concepts* should remain applicable - Online versions of the book may have newer screenshots --- ## Account Setup and Configuration ### Create a free account (sign-up) - Go to: `https://github.com` - Fill in: - Username (must be unique) - Email address - Password - Click **“Sign up for GitHub”** (green button) - You may see an upgrades/pricing page next - Safe to ignore initially - Verify your email address (GitHub sends a verification email) - Important for later steps/workflows - Account capabilities & plans - Free accounts provide almost all functionality - Paid plans: advanced tools/features + increased limits - More info: `https://github.com/pricing` - Navigation - Clicking the **Octocat** logo (top-left) takes you to your dashboard ### SSH Access (HTTPS vs SSH) - HTTPS remotes - You can connect to Git repos over HTTPS using username/password - Cloning public projects doesn’t require an account - Account becomes important for: - forking projects - pushing to your fork - SSH remotes - Requires configuring an SSH public key - If you don’t have a key yet: generate one (referenced elsewhere in the book) #### Add an SSH key to your GitHub account - Open **Account settings** (link at the top-right) - Select **“SSH keys”** in the left sidebar - Click **“Add an SSH key”** - Provide: - A recognizable **title/name** for the key (helps later revocation) - Example naming patterns: “My Laptop”, “Work Account” - Paste the contents of your public key file (e.g. `~/.ssh/id_rsa.pub`) - Click **“Add key”** ### Your Avatar (profile picture) - Optional customization - Steps - Go to **Profile** tab (in account settings) - Click **“Upload new picture”** - Select an image - Crop it - Effect - Your avatar appears next to your username everywhere you interact on GitHub - Gravatar integration - If you already have a Gravatar avatar, GitHub may use it by default ### Your Email Addresses (commit ↔ account mapping) - How GitHub associates commits with your account - By **email address** in commits - If you commit with multiple emails - Add all of them in the **Emails** section in settings - Email address states (as shown in the example) - Verified + Primary - Receives notifications/receipts - Verified (non-primary) - Can be promoted to primary - Unverified - Cannot be primary - Once added - Any commit on GitHub using one of these emails will link to your user ### Two-Factor Authentication (2FA) - Purpose - Extra security - Reduces impact if password is stolen/compromised - Location - **Security** tab in account settings - Setup - Click **“Set up two-factor authentication”** - Choose a second factor method: - Phone app generating a **time-based one-time password (TOTP)** - SMS code sent each login - After enabling - GitHub requires password + code on login --- ## Contributing to a Project ### Forking Projects (contribute without push access) - Problem: you want to contribute but you can’t push to the upstream repo - Solution: **Fork** - GitHub creates a full copy of the repo under your namespace - You can push to your fork - Terminology note (historical vs GitHub meaning) - Historically “fork” could imply a split/competing direction - On GitHub: “fork” generally means “same project under your account to propose changes” - Why this works well - Upstream maintainers don’t need to add you as a collaborator - You propose changes via a **Pull Request (PR)** - PR becomes a discussion + review thread - Maintainer merges when satisfied - How to fork - Visit the project page - Click **“Fork”** (top-right) - GitHub redirects you to your forked repo page ### The GitHub Flow (PR-centered collaboration model) - Works for: - Small teams sharing a repo - Large distributed groups and many forks - Built around **Topic Branches** (as covered in Git Branching) - Typical sequence 1. Fork the project 2. Create a topic branch from `master` 3. Commit improvements 4. Push the topic branch to your GitHub fork 5. Open a Pull Request 6. Discuss; optionally keep committing to the same branch 7. Owner merges or closes the PR 8. Sync upstream changes back into your fork - Related concept - Similar to the **Integration Manager** workflow, but discussion/review is web-based rather than email-based - Alternative tooling tip - GitHub CLI can do most web-interface tasks - Runs on Windows, macOS, Linux (installation/manual referenced in chapter) --- ## Creating a Pull Request (walkthrough example) ### Scenario - Tony wants Arduino code and finds: `https://github.com/schacon/blink` - Problem - Blink delay is too fast - Goal - Change delay from 1 second to 3 seconds - Submit improvement via PR ### Local workflow steps (fork → branch → change → push) - Fork upstream repo (`schacon/blink`) to your namespace - Example fork URL: `https://github.com/tonychacon/blink` - Clone your fork locally - `git clone https://github.com/tonychacon/blink` - Create a descriptive topic branch - `git checkout -b slow-blink` - Make the code change (example uses `sed`) - macOS: - `sed -i '' 's/1000/3000/' blink.ino` - Linux: - `sed -i 's/1000/3000/' blink.ino` - Review the change - `git diff --word-diff` - Commit - `git commit -a -m 'Change delay to 3 seconds'` - Push the topic branch to your fork - `git push origin slow-blink` - If using HTTPS remote, you may be prompted for GitHub username/password #### Meaning of the numbered actions (as presented in the example) - ① clone fork locally - ② create topic branch - ③ edit code - ④ verify diff - ⑤ commit to topic branch - ⑥ push topic branch to GitHub fork ### Open the Pull Request on GitHub - GitHub notices the new branch on your fork and suggests creating a PR (green button) - Alternative path - Use the Branches page: - `https://github.com///branches` - PR creation page typically shows - Title + description fields (recommended to write clearly) - Commits “ahead” of `master` - Unified diff of all changes that would be merged - After clicking **Create pull request** - The upstream maintainer is notified - They can review and respond ### PRs can be opened early (not only “final” work) - Common in internal/team settings - Because you can keep pushing commits to the PR branch after opening the PR - PR becomes a shared context for iterative development and review --- ## Iterating on a Pull Request (review + updates) ### How review happens on GitHub - Maintainer can: - merge - reject/close - comment (line-level or general) - Line-level comments - Maintainer comments by clicking specific lines in the diff - General comments - In the PR discussion thread - Line comments are also pulled into the overall conversation ### Notifications during PR discussion - PR author and watchers get notified on comments/activity - If email notifications are enabled - Comments may arrive as emails ### Updating an existing PR - GitHub workflow approach - Don’t “re-roll” patches like mailing lists - Instead: - add commits to the same topic branch - push again - PR updates automatically - Old line comments may collapse when code changes (they become “outdated”) - Note about notifications - Adding commits to an open PR does **not** necessarily trigger a notification - Contributors often add a comment saying they pushed updates ### “Files Changed” tab meaning (unified diff) - Shows total aggregate difference introduced by merging the PR branch - Equivalent to: - `git diff master...` (three-dot diff) for the PR base ### Merging the PR (server-side vs local) - GitHub checks if PR merges cleanly - If you have write access and merge is trivial - GitHub shows a merge button - Clicking it performs a **non-fast-forward merge** - Creates a merge commit even if fast-forward was possible - Alternative - Pull the PR branch and merge locally - If you push the merge to GitHub, the PR closes automatically ### Not only forks (internal PRs) - You can open PRs between branches in the same repository - Useful when: - multiple collaborators with write access - you want structured review/discussion without forking --- ## Advanced Pull Requests ### Pull Requests as iterative conversations (vs “perfect patch queues”) - Many GitHub projects view PRs as: - a branch where the change evolves through discussion - culminating in the final unified diff applied via merge - Contrast with mailing-list patch series - Mailing lists often expect a clean sequence of patches - GitHub supports earlier engagement and incremental improvements - Practical implication - Contributors frequently add commits instead of rebasing/resubmitting PRs - Merge commits created by GitHub can reference the PR for traceability --- ## Keeping up with upstream (fixing out-of-date/conflicting PR branches) ### When you need this - PR becomes out of date - GitHub reports: PR “does not merge cleanly” - Goal - Make PR mergeable (green) so maintainers don’t have extra work ### Two main strategies - Rebase onto upstream target branch (usually upstream `master`) - Merge upstream target branch into your topic branch - Common preference on GitHub: - preserves history/context - simpler/less error-prone than rebasing for many teams ### Merge upstream into your topic branch (step-by-step) - Add upstream repo as remote - `git remote add upstream https://github.com/schacon/blink` - Fetch upstream - `git fetch upstream` - Merge upstream main branch into your topic branch - `git merge upstream/master` - Resolve conflicts (if any) - edit conflicting files (example: `blink.ino`) - `git add ` - `git commit` (records the merge) - Push updated topic branch back to your fork/branch - `git push origin slow-blink` - Result - GitHub updates PR and re-checks mergeability automatically ### Long-running work - You can repeat “merge from upstream” regularly - Conflicts are limited to changes since your last merge ### Rebasing caution (especially once PR is open) - If you rebase and force-push over the branch used by an open PR - it can disrupt collaborators who fetched the branch - it can trigger the issues described in “Perils of Rebasing” (referenced) - Recommended alternative if you want a clean rebased history - push rebased commits to a **new** branch - open a **new** PR referencing the old PR - close the original PR --- ## References (cross-linking Issues, PRs, commits) ### Issue/PR number references (within a repository) - Every Issue and PR has a unique number within a project - Quick reference syntax - `#` in comments/descriptions links automatically ### Cross-repo / cross-fork references - In a fork of the repo you’re in: - `username#` - In a different repository: - `username/repo#` - Full GitHub URLs can also be pasted - GitHub renders them as shortened references ### Trackbacks - Mentioning a PR in another PR can create timeline cross-links - Helps connect superseding PRs when one is closed ### Commit references - You can reference a commit by SHA-1 - Requirement in chapter - must use the **full 40-character SHA-1** for auto-linking - Same cross-repo patterns apply (similar to issue references) --- ## GitHub Flavored Markdown (GFM) ### Where it works - PR descriptions - Issue descriptions - Comments - Code comments - Many GitHub text boxes ### What it is - Markdown: plain text that renders richly - GitHub adds extensions beyond base Markdown ### Task Lists - Purpose - Checklist of work items (often “before merge/complete” items) - Syntax - `- [X]` checked - `- [ ]` unchecked - Convenience - Checkboxes can be clicked directly (no need to edit Markdown) - Visibility - GitHub summarizes task progress on PR/Issue list pages - Common usage pattern - Open PR early, track progress via tasks ### Code Snippets (fenced code blocks) - Use cases - propose code ideas before committing - share failing examples - demonstrate intended behavior - Syntax - Fence with triple backticks - Add a language name for syntax highlighting (example: `java`) ### Quoting - Quote lines by prefixing with `>` - Shortcut - Select text in a comment and press `r` to quote it in the reply box ### Emoji - Emoji helper/autocomplete appears when typing `:` - Syntax - `::` (e.g., `:+1:`) - Comment tone - Adds emotion/fun; not essential but commonly used - Emoji cheat sheet link provided - `https://www.webfx.com/tools/emoji-cheat-sheet/` ### Images (drag & drop) - Not strictly a “GFM extension,” but supported - Easier than manually creating Markdown image links - Drag and drop images into comment text areas - GitHub uploads and auto-embeds - “Parsed as Markdown” hint - Provides a cheat sheet of supported Markdown features --- ## Keep your GitHub public fork up-to-date (syncing your fork’s `master`) ### Key point - A fork is independent of the original repo - GitHub may show “X commits behind upstream” - GitHub will not automatically update your fork ### Simple method (no extra configuration) - `git checkout master` - `git pull https://github.com/progit/progit2.git` - fetch + merge into your `master` - `git push origin master` - update your fork on GitHub - Downside - Typing the upstream URL repeatedly is tedious ### Configured method (more convenient) - Add upstream remote - `git remote add progit https://github.com/progit/progit2.git` - Fetch upstream - `git fetch progit` - Set your local `master` to pull from upstream `master` - `git branch --set-upstream-to=progit/master master` - Set default push destination to your fork - `git config --local remote.pushDefault origin` - Then the routine becomes - `git checkout master` - `git pull` - `git push` ### Important caution - With this setup Git won’t warn if you: - commit to `master` - pull from upstream - push to origin - You must treat `master` as “belonging to upstream” - avoid committing directly to `master` --- ## Maintaining a Project ## Creating a New Repository - Entry points - “New repository” button on dashboard - `+` menu in top toolbar → “New repository” - New repository form - Required: repository/project name - All other fields optional - After creation - Repo available as `/` - If empty, GitHub provides instructions to: - create a new repo locally and push - connect an existing repo - (Refresher referenced: Git Basics) - Repo URLs - HTTPS: `https://github.com//` - SSH: `git@github.com:/` - Sharing tip (public projects) - Prefer sharing HTTPS URL - cloning doesn’t require a GitHub account - SSH requires account + SSH key ## Adding Collaborators - Purpose - Grant push access (read + write) - Steps - Repo page → **Settings** - Left menu → **Collaborators** - Add by username → “Add collaborator” - Remove access by clicking “X” next to collaborator --- ## Managing Pull Requests (as a maintainer) ### Where PRs come from - Fork-based PRs - contributor’s branch in their fork - usually you cannot push to their branch - Internal PRs (same repo) - branches inside your repo - typically both sides can push to the branch ### Email notifications (new PR) - Maintainer receives email for a new PR - Email includes - Diffstat (files changed and how much) - Link to the PR on GitHub - Useful command-line URLs/commands - `git pull patch-1` (merge remote branch without adding remote) - `.diff` and `.patch` links for PR content - Example patch application: - `curl https://github.com///pull/.patch | git am` ### Collaborating on the PR (discussion + review) - You can comment on - specific lines - whole commits - general PR discussion - Uses GitHub Flavored Markdown everywhere - Email replies can be included back into the GitHub thread (metadata supports this) ### Merging or closing - Merge locally (various ways) - `git pull ` - or add remote for the fork, fetch, then merge - Merge on GitHub site - If merge is trivial, use **Merge** button - Creates **non-fast-forward** merge commit even if fast-forward is possible - If you decide not to merge - Close the PR - Author is notified --- ## Pull Request Refs (advanced: fetching PRs like branches) ### Motivation - Many PRs → avoid: - adding numerous remotes - repeating one-off `git pull ` operations ### Key idea - GitHub exposes PRs as “pseudo-branches” - They exist under: - `refs/pull/…` - Not fetched by default because normal fetch refspec targets: - `refs/heads/*` ### Discover PR refs on the remote - Use plumbing command: - `git ls-remote ` - You’ll see entries like: - `refs/heads/master` - `refs/pull//head` - `refs/pull//merge` ### Two refs per PR (what they mean) - `refs/pull//head` - points to the tip commit of the PR branch - `refs/pull//merge` - points to the merge commit GitHub would create when using the merge button - useful for testing the would-be merge result ### Fetch a single PR head ref directly - Example - `git fetch origin refs/pull/958/head` - Result - stored in `.git/FETCH_HEAD` - Downsides - repetitive for many PRs - merging `FETCH_HEAD` can produce awkward merge messages ### Fetch all PR heads automatically via refspec - Edit `.git/config` and add a second `fetch =` line under the `origin` remote: - Existing (typical): - `fetch = +refs/heads/*:refs/remotes/origin/*` - Add: - `fetch = +refs/pull/*/head:refs/remotes/origin/pr/*` - After `git fetch` - PRs appear locally as: - `origin/pr/` - You can test a PR locally - `git checkout pr/2` - Creates a local branch tracking the fetched PR ref - Note in chapter - The `/head` suffix is intentional; GitHub also provides `/merge` refs --- ## Pull Requests on Pull Requests - PR target is not limited to `master` - You can target - any branch in the network - even another Pull Request branch - Why this is useful - proposed change depends on another PR - exploratory/uncertain change - you don’t have push access to the target branch - How to do it (PR creation UI) - edit the base/compare selection - can change both: - branches - forks (where the branches live) --- ## Mentions and Notifications ### @mentions - Type `@` in a comment to autocomplete: - collaborators - contributors - Can mention users not in the dropdown too ### Notification effects - Mentioned user is notified - Mentioned user becomes subscribed (keeps receiving updates) - You are also subscribed if you: - open the Issue/PR - watch the repo - comment on the thread ### Unsubscribe - Use **Unsubscribe** button on Issue/PR page to stop updates --- ## The Notifications Page (config + handling) ### Where to configure - Settings → **Notification center** - Two delivery channels - Email - Web - Each can be toggled separately for: - **Participating** (threads you engage in / @mentioned) - **Watching** (repos you watch) ### Web notifications - GitHub-only - Indicated by a blue dot on the notifications icon - Notification center features - grouped by project - filter by project (left sidebar) - mark read individually (checkmark) - mark all in project read - mute an item (stop future notifications) ### Email notifications - Emails are threaded in many email clients - Headers include metadata useful for filtering/rules, such as: - `Message-ID` encoding: `///` - `` differs for issues vs pull requests - List-style headers: - `List-Post` - `List-Unsubscribe` - `List-Archive` - Mail clients can use these headers to: - reply-post into the thread - unsubscribe/mute via email - Read synchronization - if both web + email are enabled: - reading the email can mark the web notification as read (when images are allowed) --- ## Special Files GitHub Recognizes ### README - GitHub renders a README on the project landing page - Recognized formats include: - `README` - `README.md` - `README.asciidoc` - etc. - Common README contents - project purpose - install/config instructions - usage/running example - license - contribution guidance - Because GitHub renders it, you can include - images - links ### CONTRIBUTING - A `CONTRIBUTING` file (any extension) triggers GitHub to show contribution guidelines when opening a PR - Purpose - define what you want/don’t want in PR submissions - increase chance contributors read guidelines before submitting --- ## Project Administration ### Changing the default branch - If you want a default branch other than `master` - affects what users see by default - affects PR defaults - affects default branch checked out on clone - Location - Repo settings → **Options** → Default branch dropdown ### Transferring a project (ownership transfer) - Repo settings → **Options** → “Transfer ownership” - Transfer to: - another user - an organization - Useful for: - handing off a project you no longer maintain - moving a growing project into an organization - Effects - moves repo with watchers and stars - creates redirects for: - web URLs - Git clone/fetch URLs (not only web) --- ## Managing an Organization ## Organization basics - Organizations have: - shared namespace for projects - shared ownership and management features - Common usage - open source groups - companies - Create an organization - `+` menu (top-right) → “New organization” - provide: - organization name - main contact email - optionally invite other users as co-owners - Free tier note (as stated) - organizations are free if everything stored is open source - Owner capabilities - fork a repo into: - personal namespace - org namespace - create repos under: - personal account - any org you own - automatically watch new repos created under the org - Customization - upload an org avatar - Org landing page - lists org repositories and is viewable by others ## Teams - Teams connect: - people (user accounts) - repositories - access levels - Example use case - repos: `frontend`, `backend`, `deployscripts` - team-based permissions for devs vs ops - Team management includes - adding members - granting repo access - adjusting access levels - Access levels - read-only - read/write - administrative - Team invitations - invited members get an email - Team mentions - `@org/team` mentions notify all team members and subscribe them - Team strategy tip - users can be in multiple teams - create special-interest teams (not only access-control teams) - `ux`, `css`, `refactoring` - `legal`, `colorblind`, etc. ## Audit log - Available to organization owners - Shows - org-level events - who performed them - where they were performed (geographic context) - Filtering available by - event type - place - person --- ## Scripting GitHub ## Services and Hooks (integrations) ### Where to find - Repo **Settings** - **Webhooks and Services** section/tab ### Services (prebuilt integrations) - Dozens of integrations available - Common categories - CI - issue trackers - chat systems - documentation systems - Example: Email service - choose “email” from “Add Service” - configure email address - “Add service” - result: email sent on every push - Event model - services may support multiple events - many focus on push events - Integration tip - check for built-in service for your tool (example given: Jenkins) ### Hooks (generic webhooks) - Use when - you need a custom integration - a service isn’t available as a built-in “Service” - How it works - configure a URL - GitHub POSTs an HTTP payload to that URL on selected events - Enabling/configuring - click “Add webhook” - provide: - payload URL - secret key - choose events (default: push events on any branch) #### Example webhook service logic (Sinatra) - Goal example - send email if: - a specific user pushes - to a specific branch - touching a specific file - Steps in the handler - parse JSON payload from request body - identify: - pusher name - ref/branch - gather files touched across commits (added/modified/removed) - if criteria match → send email alert #### Webhook debugging & redelivery - GitHub provides a webhook delivery console - shows recent deliveries - success/failure - request/response headers and bodies - Can “redeliver” old payloads to test your service - Webhook docs reference - `https://developer.github.com/webhooks/` --- ## The GitHub API ### What it’s for - Automate actions or retrieve information beyond webhook notifications - Can do (as stated) - nearly anything you can do on the website programmatically ### Basic usage (unauthenticated GET) - Example: user info - `curl https://api.github.com/users/schacon` - Many read-only endpoints exist: - orgs, repos, issues, commits, etc. - Example: get a `.gitignore` template - `curl https://api.github.com/gitignore/templates/Java` - Also mentioned capability - render arbitrary Markdown via the API ### Authentication (for write actions/private data) - Options mentioned - basic auth (username/password) - personal access token (recommended) #### Personal access tokens - Generated in settings → **Applications** - Configure: - scopes - description (helps later cleanup) - Token visibility - shown only once → copy it - Advantages - scoped + revocable - higher rate limits - unauthenticated: 60 requests/hour - authenticated: 5,000 requests/hour ### Commenting on an Issue (API example) - Endpoint pattern - `repos///issues//comments` - HTTP method - `POST` - Headers - `Content-Type: application/json` - `Authorization: token TOKEN` - Example payload - JSON with `"body"` (can include emoji codes like `:+1:`) - Result - API returns comment data (id, URLs, timestamps, author info) - Comment appears on the GitHub issue ### Changing the status of a Pull Request (commit status API) - Concept - Each commit can have one or more statuses - API supports adding/querying statuses - Typical users - CI and testing services - Other validation examples (as stated) - commit message formatting checks - contribution guideline validation - signed/valid commit checks - Example webhook-based validator (Signed-off-by) - On push: - inspect each commit message - set status `state` to one of: - `success` - `failure` - `error` - include: - description - target URL for more info - context (e.g., `validate/signoff`) to distinguish multiple status providers - Status POST endpoint pattern - `/repos///statuses/` - UI effect on PR - green check vs red X per commit - PR overall status reflects last commit’s status - warns you if the last commit is failing (useful to avoid merging broken state) ### Octokit (API client libraries) - Purpose - Provide idiomatic wrappers around GitHub API (avoid manual HTTP) - Languages supported (at time of writing in chapter) - Go - Objective-C - Ruby - .NET - Info link - `https://github.com/octokit` ### Documentation link (API) - Full API docs + guides - `https://developer.github.com` --- ## Summary (end of chapter) - After this chapter you can: - create/manage a GitHub account - create repos and push code - contribute via forks + pull requests - review/merge/close PRs as a maintainer - manage orgs, teams, audit logs - integrate via services/webhooks - automate via the GitHub API (tokens, comments, statuses) - Next step (as stated) - learn more powerful Git tools/tips for complex situations to become a “Git master”