(
projectPath: string,
layout: RemoteProjectLayout,
currentSnapshotPath: string,
snapshotDigest: string,
baseRepoPathArg: string,
initLogger: InitLogger,
abortSignal?: AbortSignal
)
| 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}` |
no test coverage detected