diff --git a/server/src/worktree.rs b/server/src/worktree.rs index 7b4097a..136079a 100644 --- a/server/src/worktree.rs +++ b/server/src/worktree.rs @@ -155,43 +155,13 @@ fn create_worktree_sync( Ok(()) } -/// Exclude `.story_kit/work/` from git tracking in a worktree. +/// Placeholder for worktree isolation of `.story_kit/work/`. /// -/// This prevents pipeline file moves (upcoming → current → qa → merge → archived) -/// from being committed on feature branches, which avoids rename/delete merge -/// conflicts when merging back to master. -/// -/// Instead of sparse checkout (which has complex config-leaking issues between -/// worktrees and the main checkout), we write `.story_kit/work/` to the -/// worktree's local exclude file (`$GIT_DIR/info/exclude`). This makes git -/// treat those paths as untracked without affecting other checkouts. -fn configure_sparse_checkout(wt_path: &Path) -> Result<(), String> { - // Mark all .story_kit/work/ files with skip-worktree so git ignores - // any local changes to them. This prevents pipeline file moves from - // showing up as modifications on the feature branch. - let ls_output = Command::new("git") - .args(["ls-files", "-z", ".story_kit/work/"]) - .current_dir(wt_path) - .output() - .map_err(|e| format!("git ls-files: {e}"))?; - - let files: Vec = String::from_utf8_lossy(&ls_output.stdout) - .split('\0') - .filter(|s| !s.is_empty()) - .map(|s| s.to_string()) - .collect(); - - if !files.is_empty() { - let mut args: Vec<&str> = vec!["update-index", "--skip-worktree"]; - for f in &files { - args.push(f.as_str()); - } - let _ = Command::new("git") - .args(&args) - .current_dir(wt_path) - .output(); - } - +/// Previous approaches (sparse checkout, skip-worktree) all leaked state +/// from worktrees back to the main checkout's config/index. For now this +/// is a no-op — merge conflicts from pipeline file moves are handled at +/// merge time by the mergemaster (squash merge ignores work/ diffs). +fn configure_sparse_checkout(_wt_path: &Path) -> Result<(), String> { Ok(()) } @@ -431,7 +401,7 @@ mod tests { } #[test] - fn sparse_checkout_excludes_story_kit_work() { + fn worktree_has_all_files_including_work() { let tmp = TempDir::new().unwrap(); let project_root = tmp.path().join("my-project"); fs::create_dir_all(&project_root).unwrap(); @@ -456,25 +426,11 @@ mod tests { let branch = "feature/test-sparse"; create_worktree_sync(&project_root, &wt_path, branch).unwrap(); - // .story_kit/work/ still exists on disk but has skip-worktree set + // Worktree should have all files including .story_kit/work/ assert!(wt_path.join(".story_kit").join("work").exists()); assert!(wt_path.join(".git").exists()); - // Modify the work file — git should not report it as changed - fs::write(work_dir.join("test_story.md"), "# Modified").unwrap(); - let status = Command::new("git") - .args(["status", "--porcelain", ".story_kit/work/"]) - .current_dir(&wt_path) - .output() - .unwrap(); - let status_output = String::from_utf8_lossy(&status.stdout); - assert!( - status_output.trim().is_empty(), - ".story_kit/work/ changes should be invisible in worktree, got: {status_output}" - ); - - // Main checkout must NOT be affected. - // The .story_kit/work/ directory must still exist in the project root. + // Main checkout must NOT be affected by worktree creation. assert!( work_dir.exists(), ".story_kit/work/ must still exist in the main checkout"