MCPcopy
hub / github.com/coder/mux / syncProjectSnapshotViaBundle

Method syncProjectSnapshotViaBundle

src/node/runtime/SSHRuntime.ts:1936–2007  ·  view source on GitHub ↗
(
    projectPath: string,
    layout: RemoteProjectLayout,
    currentSnapshotPath: string,
    snapshotDigest: string,
    baseRepoPathArg: string,
    initLogger: InitLogger,
    abortSignal?: AbortSignal
  )

Source from the content-addressed store, hash-verified

1934 }
1935
1936 private async syncProjectSnapshotViaBundle(
1937 projectPath: string,
1938 layout: RemoteProjectLayout,
1939 currentSnapshotPath: string,
1940 snapshotDigest: string,
1941 baseRepoPathArg: string,
1942 initLogger: InitLogger,
1943 abortSignal?: AbortSignal
1944 ): Promise<void> {
1945 // Snapshot markers stay deterministic, but the uploaded bundle itself must use
1946 // a per-attempt temp path so concurrent Mux processes do not stream into the same file.
1947 const remoteBundlePath = path.posix.join(
1948 "~/.mux-bundles",
1949 layout.projectId,
1950 `${snapshotDigest}.${crypto.randomUUID()}.bundle`
1951 );
1952 const remoteBundlePathArg = this.quoteForRemote(remoteBundlePath);
1953 const remoteBundleParentDir = path.posix.dirname(remoteBundlePath);
1954 const prepareRemoteDirs = await execBuffered(
1955 this,
1956 `mkdir -p ${this.quoteForRemote(remoteBundleParentDir)} ${this.quoteForRemote(path.posix.dirname(currentSnapshotPath))}`,
1957 { cwd: "/tmp", timeout: 10, abortSignal }
1958 );
1959 if (prepareRemoteDirs.exitCode !== 0) {
1960 throw new Error(
1961 `Failed to prepare remote snapshot directories: ${prepareRemoteDirs.stderr || prepareRemoteDirs.stdout}`
1962 );
1963 }
1964
1965 await this.transferBundleToRemote(projectPath, remoteBundlePath, initLogger, abortSignal);
1966
1967 try {
1968 // Import authoritative branches and shared tags from the bundle into the
1969 // shared bare repo. Branches land in refs/mux-bundle/* (staging namespace)
1970 // instead of refs/heads/* to avoid colliding with branches checked out in
1971 // existing worktrees, and they stay pruneable because branch deletion should
1972 // invalidate snapshot reuse. Tags go directly to refs/tags/*, but they are
1973 // fetched separately without --prune so remote-only metadata tags survive.
1974 initLogger.logStep("Importing bundle into shared base repository...");
1975 const branchFetchResult = await execBuffered(
1976 this,
1977 `git -C ${baseRepoPathArg} fetch --prune ${remoteBundlePathArg} '+refs/heads/*:${BUNDLE_REF_PREFIX}*'`,
1978 { cwd: "/tmp", timeout: 300, abortSignal }
1979 );
1980 if (branchFetchResult.exitCode !== 0) {
1981 throw new Error(
1982 `Failed to import bundle branches into base repo: ${branchFetchResult.stderr || branchFetchResult.stdout}`
1983 );
1984 }
1985
1986 const tagFetchResult = await execBuffered(
1987 this,
1988 `git -C ${baseRepoPathArg} fetch ${remoteBundlePathArg} '+refs/tags/*:refs/tags/*'`,
1989 { cwd: "/tmp", timeout: 300, abortSignal }
1990 );
1991 if (tagFetchResult.exitCode !== 0) {
1992 throw new Error(
1993 `Failed to import bundle tags into base repo: ${tagFetchResult.stderr || tagFetchResult.stdout}`

Callers 1

Calls 4

quoteForRemoteMethod · 0.95
execBufferedFunction · 0.90
logStepMethod · 0.80

Tested by

no test coverage detected