Access plain text versions of GitHub content (diffs, patches, raw files) using GitHub's URL transformations...
This skill enables direct access to plain text versions of GitHub content without HTML rendering, perfect for analyzing code changes, reviewing files, and processing GitHub data.
GitHub provides multiple URL "hacks" that return content in plain text or structured formats:
.diff or .patch filesraw.githubusercontent.com?plain=1Standard PR URL:
https://github.com/owner/repo/pull/123
Plain text diff:
https://github.com/owner/repo/pull/123.diff
Patch format (with metadata):
https://github.com/owner/repo/pull/123.patch
Ignore whitespace:
https://github.com/owner/repo/pull/123.diff?w=1
Transform any PR URL by appending .diff or .patch:
Examples:
# Original
https://github.com/franklinbaldo/egregora/pull/600
# Unified diff
https://github.com/franklinbaldo/egregora/pull/600.diff
# Mail-ready patch (includes commit messages, author info)
https://github.com/franklinbaldo/egregora/pull/600.patch
# Ignore whitespace changes
https://github.com/franklinbaldo/egregora/pull/600.diff?w=1
When to use:
Important limitation - Review Comments:
PR URLs with review comment fragments (e.g., #discussion_r2506786717) require HTML fetch:
# URL with review comment
https://github.com/owner/repo/pull/123#discussion_r2506786717
# .diff format won't show the comment
https://github.com/owner/repo/pull/123.diff ❌ No review comments
# Fetch HTML to see comments and discussion
https://github.com/owner/repo/pull/123 ✅ Includes review comments
When to use HTML instead of .diff:
#discussion_..., #issuecomment-...)Works identically to PRs:
Examples:
# Original
https://github.com/franklinbaldo/egregora/commit/dee113a
# Diff format
https://github.com/franklinbaldo/egregora/commit/dee113a.diff
# Patch format
https://github.com/franklinbaldo/egregora/commit/dee113a.patch
When to use:
Compare two branches, tags, or commits:
Examples:
# Original compare
https://github.com/franklinbaldo/egregora/compare/main...feature-branch
# Diff format
https://github.com/franklinbaldo/egregora/compare/main...feature-branch.diff
# Patch format
https://github.com/franklinbaldo/egregora/compare/main...feature-branch.patch
# Ignore whitespace
https://github.com/franklinbaldo/egregora/compare/main...feature-branch.diff?w=1
When to use:
Convert any blob URL to raw content:
Method 1: raw.githubusercontent.com
# Original
https://github.com/franklinbaldo/egregora/blob/main/README.md
# Raw content
https://raw.githubusercontent.com/franklinbaldo/egregora/main/README.md
Method 2: ?raw=1 parameter
# Redirects to raw.githubusercontent.com
https://github.com/franklinbaldo/egregora/blob/main/README.md?raw=1
Pattern:
# Original blob URL
https://github.com/<owner>/<repo>/blob/<ref>/<path/to/file>
# Raw content
https://raw.githubusercontent.com/<owner>/<repo>/<ref>/<path/to/file>
When to use:
Latest version of a gist file:
https://gist.github.com/<user>/<gist-id>/raw/
Specific file in gist:
https://gist.githubusercontent.com/<user>/<gist-id>/raw/<filename>
Example:
# Gist URL
https://gist.github.com/franklinbaldo/abc123
# Raw content (latest)
https://gist.github.com/franklinbaldo/abc123/raw/
# Specific file
https://gist.githubusercontent.com/franklinbaldo/abc123/raw/example.py
When to use:
View Markdown source without rendering:
Examples:
# Original
https://github.com/franklinbaldo/egregora/blob/main/README.md
# Plain text (still HTML page, but content in <pre>)
https://github.com/franklinbaldo/egregora/blob/main/README.md?plain=1
# With line numbers
https://github.com/franklinbaldo/egregora/blob/main/README.md?plain=1#L14-L30
When to use:
Releases feed:
https://github.com/franklinbaldo/egregora/releases.atom
Commits feed (per branch):
https://github.com/franklinbaldo/egregora/commits/main.atom
https://github.com/franklinbaldo/egregora/commits/feature-branch.atom
When to use:
For scripting and API access, use Accept headers to get diff/patch content:
Examples:
# Get PR diff via API
curl -H "Accept: application/vnd.github.diff" \
https://api.github.com/repos/franklinbaldo/egregora/pulls/600
# Get PR patch via API
curl -H "Accept: application/vnd.github.patch" \
https://api.github.com/repos/franklinbaldo/egregora/pulls/600
# Get commit diff via API
curl -H "Accept: application/vnd.github.diff" \
https://api.github.com/repos/franklinbaldo/egregora/commits/dee113a
Media types:
application/vnd.github.diff - Unified diff formatapplication/vnd.github.patch - Patch format with metadataapplication/vnd.github.raw - Raw file contentapplication/vnd.github.html - Rendered HTMLWhen a user shares a PR for review:
User: "Can you review this PR? https://github.com/franklinbaldo/egregora/pull/600"
Claude workflow:
1. Transform URL: https://github.com/franklinbaldo/egregora/pull/600.diff
2. Fetch the diff using Bash + curl:
curl -s https://github.com/franklinbaldo/egregora/pull/600.diff
3. Analyze changes in plain text
4. Provide code review feedback
When analyzing a specific file:
User: "What does this file do? https://github.com/franklinbaldo/egregora/blob/main/src/egregora/privacy/anonymizer.py"
Claude workflow:
1. Transform to raw: https://raw.githubusercontent.com/franklinbaldo/egregora/main/src/egregora/privacy/anonymizer.py
2. Fetch raw content with curl:
curl -s https://raw.githubusercontent.com/franklinbaldo/egregora/main/src/egregora/privacy/anonymizer.py
3. Analyze code structure
4. Explain functionality
When checking differences between branches:
User: "What changed between main and this feature branch?"
Claude workflow:
1. Create compare URL: https://github.com/franklinbaldo/egregora/compare/main...feature-branch.diff
2. Fetch diff with curl:
curl -s https://github.com/franklinbaldo/egregora/compare/main...feature-branch.diff
3. Summarize changes by file
4. Highlight key modifications
When investigating a specific commit:
User: "What did commit dee113a change?"
Claude workflow:
1. Transform: https://github.com/franklinbaldo/egregora/commit/dee113a.patch
2. Fetch patch with curl (includes commit message + author):
curl -s https://github.com/franklinbaldo/egregora/commit/dee113a.patch
3. Parse changes
4. Explain purpose and impact
Pull Request:
github.com/{owner}/{repo}/pull/{number}
→ Add .diff or .patch
Commit:
github.com/{owner}/{repo}/commit/{sha}
→ Add .diff or .patch
File Blob:
github.com/{owner}/{repo}/blob/{ref}/{path}
→ Replace github.com with raw.githubusercontent.com
→ Remove /blob/
Compare:
github.com/{owner}/{repo}/compare/{base}...{head}
→ Add .diff or .patch
Gist:
gist.github.com/{user}/{id}
→ Add /raw/ for latest
→ Use gist.githubusercontent.com/{user}/{id}/raw/{file}
.diff when:.patch when:git applyraw when:?plain=1 when:.atom when:When a user shares a GitHub URL, use this strategy:
Check for fragment identifiers (#discussion_..., #issuecomment-...)
For plain text attempts:
Analyze and respond
Example 1 - Simple PR:
User: "Check this PR: https://github.com/owner/repo/pull/42"
Strategy:
1. No fragment identifier → Try plain text
2. Transform: https://github.com/owner/repo/pull/42.diff
3. Fetch diff with curl:
curl -sS https://github.com/owner/repo/pull/42.diff
4. If 403: Fall back to HTML:
curl -sS https://github.com/owner/repo/pull/42
5. Analyze and provide insights
Example 2 - PR with review comment:
User: "Look at this comment: https://github.com/owner/repo/pull/42#discussion_r12345"
Strategy:
1. Fragment identifier detected (#discussion_r12345) → Use HTML
2. Fetch with curl:
curl -sS https://github.com/owner/repo/pull/42
3. Locate the specific review comment in HTML
4. Provide context and analysis
For cleaner diffs, add ?w=1 to ignore whitespace:
# Before
https://github.com/owner/repo/pull/42.diff
# After (ignore whitespace)
https://github.com/owner/repo/pull/42.diff?w=1
Don't parse HTML when you can get raw text:
# Bad: Scraping rendered HTML
https://github.com/owner/repo/blob/main/README.md
# Good: Direct raw content
https://raw.githubusercontent.com/owner/repo/main/README.md
Raw URLs respect GitHub permissions:
Large PRs/commits may have truncated diffs:
404 Not Found:
403 Forbidden:
pull/123.diff fails with 403, try fetching pull/123 as HTMLRedirect Required:
github.com URLs may redirect to other domains.diff/.patch URLs redirect to patch-diff.githubusercontent.com (may cause 403)raw.githubusercontent.com directly for filesRate Limiting:
Large Content:
When plain text formats fail (403, 404, or other errors):
{url}.diff or {url}.patchExample workflow:
# User shares: https://github.com/owner/repo/pull/123
# Attempt 1: Try .diff format
curl -sS -f https://github.com/owner/repo/pull/123.diff
# Result: 403 Forbidden (exits with error due to -f flag)
# Attempt 2: Fallback to HTML
curl -sS https://github.com/owner/repo/pull/123
# Result: Success - includes code changes, comments, and discussion
curl error handling pattern:
# Try .diff, fallback to HTML on error
curl -sS -f https://github.com/owner/repo/pull/123.diff || \
curl -sS https://github.com/owner/repo/pull/123
IMPORTANT: In this environment, use the Bash tool with curl instead of WebFetch.
Claude workflow:
1. User shares: https://github.com/owner/repo/pull/123
2. Transform: https://github.com/owner/repo/pull/123.diff
3. Fetch with Bash: curl -s https://github.com/owner/repo/pull/123.diff
4. Analyze fetched diff
5. Respond with insights
Example Bash commands:
# Fetch PR diff
curl -s https://github.com/owner/repo/pull/123.diff
# Fetch commit patch
curl -s https://github.com/owner/repo/commit/abc123.patch
# Fetch raw file
curl -s https://raw.githubusercontent.com/owner/repo/main/README.md
# Fetch with error handling
curl -sS -f https://github.com/owner/repo/pull/123.diff || echo "Failed to fetch"
curl options:
-s : Silent mode (no progress bar)-S : Show errors even in silent mode-f : Fail silently on HTTP errors (404, 403, etc.)-L : Follow redirectsWith code review:
.diff with curl → analyze changes → provide feedbackWith documentation:
With testing:
.patch with curl → identify test coverage gaps → recommend tests# Pull Request / Commit
{url}.diff # Unified diff
{url}.patch # Patch with metadata
{url}.diff?w=1 # Ignore whitespace
# File Content
# Replace: github.com/{owner}/{repo}/blob/{ref}/{path}
# With: raw.githubusercontent.com/{owner}/{repo}/{ref}/{path}
# Or append
{blob_url}?raw=1 # Redirects to raw
# Gist
gist.github.com/{user}/{id}/raw/ # Latest
gist.githubusercontent.com/{user}/{id}/raw/{file} # Specific
# Markdown
{blob_url}?plain=1 # Unrendered source
{blob_url}?plain=1#L10-L20 # With line numbers
# Feeds
{repo_url}/releases.atom # Releases
{repo_url}/commits/{branch}.atom # Commits
# Compare
{repo_url}/compare/{base}...{head}.diff # Diff
{repo_url}/compare/{base}...{head}.patch # Patch
When users share GitHub URLs:
Detect fragment identifiers (#discussion_..., #issuecomment-...)
Recognize the URL type (PR, commit, file, compare, gist)
Transform to appropriate plain text format (.diff, .patch, raw)
Fetch the content using Bash + curl
curl -sS {transformed_url}Analyze the content and respond with insights
✅ Plain text first - Faster, cleaner, easier to parse ✅ HTML fallback - When plain text fails or comments needed ✅ Know the patterns - .diff, .patch, raw.githubusercontent.com ✅ Handle errors gracefully - 403 on .diff? Try HTML ✅ Fragment identifiers - Always require HTML fetch
This skill minimizes HTML scraping while providing direct access to GitHub's structured content formats, with smart fallbacks when needed.
Remember: GitHub makes it easy to access plain text versions of almost any content—you just need to know the right URL patterns and when to fall back!