Skip to content

Commit 4aae5c0

Browse files
committed
fix(vcs): separate verbose and quiet git progress modes
Git progress output (--progress, stderr inherit) was enabled globally, causing indicatif progress bars in east update to collide with git's transfer progress from concurrent fetch operations. Fix: - Git::clone() and Git::fetch() default to quiet (stderr captured) - Git::clone_verbose() added for single interactive operations - east init -m uses clone_verbose (progress visible to user) - east update uses clone/fetch (quiet, indicatif controls the display) - fetch_file also reverted to quiet mode https://claude.ai/code/session_01XPaw9o6u8dbEfgjyyVNays
1 parent 0b4ff07 commit 4aae5c0

2 files changed

Lines changed: 40 additions & 14 deletions

File tree

crates/east-cli/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ async fn cmd_init_remote(
302302
let clone_dest = workspace_root.join(repo_name);
303303

304304
eprintln!("cloning manifest repository into {repo_name}/...");
305-
Git::clone(url, &clone_dest, revision)
305+
Git::clone_verbose(url, &clone_dest, revision)
306306
.await
307307
.into_diagnostic()
308308
.wrap_err("failed to clone manifest repository")?;

crates/east-vcs/src/git.rs

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,40 @@ impl Git {
2424
///
2525
/// Returns [`VcsError`] if the git command fails.
2626
pub async fn clone(url: &str, dest: &Path, revision: Option<&str>) -> Result<(), VcsError> {
27+
Self::clone_inner(url, dest, revision, false).await
28+
}
29+
30+
/// Clone with git progress output visible to the user.
31+
///
32+
/// Use this for single interactive operations (e.g. `east init -m`).
33+
/// Do NOT use in concurrent contexts (e.g. `east update`) where
34+
/// multiple clones run in parallel — progress output will collide.
35+
///
36+
/// # Errors
37+
///
38+
/// Returns [`VcsError`] if the git command fails.
39+
pub async fn clone_verbose(
40+
url: &str,
41+
dest: &Path,
42+
revision: Option<&str>,
43+
) -> Result<(), VcsError> {
44+
Self::clone_inner(url, dest, revision, true).await
45+
}
46+
47+
async fn clone_inner(
48+
url: &str,
49+
dest: &Path,
50+
revision: Option<&str>,
51+
verbose: bool,
52+
) -> Result<(), VcsError> {
2753
let is_sha =
2854
revision.is_some_and(|r| r.len() >= 40 && r.chars().all(|c| c.is_ascii_hexdigit()));
2955

3056
let mut cmd = Command::new("git");
31-
cmd.args(["clone", "--progress"]);
57+
cmd.arg("clone");
58+
if verbose {
59+
cmd.arg("--progress");
60+
}
3261
if let Some(rev) = revision {
3362
if !is_sha {
3463
cmd.args(["--single-branch", "-b", rev]);
@@ -37,7 +66,11 @@ impl Git {
3766
cmd.arg(url);
3867
cmd.arg(dest);
3968

40-
run_git_progress(cmd, dest).await?;
69+
if verbose {
70+
run_git_progress(cmd, dest).await?;
71+
} else {
72+
run_git(cmd, dest).await?;
73+
}
4174

4275
// For SHA revisions, checkout the specific commit after cloning
4376
if is_sha {
@@ -96,9 +129,9 @@ impl Git {
96129
let mut cmd = Command::new("git");
97130
cmd.args(["-C"]);
98131
cmd.arg(repo_path);
99-
cmd.args(["fetch", "--progress", "origin"]);
132+
cmd.args(["fetch", "origin"]);
100133

101-
run_git_progress(cmd, repo_path).await
134+
run_git(cmd, repo_path).await
102135
}
103136

104137
/// Checkout a specific revision in the repository at `repo_path`.
@@ -194,20 +227,13 @@ impl Git {
194227
revision: Option<&str>,
195228
) -> Result<(), VcsError> {
196229
let mut cmd = Command::new("git");
197-
cmd.args([
198-
"clone",
199-
"--progress",
200-
"--depth",
201-
"1",
202-
"--filter=blob:none",
203-
"--sparse",
204-
]);
230+
cmd.args(["clone", "--depth", "1", "--filter=blob:none", "--sparse"]);
205231
if let Some(rev) = revision {
206232
cmd.args(["--single-branch", "--branch", rev]);
207233
}
208234
cmd.arg(url);
209235
cmd.arg(dest);
210-
run_git_progress(cmd, dest).await?;
236+
run_git(cmd, dest).await?;
211237

212238
// git -C <dest> sparse-checkout set --no-cone <file>
213239
// --no-cone is required to match individual files (cone mode only matches directories)

0 commit comments

Comments
 (0)