Skip to content
cccskills
FreePublished on GitHub

merge-upstream

Sync a fork branch with an upstream remote using a history-preserving merge. Use this whenever the user says /merge-upstream, merge upstream, sync upstream, sync fork, or wants upstream changes integrated without rebasing or force-pushing.

The English summary is being prepared. Showing the original description.

See how to install

Files included (1)

  • SKILL.md6.3 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Merge Upstream

Sync the current fork branch with upstream/<branch> using a merge commit by default. Preserve local commit hashes, keep push non-destructive, and never rewrite history.

Usage

Treat these as equivalent triggers:

/merge-upstream [--base=<branch>] [--ff-allow]
merge upstream [--base=<branch>] [--ff-allow]
sync fork with upstream

Options:

  • --base=<branch>: use that upstream branch instead of auto-detecting the upstream default branch.
  • --ff-allow: allow git merge --ff-only when the current branch has no unique local commits. Without this, use git merge --no-ff to leave an explicit sync commit.

Invariants

  • Do not run git rebase.
  • Do not run git push --force or git push --force-with-lease.
  • Do not bypass hooks or signing with --no-verify or --no-gpg-sign.
  • Ask before pushing.

Workflow

  1. Validate the repository:

    git rev-parse --is-inside-work-tree
    git branch --show-current
    git remote get-url upstream
    git remote get-url origin
    

    Abort on detached HEAD or missing upstream. If origin is missing, continue locally and skip push.

  2. Require a clean worktree:

    worktree_status=$(git status --porcelain) || exit 1
    test -z "$worktree_status"
    

    If dirty, stop and ask the user to clean or commit the changes, or use a clean task worktree.

  3. Detect the upstream target branch:

    • If --base=<branch> is provided, fetch and verify upstream/<branch>.
    • Otherwise run git remote set-head upstream -a, then read refs/remotes/upstream/HEAD.
    • If detection fails, ask the user for --base=<branch>.
  4. Fetch enough history for a reliable merge base:

    git rev-parse --is-shallow-repository
    git fetch --tags upstream "+refs/heads/${upstream_branch}:refs/remotes/upstream/${upstream_branch}"
    origin_branch_exists=false
    if git remote get-url origin >/dev/null 2>&1; then
      if ! origin_branch=$(git ls-remote --heads origin "refs/heads/${current_branch}"); then
        echo "failed to inspect origin/${current_branch}" >&2
        exit 1
      elif [ -n "$origin_branch" ]; then
        git fetch origin "+refs/heads/${current_branch}:refs/remotes/origin/${current_branch}" || exit 1
        origin_branch_exists=true
      else
        echo "origin/${current_branch} does not exist; current branch is unpublished"
      fi
    fi
    git merge-base HEAD "upstream/${upstream_branch}"
    

    If the repository is shallow, unshallow origin first when available, then upstream only if still shallow.

    Always use the fetched remote-tracking ref as the target; do not decide from a previously cached upstream/<branch> tip.

  5. Record the exact refs and report divergence:

    current_head=$(git rev-parse HEAD)
    upstream_tip=$(git rev-parse "upstream/${upstream_branch}")
    git rev-list --count "upstream/${upstream_branch}..HEAD"
    git rev-list --count "HEAD..upstream/${upstream_branch}"
    GIT_PAGER=cat git log --oneline "HEAD..upstream/${upstream_branch}"
    GIT_PAGER=cat git log --first-parent --oneline "upstream/${upstream_branch}..HEAD"
    

    Report HEAD and upstream/${upstream_branch} with their full SHAs.

  6. Merge:

    • Behind 0 means the fetched upstream_tip is already an ancestor of current_head. Confirm that state with both checks:

      git merge-base --is-ancestor "$upstream_tip" "$current_head"
      upstream_range=$(git rev-list "$current_head..$upstream_tip") || exit 1
      test -z "$upstream_range"
      

      This completes upstream integration as a successful no-op. Report the exact refs, SHAs, ancestry result, and empty range; skip the merge, release, and other change-dependent gates. Do not create an empty commit or pull request, or publish a branch solely to represent the sync. If an independent request explicitly approves pushing existing local commits, use step 9's non-destructive push semantics.

    • If behind is greater than 0 and --ff-allow is set with ahead 0, run:

      git merge --ff-only "upstream/${upstream_branch}"
      
    • Otherwise capture previous_head and upstream_tip, then run:

      git merge --no-ff "upstream/${upstream_branch}" -m "merge: sync ${current_branch} with upstream/${upstream_branch}"
      
  7. Resolve conflicts locally when they occur:

    git diff --name-only --diff-filter=U
    

    Read each conflicted file. Auto-resolve only mechanically obvious conflicts such as non-overlapping additions, import unions, formatting-only differences, or generated lockfile refreshes. For semantic conflicts, present the specific conflict and ask whether to keep ours, keep theirs, manually edit, or abort. After resolution:

    git add <file>
    git -c core.editor=true merge --continue
    
  8. Verify:

    git rev-parse --git-path MERGE_HEAD
    git rev-parse --git-path rebase-merge
    git rev-parse --git-path rebase-apply
    git show -s --format=%P HEAD
    git rev-list --left-right --count "upstream/${upstream_branch}...HEAD"
    if [ "$origin_branch_exists" = true ]; then
      git merge-base --is-ancestor "origin/${current_branch}" HEAD
    fi
    

    In default mode, verify HEAD has two parents: previous_head as first parent and upstream_tip as second parent. In --ff-allow fast-forward mode, verify HEAD equals upstream_tip.

  9. Push only with explicit approval:

    GIT_PAGER=cat git log --oneline --graph --decorate -10
    git push origin "${current_branch}"
    

    If the remote branch does not exist, use git push -u origin "${current_branch}". If push is rejected as non-fast-forward, re-fetch and offer only non-destructive options: merge origin/<branch> into HEAD and retry, or stop.

