Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(core): handle lockcache corruption error #27

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 55 additions & 15 deletions core/src/clients/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,31 +72,48 @@ pub struct Git {
pub struct Opts<'a> {
pub ignored_errors: &'a [&'a str],
pub should_log_stdout: bool,
pub return_complete_error: bool,
}

impl Default for Opts<'_> {
fn default() -> Self {
Opts {
ignored_errors: &[],
should_log_stdout: true,
return_complete_error: false,
}
}
}

impl Opts<'_> {
pub fn with_ignored<'a>(ignored_errors: &'a [&'a str]) -> Opts {
pub fn new_with_ignored<'a>(ignored_errors: &'a [&'a str]) -> Opts {
Opts {
ignored_errors,
should_log_stdout: true,
return_complete_error: false,
}
}

pub fn without_logs<'a>() -> Opts<'a> {
pub fn new_without_logs<'a>() -> Opts<'a> {
Opts {
ignored_errors: &[],
should_log_stdout: false,
return_complete_error: false,
}
}

pub fn new_with_complete_error<'a>() -> Opts<'a> {
Opts {
ignored_errors: &[],
should_log_stdout: true,
return_complete_error: true,
}
}

pub fn with_complete_error(mut self) -> Self {
self.return_complete_error = true;
self
}
}

impl Git {
Expand Down Expand Up @@ -326,17 +343,39 @@ impl Git {
};
// Ignore "remote ref does not exist" error - if that's the case, then the remote branch that we want to delete
// doesn't exist anyway, so it's effectively deleted
self.run(&args, Opts::with_ignored(&["remote ref does not exist"]))
.await
self.run(
&args,
Opts::new_with_ignored(&["remote ref does not exist"]),
)
.await
}

pub async fn verify_locks(&self) -> anyhow::Result<VerifyLocksResponse> {
let output = self
let output = match self
.run_and_collect_output(
&["lfs", "locks", "--verify", "--json"],
Opts::without_logs(),
Opts::new_without_logs().with_complete_error(),
)
.await?;
.await
{
Ok(output) => output,
Err(e) => {
// if this is a problem with the lock cache, delete the lock cache file
if e.to_string().contains("lockcache.db") {
let lock_cache_path = self.repo_path.join(".git/lfs/lockcache.db");
if lock_cache_path.exists() {
std::fs::remove_file(lock_cache_path)?;
}
}

// then try again
self.run_and_collect_output(
&["lfs", "locks", "--verify", "--json"],
Opts::new_without_logs(),
)
.await?
}
};

let response: VerifyLocksResponse = serde_json::from_str(&output)?;

Expand All @@ -351,10 +390,7 @@ impl Git {
"--pretty=format:%H|%s|%an|%aI",
git_ref,
],
Opts {
ignored_errors: &[],
should_log_stdout: false,
},
Opts::default(),
)
.await
}
Expand All @@ -367,7 +403,7 @@ impl Git {
pub async fn status(&self) -> anyhow::Result<String> {
self.run_and_collect_output(
&["status", "--porcelain", "-uall", "--branch"],
Opts::without_logs(),
Opts::new_without_logs(),
)
.await
}
Expand All @@ -386,7 +422,7 @@ impl Git {
}

pub async fn diff_filenames(&self, range: &str) -> anyhow::Result<String> {
self.run_and_collect_output(&["diff", "--name-only", range], Opts::without_logs())
self.run_and_collect_output(&["diff", "--name-only", range], Opts::new_without_logs())
.await
}

Expand All @@ -409,8 +445,7 @@ impl Git {
.await;
match res {
Err(e) => {
error!("git {:?} failed with error: {}", args, e);
bail!("Git command failed. Check the log for details.");
bail!("git {:?} failed with error: {}", args, e);
}
Ok(_) => Ok(output.unwrap()),
}
Expand Down Expand Up @@ -535,6 +570,11 @@ impl Git {
let locked_lines = err_lines.read();
let err_output: String = locked_lines.join("\n");
error!("Failed to run: {}.\n{}", git_cmd_str, err_output);

if opts.return_complete_error {
bail!("Git command failed: {}", err_output);
}

bail!("Git command failed. Check the log for details.");
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ impl Task for AddOp {
}

self.git_client
.run(args.as_slice(), Opts::without_logs())
.run(args.as_slice(), Opts::new_without_logs())
.await?;

Ok(())
Expand Down
5 changes: 1 addition & 4 deletions friendshipper/src-tauri/src/repo/operations/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,10 +330,7 @@ impl StatusOp {

debug!("s3 entries list: {:?}", builds);

let git_opts = git::Opts {
ignored_errors: &[],
should_log_stdout: false,
};
let git_opts = git::Opts::default();
let local_commit_shas: String = self
.git_client
.run_and_collect_output(&["log", "--format=\"%H\"", "-1000"], git_opts)
Expand Down
Loading