Skip to content

Commit 1374f37

Browse files
committed
fix work tree as cwd
1 parent c4d86be commit 1374f37

File tree

4 files changed

+41
-24
lines changed

4 files changed

+41
-24
lines changed

crates/chat-cli/src/cli/chat/checkpoint.rs

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ pub struct CheckpointManager {
3636
/// Path to the shadow (bare) git repository
3737
pub shadow_repo_path: PathBuf,
3838

39+
/// Path to current working directory
40+
pub work_tree_path: PathBuf,
41+
3942
/// All checkpoints in chronological order
4043
pub checkpoints: Vec<Checkpoint>,
4144

@@ -103,14 +106,17 @@ impl CheckpointManager {
103106
let path = path.as_ref();
104107
os.fs.create_dir_all(path).await?;
105108

109+
let work_tree_path =
110+
std::env::current_dir().map_err(|e| eyre!("Failed to get current working directory: {}", e))?;
111+
106112
// Initialize bare repository
107-
run_git(path, false, &["init", "--bare", &path.to_string_lossy()])?;
113+
run_git(path, None, &["init", "--bare", &path.to_string_lossy()])?;
108114

109115
// Configure git
110116
configure_git(&path.to_string_lossy())?;
111117

112118
// Create initial checkpoint
113-
stage_commit_tag(&path.to_string_lossy(), "Initial state", "0")?;
119+
stage_commit_tag(&path.to_string_lossy(), &work_tree_path, "Initial state", "0")?;
114120

115121
let initial_checkpoint = Checkpoint {
116122
tag: "0".to_string(),
@@ -126,6 +132,7 @@ impl CheckpointManager {
126132

127133
Ok(Self {
128134
shadow_repo_path: path.to_path_buf(),
135+
work_tree_path,
129136
checkpoints: vec![initial_checkpoint],
130137
tag_index,
131138
current_turn: 0,
@@ -146,7 +153,12 @@ impl CheckpointManager {
146153
tool_name: Option<String>,
147154
) -> Result<()> {
148155
// Stage, commit and tag
149-
stage_commit_tag(&self.shadow_repo_path.to_string_lossy(), description, tag)?;
156+
stage_commit_tag(
157+
&self.shadow_repo_path.to_string_lossy(),
158+
&self.work_tree_path,
159+
description,
160+
tag,
161+
)?;
150162

151163
// Record checkpoint metadata
152164
let checkpoint = Checkpoint {
@@ -175,7 +187,9 @@ impl CheckpointManager {
175187

176188
if hard {
177189
// Hard: reset the whole work-tree to the tag
178-
let output = run_git(&self.shadow_repo_path, true, &["reset", "--hard", tag])?;
190+
let output = run_git(&self.shadow_repo_path, Some(&self.work_tree_path), &[
191+
"reset", "--hard", tag,
192+
])?;
179193
if !output.status.success() {
180194
bail!("Failed to restore: {}", String::from_utf8_lossy(&output.stderr));
181195
}
@@ -187,7 +201,9 @@ impl CheckpointManager {
187201
return Ok(());
188202
}
189203
// Use checkout against work-tree
190-
let output = run_git(&self.shadow_repo_path, true, &["checkout", tag, "--", "."])?;
204+
let output = run_git(&self.shadow_repo_path, Some(&self.work_tree_path), &[
205+
"checkout", tag, "--", ".",
206+
])?;
191207
if !output.status.success() {
192208
bail!("Failed to restore: {}", String::from_utf8_lossy(&output.stderr));
193209
}
@@ -205,7 +221,7 @@ impl CheckpointManager {
205221
let out = run_git(
206222
&self.shadow_repo_path,
207223
// work_tree
208-
false,
224+
None,
209225
&["ls-tree", "-r", "--name-only", tag],
210226
)?;
211227
Ok(!out.stdout.is_empty())
@@ -223,7 +239,7 @@ impl CheckpointManager {
223239

224240
/// Compute file statistics between two checkpoints
225241
pub fn compute_stats_between(&self, from: &str, to: &str) -> Result<FileStats> {
226-
let output = run_git(&self.shadow_repo_path, false, &["diff", "--name-status", from, to])?;
242+
let output = run_git(&self.shadow_repo_path, None, &["diff", "--name-status", from, to])?;
227243

228244
let mut stats = FileStats::default();
229245
for line in String::from_utf8_lossy(&output.stdout).lines() {
@@ -246,7 +262,7 @@ impl CheckpointManager {
246262
let mut result = String::new();
247263

248264
// Get file changes
249-
let output = run_git(&self.shadow_repo_path, false, &["diff", "--name-status", from, to])?;
265+
let output = run_git(&self.shadow_repo_path, None, &["diff", "--name-status", from, to])?;
250266

251267
for line in String::from_utf8_lossy(&output.stdout).lines() {
252268
if let Some((status, file)) = line.split_once('\t') {
@@ -261,7 +277,7 @@ impl CheckpointManager {
261277
}
262278

263279
// Add statistics
264-
let stat_output = run_git(&self.shadow_repo_path, false, &[
280+
let stat_output = run_git(&self.shadow_repo_path, None, &[
265281
"diff",
266282
from,
267283
to,
@@ -279,7 +295,10 @@ impl CheckpointManager {
279295

280296
/// Check for uncommitted changes
281297
pub fn has_changes(&self) -> Result<bool> {
282-
let output = run_git(&self.shadow_repo_path, true, &["status", "--porcelain"])?;
298+
let output = run_git(&self.shadow_repo_path, Some(&self.work_tree_path), &[
299+
"status",
300+
"--porcelain",
301+
])?;
283302
Ok(!output.stdout.is_empty())
284303
}
285304

@@ -351,18 +370,18 @@ fn is_in_git_repo() -> bool {
351370
}
352371

353372
fn configure_git(shadow_path: &str) -> Result<()> {
354-
run_git(Path::new(shadow_path), false, &["config", "user.name", "Q"])?;
355-
run_git(Path::new(shadow_path), false, &["config", "user.email", "qcli@local"])?;
356-
run_git(Path::new(shadow_path), false, &["config", "core.preloadindex", "true"])?;
373+
run_git(Path::new(shadow_path), None, &["config", "user.name", "Q"])?;
374+
run_git(Path::new(shadow_path), None, &["config", "user.email", "qcli@local"])?;
375+
run_git(Path::new(shadow_path), None, &["config", "core.preloadindex", "true"])?;
357376
Ok(())
358377
}
359378

360-
fn stage_commit_tag(shadow_path: &str, message: &str, tag: &str) -> Result<()> {
379+
fn stage_commit_tag(shadow_path: &str, work_tree: &Path, message: &str, tag: &str) -> Result<()> {
361380
// Stage all changes
362-
run_git(Path::new(shadow_path), true, &["add", "-A"])?;
381+
run_git(Path::new(shadow_path), Some(work_tree), &["add", "-A"])?;
363382

364383
// Commit
365-
let output = run_git(Path::new(shadow_path), true, &[
384+
let output = run_git(Path::new(shadow_path), Some(work_tree), &[
366385
"commit",
367386
"--allow-empty",
368387
"--no-verify",
@@ -375,20 +394,20 @@ fn stage_commit_tag(shadow_path: &str, message: &str, tag: &str) -> Result<()> {
375394
}
376395

377396
// Tag
378-
let output = run_git(Path::new(shadow_path), false, &["tag", tag])?;
397+
let output = run_git(Path::new(shadow_path), None, &["tag", tag])?;
379398
if !output.status.success() {
380399
bail!("Git tag failed: {}", String::from_utf8_lossy(&output.stderr));
381400
}
382401

383402
Ok(())
384403
}
385404

386-
fn run_git(dir: &Path, with_work_tree: bool, args: &[&str]) -> Result<Output> {
405+
fn run_git(dir: &Path, work_tree: Option<&Path>, args: &[&str]) -> Result<Output> {
387406
let mut cmd = Command::new("git");
388407
cmd.arg(format!("--git-dir={}", dir.display()));
389408

390-
if with_work_tree {
391-
cmd.arg("--work-tree=.");
409+
if let Some(work_tree_path) = work_tree {
410+
cmd.arg(format!("--work-tree={}", work_tree_path.display()));
392411
}
393412

394413
cmd.args(args);

crates/chat-cli/src/cli/chat/cli/checkpoint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ impl CheckpointSubcommand {
107107
session.stderr,
108108
style::SetForegroundColor(Color::Yellow),
109109
style::Print(
110-
"⚠️ Checkpoint is disabled while in tangent mode. Disable tangent mode with: q settings -d chat.enableTangentMode.\n\n"
110+
"⚠️ Checkpoint is disabled while in tangent mode. Please exit tangent mode if you want to use checkpoint.\n\n"
111111
),
112112
style::SetForegroundColor(Color::Reset),
113113
)?;

crates/chat-cli/src/cli/chat/cli/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pub enum SlashCommand {
109109
// #[command(flatten)]
110110
// Root(RootSubcommand),
111111
#[command(
112-
about = "(Beta) Manage workspace checkpoints (list, expand, diff, restore)\n Experimental features may be changed or removed at any time",
112+
about = "(Beta) Manage workspace checkpoints (init, list, restore, expand, diff, clean)\nExperimental features may be changed or removed at any time",
113113
hide = true,
114114
subcommand
115115
)]

crates/chat-cli/src/cli/chat/conversation.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ use crate::cli::agent::hook::{
7676
use crate::cli::chat::ChatError;
7777
use crate::cli::chat::checkpoint::{
7878
Checkpoint,
79-
Checkpoint,
80-
CheckpointManager,
8179
CheckpointManager,
8280
};
8381
use crate::cli::chat::cli::model::{

0 commit comments

Comments
 (0)