Skip to content

Commit ff04bda

Browse files
committed
docs: warn about unsupported Git configuration settings
1 parent 562f546 commit ff04bda

File tree

3 files changed

+110
-1
lines changed

3 files changed

+110
-1
lines changed

git-branchless-lib/src/git/repo.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ pub enum Error {
5252
#[error("could not open repository: {0}")]
5353
OpenRepo(#[source] git2::Error),
5454

55+
#[error("could not open repository: {0}")]
56+
UnsupportedExtensionWorktreeConfig(#[source] git2::Error),
57+
5558
#[error("could not read index: {0}")]
5659
ReadIndex(#[source] git2::Error),
5760

@@ -457,7 +460,18 @@ impl Repo {
457460
/// Get the Git repository associated with the given directory.
458461
#[instrument]
459462
pub fn from_dir(path: &Path) -> Result<Self> {
460-
let repo = git2::Repository::discover(path).map_err(Error::OpenRepo)?;
463+
let repo = match git2::Repository::discover(path) {
464+
Ok(repo) => repo,
465+
Err(err)
466+
if err.code() == git2::ErrorCode::GenericError
467+
&& err
468+
.message()
469+
.contains("unsupported extension name extensions.worktreeconfig") =>
470+
{
471+
return Err(Error::UnsupportedExtensionWorktreeConfig(err))
472+
}
473+
Err(err) => return Err(Error::OpenRepo(err)),
474+
};
461475
Ok(Repo { inner: repo })
462476
}
463477

git-branchless/src/commands/mod.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,19 @@ mod wrap;
2323
use std::any::Any;
2424
use std::convert::TryInto;
2525
use std::ffi::OsString;
26+
use std::fmt::Write;
2627
use std::path::PathBuf;
2728
use std::time::SystemTime;
2829

2930
use clap::Parser;
31+
use cursive::theme::BaseColor;
32+
use cursive::utils::markup::StyledString;
3033
use eyre::Context;
3134
use itertools::Itertools;
35+
use lib::core::formatting::printable_styled_string;
3236
use lib::core::rewrite::MergeConflictRemediation;
37+
use lib::git::Repo;
38+
use lib::git::RepoError;
3339
use lib::util::ExitCode;
3440
use tracing_chrome::ChromeLayerBuilder;
3541
use tracing_error::ErrorLayer;
@@ -119,6 +125,11 @@ fn do_main_and_drop_locals() -> eyre::Result<i32> {
119125
};
120126
let effects = Effects::new(color);
121127

128+
if let Some(ExitCode(exit_code)) = check_unsupported_config_options(&effects)? {
129+
let exit_code: i32 = exit_code.try_into()?;
130+
return Ok(exit_code);
131+
}
132+
122133
let ExitCode(exit_code) = match command {
123134
Command::Amend { move_options } => amend::amend(&effects, &git_run_info, &move_options)?,
124135

@@ -433,6 +444,43 @@ fn install_tracing() -> eyre::Result<impl Drop> {
433444
Ok(flush_guard)
434445
}
435446

447+
fn check_unsupported_config_options(effects: &Effects) -> eyre::Result<Option<ExitCode>> {
448+
let _repo = match Repo::from_current_dir() {
449+
Ok(repo) => repo,
450+
Err(RepoError::UnsupportedExtensionWorktreeConfig(_)) => {
451+
writeln!(
452+
effects.get_output_stream(),
453+
"\
454+
{error}
455+
456+
Usually, this configuration setting is enabled when initializing a sparse
457+
checkout. See https://github.com/arxanas/git-branchless/issues/278 for more
458+
information.
459+
460+
Here are some options:
461+
462+
- To unset the configuration option, run: git config --unset extensions.worktreeConfig
463+
- This is safe unless you created another worktree also using a sparse checkout.
464+
- Try upgrading to Git v2.36+ and reinitializing your sparse checkout.",
465+
error = printable_styled_string(
466+
effects.get_glyphs(),
467+
StyledString::styled(
468+
"\
469+
Error: the Git configuration setting `extensions.worktreeConfig` is enabled in
470+
this repository. Due to upstream libgit2 limitations, git-branchless does not
471+
support repositories with this configuration option enabled.",
472+
BaseColor::Red.light()
473+
)
474+
)?,
475+
)?;
476+
return Ok(Some(ExitCode(1)));
477+
}
478+
Err(_) => return Ok(None),
479+
};
480+
481+
Ok(None)
482+
}
483+
436484
/// Re-exports of internals for testing purposes.
437485
pub mod testing {
438486
pub use crate::commands::undo::testing as undo;

git-branchless/tests/test_branchless.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,50 @@ fn test_profiling() -> eyre::Result<()> {
8383

8484
Ok(())
8585
}
86+
87+
#[test]
88+
fn test_sparse_checkout() -> eyre::Result<()> {
89+
let git = make_git()?;
90+
git.init_repo()?;
91+
92+
if git.run(&["sparse-checkout", "set"]).is_err() {
93+
return Ok(());
94+
}
95+
96+
{
97+
let (stdout, _stderr) = git.run(&["config", "extensions.worktreeConfig"])?;
98+
insta::assert_snapshot!(stdout, @r###"
99+
true
100+
"###);
101+
}
102+
103+
if let Ok((stdout, _stderr)) = git.run(&["smartlog"]) {
104+
insta::assert_snapshot!(stdout, @"@ f777ecc (> master) create initial.txt
105+
");
106+
} else {
107+
let (stdout, _stderr) = git.run_with_options(
108+
&["smartlog"],
109+
&GitRunOptions {
110+
expected_exit_code: 1,
111+
..Default::default()
112+
},
113+
)?;
114+
insta::assert_snapshot!(stdout, @r###"
115+
Error: the Git configuration setting `extensions.worktreeConfig` is enabled in
116+
this repository. Due to upstream libgit2 limitations, git-branchless does not
117+
support repositories with this configuration option enabled.
118+
119+
Usually, this configuration setting is enabled when initializing a sparse
120+
checkout. See https://github.com/arxanas/git-branchless/issues/278 for more
121+
information.
122+
123+
Here are some options:
124+
125+
- To unset the configuration option, run: git config --unset extensions.worktreeConfig
126+
- This is safe unless you created another worktree also using a sparse checkout.
127+
- Try upgrading to Git v2.36+ and reinitializing your sparse checkout.
128+
"###);
129+
}
130+
131+
Ok(())
132+
}

0 commit comments

Comments
 (0)