Skip to content

Commit ad74d5c

Browse files
codexByron
andcommitted
ctx: deprecate git2 boundary and finalize migration doc
Co-authored-by: Sebastian Thiel <sebastian.thiel@icloud.com>
1 parent 2800015 commit ad74d5c

17 files changed

Lines changed: 102 additions & 32 deletions

File tree

crates/but-ctx/src/legacy.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ impl Context {
3535

3636
/// Open the repository identified by `legacy_project` and `settings`, while controlling
3737
/// how the repository sources configuration via `repo_open_mode`.
38+
#[allow(
39+
deprecated,
40+
reason = "Context owns the deprecated boundary cache and must initialize it."
41+
)]
3842
pub fn new_from_legacy_project_and_settings_with_repo_open_mode(
3943
legacy_project: &gitbutler_project::Project,
4044
settings: AppSettings,

crates/but-ctx/src/lib.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,10 @@ pub struct Context {
114114
/// Keep new uses confined to the residual `git2` boundary:
115115
/// checkout/worktree materialization, staged tree/index materialization,
116116
/// and deliberate compatibility adapters that still require libgit2.
117-
/// Everything else should use [`Self::repo`] instead.
117+
/// Activation and read-side flows should use [`Self::repo`] instead.
118+
#[deprecated(
119+
note = "Boundary-only escape hatch: use Context::repo unless you are crossing the remaining libgit2 checkout/index, hook, or transport/auth adapter boundary."
120+
)]
118121
pub git2_repo: OnDemand<git2::Repository>,
119122
/// An open handle to the database. It's initialized lazily upon first access.
120123
/// It is also what makes this type non-Clone, which is fair.
@@ -155,6 +158,10 @@ pub struct ThreadSafeContext {
155158
}
156159

