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¶
- Clone location.
local_clonereflects whoever wrote the entry. Many engineers are on Windows, where repos typically sit underC:\Users\<you>\source\repos\orC:\dev\, not~/projects. Others use macOS, Linux or WSL. Ask; never guess. - Shell. Windows engineers run PowerShell or Git Bash, and the two need different path forms for the same folder. See Platform notes.
- Transport.
remote_urlis 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. - Entitlement. Access is per-repo. Someone may hold access to some portfolio repos but not
to
a platform organisation you may not have access tooran infrastructure organisation you may not have access to. A clone failure may be an authorisation boundary, not a mistake to retry. - 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"
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¶
- Open workspace folders — usually the fastest and most reliable signal.
- Match by remote. For each candidate directory, compare
git -C <dir> remote get-url originagainstremote_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. - The
local_clonehint — 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\reposis a common default, not a safe assumption. - "Which transport should I use — SSH or HTTPS?" Show the
remote_urlas recorded and ask whether it works on this machine. - "Some repos are behind. May I
git pullthem?" Pulling is a write; ask first. - "Some repos are behind. May I
git pullthem?" 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 fetchfreely;git pullonly with consent, and prefer--ff-only.- Never
checkoutaway 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:
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 |
Related¶
- Portfolio registry (often
docs/management/compliance/repos.yml) - change-throughput — a common caller
- monthly-compliance-run — portfolio cycle that starts here
- git-hygiene — run before making changes in any resolved clone