Skip to content

Commit 2c4e34b

Browse files
committed
Skip big files in create_wd_tree()
1 parent d28d7e6 commit 2c4e34b

File tree

9 files changed

+83
-50
lines changed

9 files changed

+83
-50
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use gitbutler_error::error::Marker;
1313
use gitbutler_oplog::SnapshotExt;
1414
use gitbutler_oxidize::GixRepositoryExt;
1515
use gitbutler_project::access::WorktreeWritePermission;
16+
use gitbutler_project::AUTO_TRACK_LIMIT_BYTES;
1617
use gitbutler_reference::{Refname, RemoteRefname};
1718
use gitbutler_repo::logging::{LogUntil, RepositoryExt as _};
1819
use gitbutler_repo::{
@@ -305,7 +306,7 @@ impl BranchManager<'_> {
305306

306307
// We don't support having two branches applied that conflict with each other
307308
{
308-
let uncommited_changes_tree_id = repo.create_wd_tree()?.id();
309+
let uncommited_changes_tree_id = repo.create_wd_tree(AUTO_TRACK_LIMIT_BYTES)?.id();
309310
let gix_repo = self.ctx.gix_repository_for_merging_non_persisting()?;
310311
let merges_cleanly = gix_repo
311312
.merges_cleanly_compat(

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use gitbutler_oxidize::{
2626
git2_signature_to_gix_signature, git2_to_gix_object_id, gix_to_git2_oid, GixRepositoryExt,
2727
};
2828
use gitbutler_project::access::WorktreeWritePermission;
29+
use gitbutler_project::AUTO_TRACK_LIMIT_BYTES;
2930
use gitbutler_reference::{normalize_branch_name, Refname, RemoteRefname};
3031
use gitbutler_repo::{
3132
logging::{LogUntil, RepositoryExt as _},
@@ -1089,7 +1090,7 @@ pub fn is_remote_branch_mergeable(
10891090

10901091
let base_tree = find_base_tree(ctx.repo(), &branch_commit, &target_commit)?;
10911092

1092-
let wd_tree = ctx.repo().create_wd_tree()?;
1093+
let wd_tree = ctx.repo().create_wd_tree(AUTO_TRACK_LIMIT_BYTES)?;
10931094

10941095
let branch_tree = branch_commit.tree().context("failed to find branch tree")?;
10951096
let gix_repo_in_memory = ctx.gix_repository_for_merging()?.with_object_memory();

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use gitbutler_operating_modes::{
2020
};
2121
use gitbutler_oxidize::{git2_to_gix_object_id, gix_to_git2_index, GixRepositoryExt};
2222
use gitbutler_project::access::{WorktreeReadPermission, WorktreeWritePermission};
23+
use gitbutler_project::AUTO_TRACK_LIMIT_BYTES;
2324
use gitbutler_reference::{ReferenceName, Refname};
2425
use gitbutler_repo::{rebase::cherry_rebase, RepositoryExt};
2526
use gitbutler_repo::{signature, SignaturePurpose};
@@ -234,7 +235,7 @@ pub(crate) fn save_and_return_to_workspace(
234235
let parents = commit.parents().collect::<Vec<_>>();
235236

236237
// Recommit commit
237-
let tree = repository.create_wd_tree()?;
238+
let tree = repository.create_wd_tree(AUTO_TRACK_LIMIT_BYTES)?;
238239

239240
let (_, committer) = repository.signatures()?;
240241
let commit_headers = commit

crates/gitbutler-oplog/src/oplog.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use gitbutler_oxidize::{
2020
};
2121
use gitbutler_project::{
2222
access::{WorktreeReadPermission, WorktreeWritePermission},
23-
Project,
23+
Project, AUTO_TRACK_LIMIT_BYTES,
2424
};
2525
use gitbutler_repo::RepositoryExt;
2626
use gitbutler_repo::SignaturePurpose;
@@ -30,8 +30,6 @@ use gix::object::tree::diff::Change;
3030
use gix::prelude::ObjectIdExt;
3131
use tracing::instrument;
3232

33-
const SNAPSHOT_FILE_LIMIT_BYTES: u64 = 32 * 1024 * 1024;
34-
3533
/// The Oplog allows for crating snapshots of the current state of the project as well as restoring to a previous snapshot.
3634
/// Snapshots include the state of the working directory as well as all additional GitButler state (e.g. virtual branches, conflict state).
3735
/// The data is stored as git trees in the following shape:
@@ -312,7 +310,7 @@ impl OplogExt for Project {
312310
let old_wd_tree_id = tree_from_applied_vbranches(&gix_repo, commit.parent(0)?.id())?;
313311
let old_wd_tree = repo.find_tree(old_wd_tree_id)?;
314312

315-
repo.ignore_large_files_in_diffs(SNAPSHOT_FILE_LIMIT_BYTES)?;
313+
repo.ignore_large_files_in_diffs(AUTO_TRACK_LIMIT_BYTES)?;
316314

317315
let mut diff_opts = git2::DiffOptions::new();
318316
diff_opts
@@ -602,7 +600,7 @@ fn restore_snapshot(
602600
let workdir_tree_id = tree_from_applied_vbranches(&gix_repo, snapshot_commit_id)?;
603601
let workdir_tree = repo.find_tree(workdir_tree_id)?;
604602

605-
repo.ignore_large_files_in_diffs(SNAPSHOT_FILE_LIMIT_BYTES)?;
603+
repo.ignore_large_files_in_diffs(AUTO_TRACK_LIMIT_BYTES)?;
606604

607605
// Define the checkout builder
608606
let mut checkout_builder = git2::build::CheckoutBuilder::new();
@@ -739,7 +737,7 @@ fn lines_since_snapshot(project: &Project, repo: &git2::Repository) -> Result<us
739737
// This looks at the diff between the tree of the currently selected as 'default' branch (where new changes go)
740738
// and that same tree in the last snapshot. For some reason, comparing workdir to the workdir subree from
741739
// the snapshot simply does not give us what we need here, so instead using tree to tree comparison.
742-
repo.ignore_large_files_in_diffs(SNAPSHOT_FILE_LIMIT_BYTES)?;
740+
repo.ignore_large_files_in_diffs(AUTO_TRACK_LIMIT_BYTES)?;
743741

744742
let oplog_state = OplogHandle::new(&project.gb_dir());
745743
let Some(oplog_commit_id) = oplog_state.oplog_head()? else {

crates/gitbutler-project/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,6 @@ pub fn configure_git2() {
1818
// These settings are only changed from `main` of applications.
1919
git2::opts::strict_object_creation(false);
2020
}
21+
22+
/// The maximum size of files to automatically start tracking, i.e. untracked files we pick up for tree-creation.
23+
pub const AUTO_TRACK_LIMIT_BYTES: u64 = 32 * 1024 * 1024;

crates/gitbutler-repo/src/repository_ext.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,15 @@ pub trait RepositoryExt {
4242
fn sign_buffer(&self, buffer: &[u8]) -> Result<BString>;
4343
fn checkout_tree_builder<'a>(&'a self, tree: &'a git2::Tree<'a>) -> CheckoutTreeBuidler<'a>;
4444
fn maybe_find_branch_by_refname(&self, name: &Refname) -> Result<Option<git2::Branch>>;
45-
/// Based on the index, add all data similar to `git add .` and create a tree from it, which is returned.
46-
fn create_wd_tree(&self) -> Result<Tree>;
45+
/// Add all untracked and modified files in the worktree to
46+
/// the object database, and create a tree from it.
47+
///
48+
/// Use `untracked_limit_in_bytes` to control the maximum file size for untracked files
49+
/// before we stop tracking them automatically. Set it to 0 to disable the limit.
50+
///
51+
/// It should also be noted that this will fail if run on an empty branch
52+
/// or if the HEAD branch has no commits.
53+
fn create_wd_tree(&self, untracked_limit_in_bytes: u64) -> Result<Tree>;
4754

4855
/// Returns the `gitbutler/workspace` branch if the head currently points to it, or fail otherwise.
4956
/// Use it before any modification to the repository, or extra defensively each time the
@@ -105,15 +112,8 @@ impl RepositoryExt for git2::Repository {
105112
Ok(branch)
106113
}
107114

108-
/// Add all untracked and modified files in the worktree to
109-
/// the object database, and create a tree from it.
110-
///
111-
/// Note that right now, it doesn't skip big files.
112-
///
113-
/// It should also be noted that this will fail if run on an empty branch
114-
/// or if the HEAD branch has no commits.
115115
#[instrument(level = tracing::Level::DEBUG, skip(self), err(Debug))]
116-
fn create_wd_tree(&self) -> Result<Tree> {
116+
fn create_wd_tree(&self, untracked_limit_in_bytes: u64) -> Result<Tree> {
117117
use bstr::ByteSlice;
118118
use gix::dir::walk::EmissionMode;
119119
use gix::status;

0 commit comments

Comments
 (0)