diff --git a/lib/src/settings.rs b/lib/src/settings.rs index ceb28a7ad..e2418e608 100644 --- a/lib/src/settings.rs +++ b/lib/src/settings.rs @@ -29,15 +29,19 @@ pub struct RepoSettings { _config: config::Config, } +fn get_timestamp_config(config: &config::Config, key: &str) -> Option { + match config.get_string(key) { + Ok(timestamp_str) => match DateTime::parse_from_rfc3339(×tamp_str) { + Ok(datetime) => Some(Timestamp::from_datetime(datetime)), + Err(_) => None, + }, + Err(_) => None, + } +} + impl UserSettings { pub fn from_config(config: config::Config) -> Self { - let timestamp = match config.get_string("user.timestamp") { - Ok(timestamp_str) => match DateTime::parse_from_rfc3339(×tamp_str) { - Ok(datetime) => Some(Timestamp::from_datetime(datetime)), - Err(_) => None, - }, - Err(_) => None, - }; + let timestamp = get_timestamp_config(&config, "user.timestamp"); UserSettings { config, timestamp } } @@ -88,6 +92,10 @@ impl UserSettings { "(no email configured)" } + pub fn operation_timestamp(&self) -> Option { + get_timestamp_config(&self.config, "operation.timestamp") + } + pub fn operation_hostname(&self) -> String { self.config .get_string("operation.hostname") diff --git a/lib/src/transaction.rs b/lib/src/transaction.rs index 8f7bc6b11..d2cc60e84 100644 --- a/lib/src/transaction.rs +++ b/lib/src/transaction.rs @@ -28,6 +28,7 @@ pub struct Transaction { repo: Option, parent_ops: Vec, op_metadata: OperationMetadata, + end_time: Option, } impl Transaction { @@ -38,10 +39,12 @@ impl Transaction { ) -> Transaction { let parent_ops = vec![mut_repo.base_repo().operation().clone()]; let op_metadata = create_op_metadata(user_settings, description.to_string()); + let end_time = user_settings.operation_timestamp(); Transaction { repo: Some(mut_repo), parent_ops, op_metadata, + end_time, } } @@ -97,7 +100,7 @@ impl Transaction { let index = base_repo.index_store().write_index(mut_index).unwrap(); let view_id = base_repo.op_store().write_view(view.store_view()).unwrap(); - self.op_metadata.end_time = Timestamp::now(); + self.op_metadata.end_time = self.end_time.unwrap_or_else(Timestamp::now); let parents = self.parent_ops.iter().map(|op| op.id().clone()).collect(); let store_operation = op_store::Operation { view_id, @@ -119,7 +122,9 @@ impl Transaction { } pub fn create_op_metadata(user_settings: &UserSettings, description: String) -> OperationMetadata { - let start_time = Timestamp::now(); + let start_time = user_settings + .operation_timestamp() + .unwrap_or_else(Timestamp::now); let end_time = start_time.clone(); let hostname = user_settings.operation_hostname(); let username = user_settings.operation_username(); diff --git a/src/config.rs b/src/config.rs index c2e43ab83..abaa420a7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -78,6 +78,9 @@ fn env_overrides() -> config::Config { if let Ok(value) = env::var("JJ_TIMESTAMP") { builder = builder.set_override("user.timestamp", value).unwrap(); } + if let Ok(value) = env::var("JJ_OP_TIMESTAMP") { + builder = builder.set_override("operation.timestamp", value).unwrap(); + } if let Ok(value) = env::var("JJ_OP_HOSTNAME") { builder = builder.set_override("operation.hostname", value).unwrap(); } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 7951038d3..49438b6f7 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -72,6 +72,7 @@ impl TestEnvironment { cmd.env("JJ_TIMESTAMP", timestamp.to_rfc3339()); cmd.env("JJ_USER", "Test User"); cmd.env("JJ_EMAIL", "test.user@example.com"); + cmd.env("JJ_OP_TIMESTAMP", timestamp.to_rfc3339()); cmd.env("JJ_OP_HOSTNAME", "host.example.com"); cmd.env("JJ_OP_USERNAME", "test-username"); cmd