From 73a73932f430fe991f26222ba2735332c03c0e77 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 5 Mar 2022 20:44:59 +0800 Subject: [PATCH] keep-going support on the command-line (#301) That way it's possible to see all the errors that happened which may help with debugging certain issues. --- gitoxide-core/src/index/mod.rs | 20 +++++++++++++++++++- src/plumbing/main.rs | 2 ++ src/plumbing/options.rs | 3 +++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/gitoxide-core/src/index/mod.rs b/gitoxide-core/src/index/mod.rs index 6d12fa9997f..7613aea677e 100644 --- a/gitoxide-core/src/index/mod.rs +++ b/gitoxide-core/src/index/mod.rs @@ -2,6 +2,7 @@ use anyhow::bail; use std::path::{Path, PathBuf}; use git_repository as git; +use git_repository::worktree::index::checkout; use git_repository::{odb::FindExt, Progress}; pub struct Options { @@ -106,6 +107,7 @@ pub mod checkout_exclusive { pub index: super::Options, /// If true, all files will be written with zero bytes despite having made an ODB lookup. pub empty_files: bool, + pub keep_going: bool, } } @@ -117,6 +119,7 @@ pub fn checkout_exclusive( checkout_exclusive::Options { index: Options { object_hash, .. }, empty_files, + keep_going, }: checkout_exclusive::Options, ) -> anyhow::Result<()> { let repo = repo @@ -157,6 +160,7 @@ pub fn checkout_exclusive( // TODO: turn the two following flags into an enum destination_is_initially_empty: true, overwrite_existing: false, + keep_going, ..Default::default() }; @@ -168,7 +172,7 @@ pub fn checkout_exclusive( bytes.init(None, git::progress::bytes()); let start = std::time::Instant::now(); - match &repo { + let checkout::Outcome { errors, collisions } = match &repo { Some(repo) => git::worktree::index::checkout( &mut index, dest_directory, @@ -209,5 +213,19 @@ pub fn checkout_exclusive( entries_for_checkout, repo.is_none().then(|| "empty").unwrap_or_default() )); + + if !(collisions.is_empty() && errors.is_empty()) { + let mut messages = Vec::new(); + if !errors.is_empty() { + messages.push(format!("kept going through {} errors(s)", errors.len())); + } + if !collisions.is_empty() { + messages.push(format!("encountered {} collision(s)", collisions.len())); + } + bail!( + "One or more errors occurred - checkout is incomplete: {}", + messages.join(", ") + ); + } Ok(()) } diff --git a/src/plumbing/main.rs b/src/plumbing/main.rs index f0f5b5ddde6..0de19d243e5 100644 --- a/src/plumbing/main.rs +++ b/src/plumbing/main.rs @@ -82,6 +82,7 @@ pub fn main() -> Result<()> { directory, empty_files, repository, + keep_going, } => prepare_and_run( "index-checkout", verbose, @@ -97,6 +98,7 @@ pub fn main() -> Result<()> { core::index::checkout_exclusive::Options { index: core::index::Options { object_hash, format }, empty_files, + keep_going, }, ) }, diff --git a/src/plumbing/options.rs b/src/plumbing/options.rs index 53a4e4fa9af..8208d618a1c 100644 --- a/src/plumbing/options.rs +++ b/src/plumbing/options.rs @@ -413,6 +413,9 @@ pub mod index { /// in the index. Use this measure the impact on extracting objects on overall performance. #[clap(long, short = 'r')] repository: Option, + /// Ignore errors and keep checking out as many files as possible, and report all errors at the end of the operation. + #[clap(long, short = 'k')] + keep_going: bool, /// Enable to query the object database yet write only empty files. This is useful to measure the overhead of ODB query /// compared to writing the bytes to disk. #[clap(long, short = 'e', requires = "repository")]