Enterprise Content Mirror

Purpose

Define the manual procedure for mirroring the current content of tandpds/dsambayesplus:main to tandpds/dsambayesplus:main.

This is deliberately not CI/CD. Run it only when the enterprise repository needs to reflect an approved development state, normally after a release or a material colleague-facing update.

Mirror contract

tandpds/dsambayesplus:main is the canonical source of truth. The enterprise repository is a content mirror:

  • its main tree must match the canonical main tree exactly;
  • its Git history is intentionally independent and does not share commit SHAs with the canonical repository;
  • do not make enterprise-only source changes. Make the change in tandpds, validate it there, then mirror it.

The independent history is intentional. It avoids attempting to merge two unrelated repository histories while retaining a colleague-facing repository.

Preconditions

Before starting:

  1. Confirm that the intended canonical commit is on tandpds/main and has passed the proportionate manual validation for its change.
  2. Ensure the working tree is clean.
  3. Ensure the credential used for the enterprise remote has GitHub SAML SSO authorisation for groupm-global. Never put a token in a tracked file or a command transcript.
  4. Record the current enterprise branch-protection settings. The normal policy requires pull requests, enforces rules for administrators, and forbids force pushes.

Use remotes named origin (canonical tandpds) and enterprise (groupm-global) below. Authenticate through the local credential mechanism; do not embed a token in a command.

Manual procedure

1. Identify the two branch tips

git fetch origin main
git fetch enterprise main

canonical_main=$(git rev-parse origin/main)
canonical_tree=$(git rev-parse "${canonical_main}^{tree}")
enterprise_main=$(git rev-parse enterprise/main)

printf 'canonical main: %s\ncanonical tree: %s\nenterprise main: %s\n' \
  "$canonical_main" "$canonical_tree" "$enterprise_main"

Stop if canonical_main is not the reviewed state you intend to share.

2. Preserve the enterprise rollback point

Create a dated archive branch before changing enterprise main.

archive_branch="archive/pre-tandpds-mirror-$(date +%F)"
git push enterprise "${enterprise_main}:refs/heads/${archive_branch}"
git ls-remote enterprise "refs/heads/${archive_branch}"

The archive ref must resolve to enterprise_main. If it does not, stop.

3. Create a history-free content snapshot

Create a root commit whose tree is exactly the canonical tree. This does not modify the working tree.

snapshot_commit=$(printf '%s\n\n%s\n%s\n' \
  'chore: mirror tandpds main content' \
  "Content snapshot of tandpds/dsambayesplus main at ${canonical_main}." \
  "Enterprise rollback point: ${archive_branch}." \
  | git commit-tree "$canonical_tree")

git show --no-patch --format=fuller "$snapshot_commit"
test "$(git rev-parse "${snapshot_commit}^{tree}")" = "$canonical_tree"

Do not replace this with a merge. The repositories have unrelated histories; a merge would create conflict noise without preserving a meaningful common lineage.

4. Temporarily permit the controlled update

In the enterprise repository’s GitHub settings, temporarily:

  1. permit force pushes for the named release owner only;
  2. disable the required-pull-request rule for this one direct update; and
  3. permit administrator bypass only if the existing policy requires it.

Do not select a broad “Everyone can force push” option. Restore the normal settings immediately after the verified update.

5. Update enterprise main with a lease

The lease prevents overwriting a branch that changed since Step 1.

git push --no-thin \
  --force-with-lease="refs/heads/main:${enterprise_main}" \
  enterprise \
  "${snapshot_commit}:refs/heads/main"

If this fails, do not retry with an unconditional --force. Fetch the remote state, determine why main changed, and restart from Step 1.

6. Verify the content mirror

remote_main=$(git ls-remote enterprise refs/heads/main | awk '{print $1}')
test "$remote_main" = "$snapshot_commit"
test "$(git rev-parse "${snapshot_commit}^{tree}")" = "$canonical_tree"

printf 'enterprise main: %s\ncanonical tree: %s\n' \
  "$remote_main" "$canonical_tree"

The commit SHA will differ from canonical_main by design. The equality that matters is the tree equality established in Steps 3 and 6.

7. Restore protection and record the result

Immediately restore the normal enterprise main settings:

  • pull requests required;
  • administrator enforcement enabled;
  • force pushes disabled.

Record the canonical SHA, canonical tree SHA, enterprise snapshot SHA, archive branch name, date, and operator in the relevant release or handover note.

Rollback and retention

To roll back within the retention window, temporarily apply the same narrowly scoped branch-protection exception and force-update main to the archive ref. Verify the resulting remote tip before restoring protection.

Keep each archive/pre-tandpds-mirror-YYYY-MM-DD branch for at least 30 days. Delete it only after confirming that no rollback or audit need remains.

Failure boundaries

Stop and investigate when any of the following occurs:

  • SAML SSO denies access to the enterprise repository;
  • the rollback branch cannot be verified;
  • the force-with-lease rejects the update;
  • the snapshot tree differs from the canonical tree; or
  • the branch-protection settings cannot be restored.

These are control failures, not reasons to bypass the procedure with an unconditional force push.