Skip to content

Sync Portfolio Repos

ContributorsMyles Henaghan, GitHub Copilot

Contributors 🕹️ Myles Henaghan

When to use: Any time a cross-repo task needs more than one portfolio repository and you do not already know, with certainty, where those clones live on this machine. Run this before the scan, not in the middle of it.

The registry (often docs/management/compliance/repos.yml; confirm the path) is the source of truth for which repos exist and where their remotes are. It is not a source of truth for anything local.

Field Trust it? Why
remote_url ✅ authoritative Committed, reviewed, machine-independent
web_url ✅ authoritative Same
default_branch ⚠️ verify Has drifted before — four entries said main when the remote said master
merge_policy ⚠️ verify Only recorded for some repos so far
local_clone ❌ hint only Every machine and user differs

Never assume

  1. Clone location. local_clone reflects whoever wrote the entry. Many engineers are on Windows, where repos typically sit under C:\Users\<you>\source\repos\ or C:\dev\, not ~/projects. Others use macOS, Linux or WSL. Ask; never guess.
  2. Shell. Windows engineers run PowerShell or Git Bash, and the two need different path forms for the same folder. See Platform notes.
  3. Transport. remote_url is recorded in one form (usually SSH). The user may only have HTTPS access, may use Git Credential Manager, a PAT, or an SSH agent with a passphrase. Do not rewrite a URL between SSH and HTTPS without asking.
  4. Entitlement. Access is per-repo. Someone may hold access to some portfolio repos but not to a platform organisation you may not have access to or an infrastructure organisation you may not have access to. A clone failure may be an authorisation boundary, not a mistake to retry.
  5. Permission to write to disk. Cloning creates directories. Ask where before doing it.

Platform notes

Windows is a common desktop platform; give Windows examples first, then Git Bash, then macOS/Linux/WSL.

The same clone, three ways

Context Path form
PowerShell C:\Users\<you>\source\repos\pipe-dream
PowerShell (portable) $env:USERPROFILE\source\repos\pipe-dream
Git Bash / WSL /c/Users/<you>/source/repos/pipe-dream
macOS / Linux ~/src/pipe-dream

When reporting resolved paths back to the user, use the form matching their shell. A Git Bash user handed C:\Users\... has to translate it by hand, and vice versa.

Cloning

# PowerShell
$root = "$env:USERPROFILE\source\repos"
New-Item -ItemType Directory -Force -Path $root | Out-Null
git -C $root clone <remote_url>
# Git Bash / WSL / macOS / Linux
root="/c/Users/$USER/source/repos"     # or ~/src on macOS/Linux
mkdir -p "$root"
git -C "$root" clone <remote_url>

Windows-specific gotchas

Symptom Cause Fix
Filename too long on clone or checkout Windows MAX_PATH; the Databricks monorepos have deeply nested paths git config --global core.longpaths true before cloning
A /subscriptions/...-style argument turns into C:/Program Files/Git/... Git Bash POSIX path conversion Prefix the command with MSYS_NO_PATHCONV=1
Line-ending churn across the whole repo core.autocrlf mismatch Confirm the team's setting before touching files; do not "fix" it unasked
ssh: connect ... Permission denied (publickey) in PowerShell but not Git Bash Two different SSH agents and key stores Ask which shell they normally clone from
HTTPS clone opens a browser or credential dialog Git Credential Manager Expected on Windows — let the user complete it; never ask for the credential

Running the diagnostic scripts afterwards:

# PowerShell — prefer the workspace interpreter
.venv\Scripts\python.exe scripts\collect.py --repo "$env:USERPROFILE\source\repos\pipe-dream"
py -3 scripts\collect.py --repo "C:\Users\<you>\source\repos\pipe-dream"
# Git Bash
python scripts/collect.py --repo "/c/Users/<you>/source/repos/pipe-dream"

Procedure

1. Read the registry

Load docs/management/compliance/repos.yml. Build the candidate list — either all repos, or those with the relevant scan_id in enabled_scans if the caller named a scan.

2. Try to resolve each clone locally, cheapest first

  1. Open workspace folders — usually the fastest and most reliable signal.
  2. Match by remote. For each candidate directory, compare git -C <dir> remote get-url origin against remote_url, normalising SSH and HTTPS forms of the same repo to the same identity (host + org/project + name). A repo cloned over HTTPS is still the same repo.
  3. The local_clone hint — check it, but treat a hit as a coincidence worth confirming, not as proof.

3. Report before acting

Present what was found as a table — resolved path, branch, ahead/behind, and last commit date — and list anything unresolved separately. Stop here and ask. Do not clone, pull or check out anything yet.

4. Ask the user (mandatory when anything is ambiguous)

Check persistent memory first. If the user's terminal, projects folder and git transport were already recorded via IDE-specific skill wiring, use them and do not re-ask. Only ask for what is genuinely unknown.

Use interactive option tools where available; otherwise ask in plain chat and wait.

  • "I could not find N repos locally. Do you already have them somewhere I have not looked, or should they be cloned?"
  • "Which shell are you using — PowerShell, Git Bash, or a Unix shell?" This decides the path form for every command and every path reported back.
  • "If cloning, which parent directory should I use?" — offer the directory that already holds the resolved repos as the likely answer, but let the user override. On Windows, %USERPROFILE%\source\repos is a common default, not a safe assumption.
  • "Which transport should I use — SSH or HTTPS?" Show the remote_url as recorded and ask whether it works on this machine.
  • "Some repos are behind. May I git pull them?" Pulling is a write; ask first.
  • "Some repos are behind. May I git pull them?" Pulling is a write; ask first.

Never ask for a passphrase, PAT, password or token. If a clone stalls on a credential prompt, stop and tell the user to enter it directly in their own terminal. Credentials must never pass through the model.

5. Only then act

  • Clone with the transport the user chose, into the directory the user named.
  • git fetch freely; git pull only with consent, and prefer --ff-only.
  • Never checkout away from whatever branch the user had open without saying so — a clone parked on a feature branch is somebody's work in progress.

6. Verify and hand back

For every repo now available, confirm the real default branch:

git -C <clone> ls-remote --symref origin HEAD

Use that, not the checked-out branch and not repos.yml. Where it disagrees with the registry, say so and offer to correct repos.yml — that drift silently produced zero-result scans in the August 2026 run.

Hand back a table of repo_id → resolved path → verified default branch, which is exactly what the diagnostic prompts need.

Failure modes worth naming

Symptom Likely cause Response
Permission denied (publickey) No SSH key or agent for that host Ask whether HTTPS is preferred; do not silently switch
Clone hangs with no output Waiting on a passphrase or credential helper Stop; ask the user to run it in their own terminal
Repository not found on one host only Per-repo entitlement Report as an access boundary, not an error to retry
Clone exists but origin differs Fork, mirror, or renamed remote Confirm with the user before treating it as the same repo
Scan returns zero results Wrong branch, not an idle repo Re-check with ls-remote --symref
Filename too long (Windows) MAX_PATH limit git config --global core.longpaths true, then re-clone