ok/jj
1
0
Fork 0
forked from mirrors/jj

working_copy: don't snapshot new files larger than 1MiB by default

This commit is contained in:
Ben Saunders 2023-06-28 15:10:19 -07:00 committed by Benjamin Saunders
parent 32d622863a
commit 351e7feef5
8 changed files with 51 additions and 0 deletions

View file

@ -29,6 +29,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* The default editor on Windows is now `Notepad` instead of `pico`.
* `jj` will fail attempts to snapshot new files larger than 1MiB by default. This behavior
can be customized with the `snapshot.max-new-file-size` config option.
### New features
* Default template for `jj log` now does not show irrelevant information

View file

@ -1289,6 +1289,7 @@ See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-workin
base_ignores,
fsmonitor_kind: self.settings.fsmonitor_kind()?,
progress: progress.as_ref().map(|x| x as _),
max_new_file_size: self.settings.max_new_file_size()?,
})?;
drop(progress);
if new_tree_id != *wc_commit.tree_id() {

View file

@ -1338,6 +1338,7 @@ fn cmd_untrack(
base_ignores,
fsmonitor_kind: command.settings().fsmonitor_kind()?,
progress: None,
max_new_file_size: command.settings().max_new_file_size()?,
})?;
if wc_tree_id != new_tree_id {
let wc_tree = store.get_tree(&RepoPath::root(), &wc_tree_id)?;

View file

@ -329,6 +329,17 @@
"type": "string"
}
}
},
"snapshot": {
"type": "object",
"description": "Parameters governing automatic capture of files into the working copy commit",
"properties": {
"max-new-file-size": {
"type": "integer",
"description": "New files with a size in bytes above this threshold are not snapshotted, unless the threshold is 0",
"default": "1048576"
}
}
}
}
}

View file

@ -8,3 +8,6 @@
paginate = "auto"
pager = { command = ["less", "-FRX"], env = { LESSCHARSET = "utf-8" } }
log-word-wrap = false
[snapshot]
max-new-file-size = 1048576

View file

@ -414,6 +414,7 @@ pub fn edit_diff_external(
base_ignores,
fsmonitor_kind: settings.fsmonitor_kind()?,
progress: None,
max_new_file_size: settings.max_new_file_size()?,
})?;
Ok(right_tree_state.current_tree_id().clone())
}

View file

@ -196,6 +196,16 @@ impl UserSettings {
.get_string("ui.graph.style")
.unwrap_or_else(|_| "curved".to_string())
}
pub fn max_new_file_size(&self) -> Result<u64, config::ConfigError> {
let cfg = self.config.get::<u64>("snapshot.max-new-file-size");
match cfg {
Ok(0) => Ok(u64::MAX),
x @ Ok(_) => x,
Err(config::ConfigError::NotFound(_)) => Ok(1024 * 1024),
e @ Err(_) => e,
}
}
}
/// This Rng uses interior mutability to allow generating random values using an

View file

@ -310,6 +310,12 @@ pub enum SnapshotError {
InternalBackendError(#[from] BackendError),
#[error(transparent)]
TreeStateError(#[from] TreeStateError),
#[error("New file {path} of size {size} exceeds snapshot.max-new-file-size ({max_size})")]
NewFileTooLarge {
path: PathBuf,
size: u64,
max_size: u64,
},
}
#[derive(Debug, Error)]
@ -358,6 +364,7 @@ pub struct SnapshotOptions<'a> {
pub base_ignores: Arc<GitIgnoreFile>,
pub fsmonitor_kind: Option<FsmonitorKind>,
pub progress: Option<&'a SnapshotProgress<'a>>,
pub max_new_file_size: u64,
}
impl SnapshotOptions<'_> {
@ -366,6 +373,7 @@ impl SnapshotOptions<'_> {
base_ignores: GitIgnoreFile::empty(),
fsmonitor_kind: None,
progress: None,
max_new_file_size: u64::MAX,
}
}
}
@ -630,6 +638,7 @@ impl TreeState {
base_ignores,
fsmonitor_kind,
progress,
max_new_file_size,
} = options;
let sparse_matcher = self.sparse_matcher();
@ -665,6 +674,7 @@ impl TreeState {
present_files_tx,
directory_to_visit,
progress,
max_new_file_size,
)
})?;
@ -736,6 +746,7 @@ impl TreeState {
present_files_tx: Sender<RepoPath>,
directory_to_visit: DirectoryToVisit,
progress: Option<&SnapshotProgress>,
max_new_file_size: u64,
) -> Result<(), SnapshotError> {
let DirectoryToVisit {
dir,
@ -841,6 +852,7 @@ impl TreeState {
present_files_tx.clone(),
directory_to_visit,
progress,
max_new_file_size,
)?;
}
} else if matcher.matches(&path) {
@ -859,6 +871,14 @@ impl TreeState {
message: format!("Failed to stat file {}", entry.path().display()),
err,
})?;
if maybe_current_file_state.is_none() && metadata.len() > max_new_file_size
{
return Err(SnapshotError::NewFileTooLarge {
path: entry.path().clone(),
size: metadata.len(),
max_size: max_new_file_size,
});
}
if let Some(new_file_state) = file_state(&metadata) {
present_files_tx.send(path.clone()).ok();
let update = self.get_updated_tree_value(