fix: preserve remote workspace changes across sessions

This commit is contained in:
2026-10-14 14:06:44 +09:00
parent debb38a29b
commit c9cceb4c01
4 changed files with 135 additions and 45 deletions
+13 -42
View File
@@ -4231,21 +4231,20 @@ async function installRemoteWorkspaceModule(
`STUDENT_REPO="$(printf %s ${quoteShellSingle(encodeBase64(studentRepositoryWithCredential))} | base64 -d)"`,
`PREBUILT_JSON="$(printf %s ${quoteShellSingle(encodeBase64(prebuiltJson))} | base64 -d)"`,
'mkdir -p "$ROOT"',
'if [ ! -d "$TARGET/.git" ]; then git clone "$TEMPLATE_REPO" "$TARGET"; fi',
'git -C "$TARGET" remote set-url origin "$TEMPLATE_REPO"',
'git -C "$TARGET" fetch origin --prune',
'CURRENT_STUDENT="$(git -C "$TARGET" remote get-url student 2>/dev/null || true)"',
'if [ "$CURRENT_STUDENT" != "$STUDENT_REPO" ]; then',
' git -C "$TARGET" checkout -B main origin/main',
' git -C "$TARGET" reset --hard origin/main',
' git -C "$TARGET" clean -fdx',
' git -C "$TARGET" remote remove student >/dev/null 2>&1 || true',
// An existing workspace owns its source, commits and build artifacts. Install
// retries (including changed repository credentials) must not overwrite it.
'if [ -e "$TARGET/.git" ]; then',
' printf "OK\\t%s\\n" "$TARGET"',
' exit 0',
'fi',
'git clone "$TEMPLATE_REPO" "$TARGET"',
'if [ -n "$STUDENT_REPO" ]; then',
' git -C "$TARGET" remote add student "$STUDENT_REPO"',
' git -C "$TARGET" fetch student --prune || true',
' git -C "$TARGET" fetch student --prune',
' if git -C "$TARGET" show-ref --verify --quiet refs/remotes/student/main; then',
' git -C "$TARGET" checkout -B student-work student/main',
' git -C "$TARGET" checkout -b student-work student/main',
' else',
' git -C "$TARGET" checkout -B student-work origin/main',
' git -C "$TARGET" checkout -b student-work origin/main',
' git -C "$TARGET" push student student-work:main',
' fi',
'fi',
@@ -5732,36 +5731,8 @@ async function resetRemoteWorkspaceSession(
targetInput: RemoteWorkspaceTarget,
modules: Array<{ moduleName: string; folderName?: string | null; templateRepositoryUrl?: string | null }>,
): Promise<{ ok: boolean; message: string }> {
try {
const target = normalizeRemoteTarget(targetInput)
await stopRemoteWorkspaceModules(target, modules).catch(() => ({ ok: false, message: '모듈 중지 실패' }))
const commands = [
'set -e',
`ROOT=${quoteShellSingle(target.workspaceRoot)}`,
...expandRemotePathVar('ROOT'),
]
for (const module of modules) {
const folderName = module.folderName?.trim()
const templateRepositoryUrl = module.templateRepositoryUrl?.trim()
if (!folderName || !templateRepositoryUrl) continue
const templateRepositoryWithCredential = withGitCredential(remoteRepositoryUrl(templateRepositoryUrl))
commands.push(
`MODULE="$ROOT/${folderName}"`,
'if [ -d "$MODULE/.git" ]; then',
' git -C "$MODULE" remote remove student >/dev/null 2>&1 || true',
` git -C "$MODULE" remote set-url origin ${quoteShellSingle(templateRepositoryWithCredential)}`,
' git -C "$MODULE" fetch origin --prune',
' git -C "$MODULE" checkout -B main origin/main',
' git -C "$MODULE" reset --hard origin/main',
' git -C "$MODULE" clean -fdx',
'fi',
)
}
await runSsh(target, commands.join('\n'), 180000)
return { ok: true, message: '템플릿 기준으로 초기화했습니다.' }
} catch (error) {
return { ok: false, message: error instanceof Error ? error.message : String(error) }
}
// Keep the legacy IPC contract without resetting student files or Git history.
return stopRemoteWorkspaceModules(targetInput, modules)
}
async function restartWorkspaceModule(