.agents/skills/migrate-internal-package/references/history-and-merge.md
Read this reference before creating the Ghost import PR.
Work from an up-to-date clone of the source repository. Use its actual default
branch and a temporary branch name that cannot be confused with a product
branch. For example, when the default branch is main:
git fetch origin
git switch --detach origin/main
git subtree split \
--prefix=<source-package-path> \
-b migrate-<package>-history
Record the split tip and inspect the resulting package-only history:
git rev-parse migrate-<package>-history
git log --oneline --reverse migrate-<package>-history
git subtree split retains the relevant commit authorship and chronology while
excluding unrelated source-repository paths.
From a branch based on freshly fetched Ghost origin/main, fetch the local
source split and add it without --squash:
git fetch /absolute/path/to/source-repository migrate-<package>-history
git subtree add \
--prefix=packages/<ghost-directory> \
FETCH_HEAD
The resulting commit should include:
git-subtree-dir: packages/<ghost-directory>
git-subtree-mainline: <ghost-parent>
git-subtree-split: <source-split-tip>
Verify the topology before adding integration commits:
git show --no-patch --format='%H%nparents: %P%n%B' HEAD
git log --graph --oneline --decorate --all --max-count=40
git log --follow -- packages/<ghost-directory>/path/to/representative-file
The subtree commit must have two parents, and its second parent must equal the recorded split tip.
The Admin API schema migration from TryGhost/SDK is a known-good example:
a8fa1f10f23345f740bb4dmain: 6f2ae064fed56f9cf0e1d2Expect GitHub to show imported source commits in the PR commit list. Before the merge checkpoint:
gh pr checks <pr-number> --repo TryGhost/Ghost
gh pr view <pr-number> --repo TryGhost/Ghost \
--json state,isDraft,mergeable,mergeStateStatus,headRefOid,baseRefOid
Resolve real failures and base conflicts without flattening the subtree merge. Verify the graph again after any branch update.
The merge must retain both the subtree topology and the import branch as the second parent of GitHub's merge commit. Do not manually reproduce the repository-setting sequence from prose.
An authorized admin should run:
.agents/skills/migrate-internal-package/scripts/merge-history-pr \
TryGhost/Ghost \
<pr-number> \
<source-split-tip> \
--confirm
Use --dry-run instead of --confirm for read-only preflight. The script:
allow_merge_commit setting;--merge --match-head-commit;If branch protection or a merge queue blocks the operation, report the exact
blocker. Do not add --admin or bypass policy.
After the script succeeds, fetch the remote rather than relying only on its output:
git fetch origin main
git log --first-parent --oneline origin/main --max-count=10
git show --no-patch --format='%H%nparents: %P%n%s' origin/main
git merge-base --is-ancestor <source-split-tip> origin/main
The final command must exit zero. Only then begin cleanup in the source repository.