157160
impl From<ThreadSafeContext> for Context {
161+
#[allow(
162+
deprecated,
163+
reason = "Context owns the deprecated boundary cache and must initialize it."
164+
)]
158165
fn from(value: ThreadSafeContext) -> Self {
159166
let ThreadSafeContext {
160167
settings,
@@ -268,6 +275,10 @@ impl Context {
268275

269276
/// Just like [`Context::new()`], but allows controlling how the repository
270277
/// sources configuration via `repo_open_mode`.
278+
#[allow(
279+
deprecated,
280+
reason = "Context owns the deprecated boundary cache and must initialize it."
281+
)]
271282
pub fn new_with_repo_open_mode(
272283
gitdir: impl Into<PathBuf>,
273284
app_config_dir: impl AsRef<Path>,
@@ -373,6 +384,10 @@ impl Context {
373384
Self::from_repo_with_legacy_support(repo, repo_open_mode)
374385
}
375386

387+
#[allow(
388+
deprecated,
389+
reason = "Context owns the deprecated boundary cache and must initialize it."
390+
)]
376391
fn from_repo_with_legacy_support(
377392
repo: gix::Repository,
378393
repo_open_mode: RepoOpenMode,
@@ -433,6 +448,10 @@ impl Context {
433448
///
434449
/// Particularly useful in testing, which might start off with just a Git repository.
435450
/// **Note that it does not have support for legacy projects to encourage single-branch compatible code.**
451+
#[allow(
452+
deprecated,
453+
reason = "Context owns the deprecated boundary cache and must initialize it."
454+
)]
436455
pub fn from_repo(repo: gix::Repository) -> anyhow::Result<Context> {
437456
let gitdir = repo.git_dir().to_owned();
438457
let project_data_dir = repo.gitbutler_storage_path()?;
@@ -959,6 +978,10 @@ impl Context {
959978
}
960979

961980
/// Take all copyable values and place them in an instance that can pass across thread boundaries.
981+
#[allow(
982+
deprecated,
983+
reason = "Context owns the deprecated boundary cache and must move it out internally."
984+
)]
962985
pub fn into_sync(self) -> ThreadSafeContext {
963986
let Context {
964987
settings,

crates/but-testsupport/src/legacy/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ pub mod virtual_branches {
3434
pub fn set_test_target(ctx: &Context) -> anyhow::Result<()> {
3535
let mut vb_state = VirtualBranchesHandle::new(ctx.project_data_dir());
3636
let (remote_repo, _tmp) = empty_bare_repository();
37+
#[expect(
38+
deprecated,
39+
reason = "legacy fixture coverage for transport/setup compatibility"
40+
)]
3741
let git2_repo = &*ctx.git2_repo.get()?;
3842
let mut remote = git2_repo
3943
.remote("origin", remote_repo.path().to_str().unwrap())

crates/but-workspace/src/legacy/stacks.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -498,12 +498,10 @@ pub fn stack_branches(stack_id: StackId, ctx: &Context) -> anyhow::Result<Vec<ui
498498
let mut current_base = stack.merge_base(ctx)?;
499499
let repo = ctx.repo.get()?;
500500
for internal in stack.branches() {
501-
let upstream_reference = ctx
502-
.git2_repo
503-
.get()?
504-
.find_reference(&internal.remote_reference(remote.as_str()))
505-
.ok()
506-
.map(|_| internal.remote_reference(remote.as_str()));
501+
let upstream_reference_name = internal.remote_reference(remote.as_str());
502+
let upstream_reference = repo
503+
.try_find_reference(&upstream_reference_name)?
504+
.map(|_| upstream_reference_name);
507505
let result = ui::Branch {
508506
name: internal.name().to_owned().into(),
509507
remote_tracking_branch: upstream_reference.map(Into::into),

crates/gitbutler-branch-actions/src/base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ fn go_back_to_integration(ctx: &Context, default_target: &Target) -> Result<Base
156156

157157
let final_tree_id = outcome.tree.write()?.detach();
158158

159+
#[expect(deprecated, reason = "checkout/materialization boundary")]
159160
let git2_repo = &*ctx.git2_repo.get()?;
160161
let final_tree = git2_repo.find_tree(final_tree_id.to_git2())?;
161162
git2_repo

crates/gitbutler-branch-actions/src/branch_manager/branch_removal.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ impl BranchManager<'_> {
3535
.to_string());
3636
}
3737

38+
#[expect(deprecated, reason = "checkout/materialization boundary")]
3839
let git2_repo = self.ctx.git2_repo.get()?;
3940

4041
// Commit any assigned diffspecs if such exist so that it will be part of the unapplied branch.

crates/gitbutler-branch-actions/src/integration.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub fn update_workspace_commit_with_vb_state(
8080
.get_default_target()
8181
.context("failed to get target")?;
8282

83+
#[expect(deprecated, reason = "workspace checkout/index boundary")]
8384
let repo = &*ctx.git2_repo.get()?;
8485
let gix_repo = ctx.repo.get()?.clone();
8586

@@ -263,6 +264,7 @@ fn verify_current_branch_name(ctx: &Context) -> Result<&Context> {
263264

264265
// TODO(ST): Probably there should not be an implicit vbranch creation here.
265266
fn verify_head_is_clean(ctx: &Context, perm: &mut RepoExclusive) -> Result<()> {
267+
#[expect(deprecated, reason = "soft reset/index boundary")]
266268
let git2_repo = &*ctx.git2_repo.get()?;
267269
let gix_repo = ctx.repo.get()?.clone();
268270
let head_commit_id = gix_repo.head_id()?.detach();

crates/gitbutler-branch-actions/tests/branch-actions/hooks.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ fn post_commit_hook_rejection() -> anyhow::Result<()> {
1717
echo 'rejected'
1818
exit 1
1919
";
20+
#[expect(deprecated, reason = "hook compatibility coverage")]
2021
git2_hooks::create_hook(&*ctx.git2_repo.get()?, git2_hooks::HOOK_POST_COMMIT, hook);
2122

2223
assert_eq!(
@@ -40,6 +41,7 @@ fn message_hook_rejection() -> anyhow::Result<()> {
4041
echo 'rejected'
4142
exit 1
4243
";
44+
#[expect(deprecated, reason = "hook compatibility coverage")]
4345
git2_hooks::create_hook(&*ctx.git2_repo.get()?, git2_hooks::HOOK_COMMIT_MSG, hook);
4446

4547
let message = "commit message".to_owned();
@@ -63,6 +65,7 @@ fn rewrite_message() -> anyhow::Result<()> {
6365
#!/bin/sh
6466
echo 'rewritten message' > $1
6567
";
68+
#[expect(deprecated, reason = "hook compatibility coverage")]
6669
git2_hooks::create_hook(&*ctx.git2_repo.get()?, git2_hooks::HOOK_COMMIT_MSG, hook);
6770

6871
let message = "commit message".to_owned();
@@ -86,6 +89,7 @@ fn keep_message() -> anyhow::Result<()> {
8689
#!/bin/sh
8790
echo 'commit message' > $1
8891
";
92+
#[expect(deprecated, reason = "hook compatibility coverage")]
8993
git2_hooks::create_hook(&*ctx.git2_repo.get()?, git2_hooks::HOOK_COMMIT_MSG, hook);
9094

9195
let message = "commit message\n".to_owned();
@@ -102,6 +106,7 @@ fn husky_hooks_disabled_even_if_present() -> anyhow::Result<()> {
102106
let case = suite.new_case();
103107
let Case { ctx, .. } = &case;
104108

109+
#[expect(deprecated, reason = "hook compatibility coverage")]
105110
let repo = ctx.git2_repo.get()?;
106111
let husky_dir = repo
107112
.path()

crates/gitbutler-edit-mode/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ fn get_commit_index(ctx: &Context, commit_id: gix::ObjectId) -> Result<git2::Ind
5858
}
5959
gix_to_git2_index(&index)
6060
} else {
61+
#[expect(deprecated, reason = "index materialization boundary")]
6162
let git2_repo = &*ctx.git2_repo.get()?;
6263
let commit_tree = git2_repo.find_tree(commit.tree.to_git2())?;
6364
let mut index = git2::Index::new()?;
@@ -115,6 +116,7 @@ fn get_uncommitted_changes(repo: &gix::Repository) -> Result<gix::ObjectId> {
115116

116117
fn checkout_edit_branch(ctx: &Context, commit_id: gix::ObjectId) -> Result<()> {
117118
let repo = &*ctx.repo.get()?;
119+
#[expect(deprecated, reason = "checkout/index materialization boundary")]
118120
let git2_repo = &*ctx.git2_repo.get()?;
119121
let commit = git2_repo.find_commit(commit_id.to_git2())?;
120122

@@ -234,6 +236,7 @@ pub(crate) fn abort_and_return_to_workspace(
234236
);
235237
}
236238

239+
#[expect(deprecated, reason = "checkout/materialization boundary")]
237240
let repo = &*ctx.git2_repo.get()?;
238241

239242
// Checkout gitbutler workspace branch
@@ -253,6 +256,7 @@ pub(crate) fn abort_and_return_to_workspace(
253256

254257
pub(crate) fn save_and_return_to_workspace(ctx: &Context, perm: &mut RepoExclusive) -> Result<()> {
255258
let edit_mode_metadata = read_edit_mode_metadata(ctx).context("Failed to read metadata")?;
259+
#[expect(deprecated, reason = "checkout/index materialization boundary")]
256260
let git2_repo = &*ctx.git2_repo.get()?;
257261
let repo = &*ctx.repo.get()?;
258262

@@ -360,6 +364,7 @@ pub(crate) fn starting_index_state(
360364
bail!("Starting index state can only be fetched while in edit mode")
361365
};
362366

367+
#[expect(deprecated, reason = "conflicted tree lookup boundary")]
363368
let git2_repo = &*ctx.git2_repo.get()?;
364369
let repo = &*ctx.repo.get()?;
365370

crates/gitbutler-edit-mode/tests/edit_mode.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ fn conficted_entries_get_written_when_leaving_edit_mode() -> Result<()> {
227227
let stack_id = stack_id(&ctx)?;
228228
enter_edit_mode(&mut ctx, foobar, stack_id)?;
229229

230+
#[expect(deprecated, reason = "checkout/index boundary coverage")]
230231
let repo = ctx.git2_repo.get()?;
231232
let init = repo.find_reference("refs/heads/main")?.peel_to_commit()?;
232233
let left = repo.find_reference("refs/heads/left")?.peel_to_commit()?;

0 commit comments

Comments
 (0)