| name | upstream-pr |
| description | Load this skill whenever working in a fork of a third-party project. |
Upstream PR Workflow
This skill manages the full lifecycle of contributing a fix from a fork back to an
upstream repository, following a draft-in-tree convention: a PULL_REQUEST_DRAFT.md
file lives in every commit on the PR branch and is git rm'd immediately before
submission.
The PULL_REQUEST_DRAFT.md Convention
Every commit on a PR branch must contain PULL_REQUEST_DRAFT.md at the repo root.
Format:
# PR Title Here (this line → `gh pr create --title`)
Everything below this line becomes the PR body (`--body`).
## Problem
…
## Solution
…
## Testing
…
- The first
# H1 line is the PR title.
- All remaining content is the PR body (GitHub Markdown).
- The file is committed so every intermediate state of the branch is self-documenting.
- Do NOT
.gitignore it — it must be visible in git log and reviewable.
- Remove it with
git rm just before creating the PR (see Submission step).
Remotes Convention
In a fork, always name remotes:
| Remote | Points to |
|---|
origin | Your fork (read/write) |
upstream | The original project |
If upstream is not configured:
git remote add upstream https://github.com/OWNER/REPO.git
git fetch upstream
The akaihola Working Branch (git-knit)
All unmerged feature branches must be stacked into a single working branch
called akaihola using git-knit. This gives a single integration branch that
combines every in-flight change on top of upstream/main.
Initialize (once per repo)
git knit init akaihola upstream/main [fix/branch-a fix/branch-b ...]
If akaihola already exists in the remote, verify git knit status matches
what is currently checked out before touching it.
Day-to-day commands
git knit status
git knit add fix/new-branch
git knit remove fix/old-branch
git knit rebuild
git knit restack
Rules
- Every new feature/fix branch must be
git knit add-ed immediately after creation.
- After rebasing any feature branch onto updated
upstream/main, run
git knit rebuild to regenerate akaihola.
- Never commit directly to
akaihola — it is a derived branch. All real commits
go to individual fix/* / feat/* / docs/* branches.
- When a PR is merged upstream, run
git knit remove <branch> and
git knit rebuild.
Workflow
1. Identify the change
Determine what needs contributing. Common sources:
- A commit in your fork's
main not in upstream/main
- A bug fix applied locally but never submitted
- An enhancement developed in a feature branch
Useful commands:
git log --oneline upstream/main..main
git diff upstream/main..main -- path/to/file.go
git cherry -v upstream/main <your-branch>
Always verify the change is not already in upstream before creating a PR branch.
Upstream may have merged the content under different commit SHAs. Use
git diff upstream/main...<your-branch> (three dots = content diff from merge base)
to confirm actual differences exist.
2. Fetch upstream
git fetch upstream
3. Create a clean branch from upstream/main
git checkout -b <branch-name> upstream/main
Branch naming convention:
fix/<short-description> for bug fixes
feat/<short-description> for new features
chore/<short-description> for non-functional changes
docs/<short-description> for documentation
4. Apply the change
Choose the cleanest approach:
a) Cherry-pick (when the commit applies cleanly):
git cherry-pick <commit-sha>
b) Apply a file diff (when cherry-pick would drag in unrelated changes):
git diff upstream/main..main -- path/to/file > /tmp/fix.patch
git apply /tmp/fix.patch
git add path/to/file
git commit -m "fix: description of the fix"
c) Implement fresh (when rewriting is cleaner than patching):
Just make the changes and commit normally.
5. Add PULL_REQUEST_DRAFT.md to the commit
After the fix commit exists (or as part of it), add PULL_REQUEST_DRAFT.md:
cat > PULL_REQUEST_DRAFT.md << 'EOF'
Describe what was broken and why it mattered.
Explain what the fix does. Reference the functions/files changed.
How to verify the fix works. Include commands if applicable.
EOF
git add PULL_REQUEST_DRAFT.md
git commit --amend --no-edit
For multi-commit PRs, include PULL_REQUEST_DRAFT.md in every commit
(use git commit --amend or update it at each step). The file should always
reflect the PR's current intended title and description.
6. Push the branch to origin
git push origin <branch-name>
Note: the agent cannot push to GitHub. Remind the user to run ghpp on atom
or use git push from a machine with push access.
7. Submit the PR (submission step)
When the branch is ready to submit, use the helper script:
bash /path/to/skills-akaihola/upstream-pr/scripts/submit-pr.sh [--upstream-repo OWNER/REPO]
The script:
- Reads
PULL_REQUEST_DRAFT.md and extracts title + body
- Shows a preview and asks for confirmation
- Runs
git rm PULL_REQUEST_DRAFT.md && git commit -m "chore: remove PR draft before submission"
- Runs
git push origin <branch> (if needed)
- Runs
gh pr create --repo OWNER/REPO --title "..." --body "..."
Manual equivalent (if not using the script):
TITLE=$(grep -m1 '^# ' PULL_REQUEST_DRAFT.md | sed 's/^# //')
BODY=$(tail -n +2 PULL_REQUEST_DRAFT.md | sed '1{/^$/d}')
git rm PULL_REQUEST_DRAFT.md
git commit -m "chore: remove PR draft before submission"
git push origin <branch>
gh pr create --repo OWNER/REPO --title "$TITLE" --body "$BODY"
Handling Conflicts
When cherry-picking produces conflicts:
- Inspect the conflict with
git diff and understand both sides.
- Resolve by keeping the most correct version — usually upstream's recent refactors
plus your new logic on top.
git add resolved files, then git cherry-pick --continue.
- Do not use
--strategy-option theirs/ours blindly — read the conflict.
Verifying the Branch is Clean
Before pushing, confirm the branch only contains what you intend:
git log --oneline upstream/main..<branch>
git diff --stat upstream/main...<branch>
git show HEAD:PULL_REQUEST_DRAFT.md | head -3
Keeping Branches Updated
If upstream/main advances while your PR is under review:
git fetch upstream
git rebase upstream/main
git push --force-with-lease origin <branch>
Example: Full Single-Fix PR
cd ~/mitto
git fetch upstream
git checkout -b fix/my-bug-fix upstream/main
git cherry-pick abc1234
cat > PULL_REQUEST_DRAFT.md << 'EOF'
Widget exploded when user did X.
Guard against nil pointer in `handleFoo()`.
`go test ./internal/web/...` passes. Manually verified: X no longer explodes.
EOF
git add PULL_REQUEST_DRAFT.md
git commit --amend --no-edit
git push origin fix/my-bug-fix
Notes
- Always target
upstream/main as the base, not origin/main or main.
- Always verify the fix is not already upstream before creating a branch.
- If the upstream repo uses squash-merge, a single commit per PR is cleaner.
- Keep PR branches focused: one logical change per branch.
- Close the corresponding upstream issue in the PR body with
Fixes #N.