Final Report

Include:

  • branch and upstream target, including their full SHAs
  • whether merge, fast-forward, or no-op happened
  • for a no-op, confirmed ancestry and the empty HEAD..upstream/<branch> range
  • fork commits preserved
  • upstream commits integrated
  • push status
  • any conflicts and how they were resolved

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Read before a js eval cell that installs a package, spawns a server or PTY, or starts a long run, and before any bun -e, script, server, CLI, test, bundle, or package-management work: this session's eval js kernel runs Bun 1.4+ (this skill is present only when it does). Bun 1.4 ships builtins that replace 15+ npm deps — check here BEFORE installing sharp, puppeteer/playwright (scraping), marked, node-cron, node-pty, concurrently, serve-static, tar, json5, fast-xml-parser, string-width. Triggers: eval js, bun, Bun.serve, bun test, bun build, bun install, bun run, image resize, headless browser, markdown render, cron, PTY.

The English summary is being prepared. Showing the original description.

code-yeongyu/senpi483Updated Oct 18, 2026

Implements a single feature in the pi-mono `todotools` builtin extension work. Use for refactoring, continuation runtime, config resolver, prompt builder, test authoring, golden snapshots, CHANGELOG entries, and harness helpers. Does NOT do manual tmux QA.

The English summary is being prepared. Showing the original description.

code-yeongyu/senpi483Updated Oct 18, 2026

Example skill loaded from resources_discover

The English summary is being prepared. Showing the original description.

code-yeongyu/senpi483Updated Oct 18, 2026

MUST read before generating images. Prompt-crafting guide for gpt-image-2.5 covering tool routing (native image_generation server tool vs the generate_image tool), model and quality selection, prompt structure, exact text rendering, reference-image editing, transparent assets, output formats, and multi-turn refinement.

The English summary is being prepared. Showing the original description.

code-yeongyu/senpi483Updated Oct 18, 2026

Release, publish, CalVer tag push, npm publish, 배포, 릴리즈 for senpi. Use for the canonical release flow, GitHub tag/release publication, and npm publishing.

The English summary is being prepared. Showing the original description.

code-yeongyu/senpi483Updated Oct 18, 2026

Manual QA harness for the senpi coding agent itself. MUST USE after changing packages/ai, packages/agent, packages/coding-agent, or packages/tui — a green typecheck and `npm test` are NOT QA. Drives the real CLI from source in an isolated sandbox (never touches ~/.senpi or real credentials) across four channels: remote RPC (--mode rpc JSONL stdio), TUI smoke (node-pty on Windows, tmux on POSIX), mock loop (a local fake model server for deterministic, zero-token agent-loop runs), and CLI smoke (--help/--print/--list-models). Every helper ships a --self-test. Use whenever someone says qa senpi, test the agent, verify my change, rpc qa, tui qa, mock-loop qa, smoke the cli, or needs evidence that an agent-loop, tool, keybinding, or provider change works end to end. Capture evidence to local-ignore/qa-evidence/.

The English summary is being prepared. Showing the original description.

code-yeongyu/senpi483Updated Oct 18, 2026

See all skills by code-yeongyu

Report a problem with this skill