Skip to content

Commit 6f1e271

Browse files
committed
Use gix in operating_mode and avoid panic
1 parent f1c53a8 commit 6f1e271

File tree

2 files changed

+52
-9
lines changed

2 files changed

+52
-9
lines changed

crates/gitbutler-operating-modes/src/lib.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,26 @@ pub enum OperatingMode {
7979
}
8080

8181
pub fn operating_mode(ctx: &Context) -> OperatingMode {
82-
let repo = ctx.git2_repo.get().unwrap();
82+
let outside = || OperatingMode::OutsideWorkspace(outside_workspace_metadata(ctx).unwrap_or_default());
83+
84+
let Ok(repo) = ctx.repo.get() else {
85+
// If we can't even open/borrow the repo handle, attempting to compute metadata would just
86+
// try (and fail) to open it again.
87+
return OperatingMode::OutsideWorkspace(OutsideWorkspaceMetadata::default());
88+
};
8389
let Ok(head_ref) = repo.head() else {
84-
return OperatingMode::OutsideWorkspace(outside_workspace_metadata(ctx).unwrap_or_default());
90+
return outside();
8591
};
86-
87-
let Some(head_ref_name) = head_ref.name() else {
88-
return OperatingMode::OutsideWorkspace(outside_workspace_metadata(ctx).unwrap_or_default());
92+
let Some(head_ref_name) = head_ref.referent_name().map(|name| name.as_bstr()) else {
93+
return outside();
8994
};
9095

91-
if OPEN_WORKSPACE_REFS.contains(&head_ref_name) {
96+
if OPEN_WORKSPACE_REFS
97+
.iter()
98+
.any(|workspace_ref| workspace_ref.as_bytes() == head_ref_name)
99+
{
92100
OperatingMode::OpenWorkspace
93-
} else if head_ref_name == EDIT_BRANCH_REF {
101+
} else if EDIT_BRANCH_REF.as_bytes() == head_ref_name {
94102
let edit_mode_metadata = read_edit_mode_metadata(ctx);
95103

96104
match edit_mode_metadata {
@@ -100,11 +108,11 @@ pub fn operating_mode(ctx: &Context) -> OperatingMode {
100108
"Failed to open in edit mode, falling back to outside workspace {}",
101109
error
102110
);
103-
OperatingMode::OutsideWorkspace(outside_workspace_metadata(ctx).unwrap_or_default())
111+
outside()
104112
}
105113
}
106114
} else {
107-
OperatingMode::OutsideWorkspace(outside_workspace_metadata(ctx).unwrap_or_default())
115+
outside()
108116
}
109117
}
110118

crates/gitbutler-operating-modes/tests/operating_modes.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,41 @@ fn create_edit_mode_metadata(ctx: &Context) {
2222
}
2323

2424
mod operating_modes {
25+
mod invalid_repo_fallback {
26+
use gitbutler_testsupport::{Case, Suite};
27+
28+
#[test]
29+
fn operating_mode_falls_back_to_outside_workspace_when_repo_cannot_be_opened() {
30+
let suite = Suite::default();
31+
let Case { ctx, .. } = &suite.new_case();
32+
33+
// Make opening the repo fail by removing the `.git` directory.
34+
std::fs::remove_dir_all(&ctx.gitdir).unwrap();
35+
36+
assert_eq!(
37+
gitbutler_operating_modes::operating_mode(ctx),
38+
gitbutler_operating_modes::OperatingMode::OutsideWorkspace(
39+
gitbutler_operating_modes::OutsideWorkspaceMetadata::default()
40+
)
41+
);
42+
}
43+
}
44+
45+
mod edit_branch_no_metadata_fallback {
46+
use gitbutler_operating_modes::{OperatingMode, operating_mode};
47+
use gitbutler_testsupport::{Case, Suite};
48+
49+
#[test]
50+
fn operating_mode_falls_back_to_outside_workspace_when_on_edit_branch_without_metadata() {
51+
let suite = Suite::default();
52+
let Case { ctx, .. } = &suite.new_case();
53+
54+
crate::create_and_checkout_branch(ctx, "gitbutler/edit");
55+
56+
assert!(matches!(operating_mode(ctx), OperatingMode::OutsideWorkspace(_)));
57+
}
58+
}
59+
2560
mod open_workspace_mode {
2661
use gitbutler_operating_modes::{ensure_open_workspace_mode, in_open_workspace_mode};
2762
use gitbutler_testsupport::{Case, Suite};

0 commit comments

Comments
 (0)