## Summary Introduces a “ghost commit” workflow that snapshots the tree without touching refs. 1. git commit-tree writes an unreferenced commit object from the current index, optionally pointing to the current HEAD as its parent. 2. We then stash that commit id and use git restore --source <ghost> to roll the worktree (and index) back to the recorded snapshot later on. ## Details - Ghost commits live only as loose objects—we never update branches or tags—so the repo history stays untouched while still giving us a full tree snapshot. - Force-included paths let us stage otherwise ignored files before capturing the tree. - Restoration rehydrates both tracked and force-included files while leaving untracked/ignored files alone.
38 lines
911 B
Rust
38 lines
911 B
Rust
use std::path::Path;
|
|
|
|
use crate::GitToolingError;
|
|
|
|
#[cfg(unix)]
|
|
pub fn create_symlink(
|
|
_source: &Path,
|
|
link_target: &Path,
|
|
destination: &Path,
|
|
) -> Result<(), GitToolingError> {
|
|
use std::os::unix::fs::symlink;
|
|
|
|
symlink(link_target, destination)?;
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
pub fn create_symlink(
|
|
source: &Path,
|
|
link_target: &Path,
|
|
destination: &Path,
|
|
) -> Result<(), GitToolingError> {
|
|
use std::os::windows::fs::FileTypeExt;
|
|
use std::os::windows::fs::symlink_dir;
|
|
use std::os::windows::fs::symlink_file;
|
|
|
|
let metadata = std::fs::symlink_metadata(source)?;
|
|
if metadata.file_type().is_symlink_dir() {
|
|
symlink_dir(link_target, destination)?;
|
|
} else {
|
|
symlink_file(link_target, destination)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
#[cfg(not(any(unix, windows)))]
|
|
compile_error!("codex-git-tooling symlink support is only implemented for Unix and Windows");
|