28 KiB
28 KiB
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)
- A recognizable title/name for the key (helps later revocation)
- 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
- Verified + 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
- Fork the project
- Create a topic branch from
master - Commit improvements
- Push the topic branch to your GitHub fork
- Open a Pull Request
- Discuss; optionally keep committing to the same branch
- Owner merges or closes the PR
- 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
- Example fork URL:
- 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
- macOS:
- 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/<user>/<project>/branches
- Use the Branches page:
- 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...<branch>(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
- Common preference on GitHub:
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 <file>git commit(records the merge)
- edit conflicting files (example:
- 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
#<num>in comments/descriptions links automatically
Cross-repo / cross-fork references
- In a fork of the repo you’re in:
username#<num>
- In a different repository:
username/repo#<num>
- 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
rto quote it in the reply box
- Select text in a comment and press
Emoji
- Emoji helper/autocomplete appears when typing
: - Syntax
:<name>:(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 mastergit pull https://github.com/progit/progit2.git- fetch + merge into your
master
- fetch + merge into your
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
masterto pull from upstreammastergit 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 mastergit pullgit push
Important caution
- With this setup Git won’t warn if you:
- commit to
master - pull from upstream
- push to origin
- commit to
- You must treat
masteras “belonging to upstream”- avoid committing directly to
master
- avoid committing directly to
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
<user>/<project_name> - If empty, GitHub provides instructions to:
- create a new repo locally and push
- connect an existing repo
- (Refresher referenced: Git Basics)
- Repo available as
- Repo URLs
- HTTPS:
https://github.com/<user>/<project_name> - SSH:
git@github.com:<user>/<project_name>
- HTTPS:
- Sharing tip (public projects)
- Prefer sharing HTTPS URL
- cloning doesn’t require a GitHub account
- SSH requires account + SSH key
- Prefer sharing HTTPS URL
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 <url> patch-1(merge remote branch without adding remote).diffand.patchlinks for PR content- Example patch application:
curl https://github.com/<user>/<repo>/pull/<id>.patch | git am
- Example patch application:
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 <url> <branch>- 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 <url>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 <repo-url>
- You’ll see entries like:
refs/heads/masterrefs/pull/<id>/headrefs/pull/<id>/merge
Two refs per PR (what they mean)
refs/pull/<id>/head- points to the tip commit of the PR branch
refs/pull/<id>/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
- stored in
- Downsides
- repetitive for many PRs
- merging
FETCH_HEADcan produce awkward merge messages
Fetch all PR heads automatically via refspec
- Edit
.git/configand add a secondfetch =line under theoriginremote:- Existing (typical):
fetch = +refs/heads/*:refs/remotes/origin/*
- Add:
fetch = +refs/pull/*/head:refs/remotes/origin/pr/*
- Existing (typical):
- After
git fetch- PRs appear locally as:
origin/pr/<id>
- PRs appear locally as:
- You can test a PR locally
git checkout pr/2- Creates a local branch tracking the fetched PR ref
- Note in chapter
- The
/headsuffix is intentional; GitHub also provides/mergerefs
- The
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
- 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-IDencoding:<user>/<project>/<type>/<id><type>differs for issues vs pull requests
- List-style headers:
List-PostList-UnsubscribeList-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)
- if both web + email are enabled:
Special Files GitHub Recognizes
README
- GitHub renders a README on the project landing page
- Recognized formats include:
READMEREADME.mdREADME.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
CONTRIBUTINGfile (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
- fork a repo into:
- 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
- repos:
- 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/teammentions 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,refactoringlegal,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
- send email if:
- 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
.gitignoretemplatecurl 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/<user>/<repo>/issues/<num>/comments
- HTTP method
POST
- Headers
Content-Type: application/jsonAuthorization: token TOKEN
- Example payload
- JSON with
"body"(can include emoji codes like:+1:)
- JSON with
- 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
stateto one of:successfailureerror
- include:
- description
- target URL for more info
- context (e.g.,
validate/signoff) to distinguish multiple status providers
- Status POST endpoint pattern
/repos/<user>/<repo>/statuses/<commit_sha>
- 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)
- On push:
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”