MCPcopy Index your code
hub / github.com/coder/mux / syncProjectToRemote

Method syncProjectToRemote

src/node/runtime/SSHRuntime.ts:2252–2318  ·  view source on GitHub ↗

* Sync local project to the shared bare base repo on the remote. * * OpenSSH runtimes use native `git push` so Git negotiates incremental object * transfer automatically. SSH2 runtimes keep the bundle path so sync does not * depend on a local OpenSSH CLI or local known_hosts state. *

(
    projectPath: string,
    initLogger: InitLogger,
    abortSignal?: AbortSignal
  )

Source from the content-addressed store, hash-verified

2250 * shared metadata instead of authoritative snapshot state.
2251 */
2252 protected async syncProjectToRemote(
2253 projectPath: string,
2254 initLogger: InitLogger,
2255 abortSignal?: AbortSignal
2256 ): Promise<void> {
2257 if (abortSignal?.aborted) {
2258 throw new Error(OPERATION_ABORTED_ERROR);
2259 }
2260
2261 const layout = this.getProjectLayout(projectPath);
2262 const projectKey = this.getProjectSyncKey(layout.projectId);
2263 const retryCleanupBaseRepoPathArg = expandTildeForSSH(layout.baseRepoPath);
2264
2265 // Keep retries, cancellation handling, and retry cleanup inside the project-scoped
2266 // sync lock so a follow-up init cannot race the shared base repo while we are healing it.
2267 await enqueueProjectSync(projectKey, abortSignal, async () => {
2268 // Latches once a thin-pack delta-base failure is observed so every
2269 // subsequent attempt in this sync push a self-contained pack (`--no-thin`).
2270 // Stays `false` for connection-reset / killed-by-signal retries since
2271 // those don't benefit from forcing a larger pack.
2272 let forceNoThinNextAttempt = false;
2273 for (let attempt = 1; attempt <= PROJECT_SYNC_MAX_ATTEMPTS; attempt++) {
2274 if (abortSignal?.aborted) {
2275 throw new Error(OPERATION_ABORTED_ERROR);
2276 }
2277
2278 try {
2279 await this.syncProjectToRemoteOnce(projectPath, layout, initLogger, abortSignal, {
2280 forceNoThin: forceNoThinNextAttempt,
2281 });
2282 return;
2283 } catch (error) {
2284 const errorMsg = getErrorMessage(error);
2285 if (abortSignal?.aborted || errorMsg === OPERATION_ABORTED_ERROR) {
2286 throw error instanceof Error ? error : new Error(errorMsg);
2287 }
2288 if (
2289 !this.isRetryableProjectSyncError(errorMsg) ||
2290 attempt === PROJECT_SYNC_MAX_ATTEMPTS
2291 ) {
2292 throw new Error(`Failed to sync project: ${errorMsg}`);
2293 }
2294
2295 if (isUnresolvedDeltaPushFailure(errorMsg)) {
2296 forceNoThinNextAttempt = true;
2297 }
2298
2299 log.info(
2300 `Sync failed (attempt ${attempt}/${PROJECT_SYNC_MAX_ATTEMPTS}), will retry: ${errorMsg}`
2301 );
2302 await this.cleanupRetryableProjectSyncFailure(
2303 retryCleanupBaseRepoPathArg,
2304 attempt,
2305 PROJECT_SYNC_MAX_ATTEMPTS,
2306 abortSignal
2307 );
2308 if (abortSignal?.aborted) {
2309 throw new Error(OPERATION_ABORTED_ERROR);

Callers 2

runSyncMethod · 0.80

Calls 11

getProjectLayoutMethod · 0.95
getProjectSyncKeyMethod · 0.95
expandTildeForSSHFunction · 0.90
getErrorMessageFunction · 0.90
enqueueProjectSyncFunction · 0.85
logStepMethod · 0.80

Tested by 1

runSyncMethod · 0.64