diff --git a/examples/custom-backend/main.rs b/examples/custom-backend/main.rs index af7735ac8..fbfd2b354 100644 --- a/examples/custom-backend/main.rs +++ b/examples/custom-backend/main.rs @@ -19,7 +19,8 @@ use git2::Repository; use jujutsu::cli_util::{CliRunner, CommandError, CommandHelper}; use jujutsu::ui::Ui; use jujutsu_lib::backend::{ - Backend, BackendResult, Commit, CommitId, Conflict, ConflictId, FileId, SymlinkId, Tree, TreeId, + Backend, BackendResult, ChangeId, Commit, CommitId, Conflict, ConflictId, FileId, SymlinkId, + Tree, TreeId, }; use jujutsu_lib::git_backend::GitBackend; use jujutsu_lib::repo::StoreFactories; @@ -120,6 +121,10 @@ impl Backend for JitBackend { self.inner.root_commit_id() } + fn root_change_id(&self) -> &ChangeId { + self.inner.root_change_id() + } + fn empty_tree_id(&self) -> &TreeId { self.inner.empty_tree_id() } diff --git a/lib/src/backend.rs b/lib/src/backend.rs index ee3300206..7ffb73dab 100644 --- a/lib/src/backend.rs +++ b/lib/src/backend.rs @@ -18,7 +18,6 @@ use std::io::Read; use std::result::Result; use std::vec::Vec; -use once_cell::sync::Lazy; use thiserror::Error; use crate::content_hash::ContentHash; @@ -350,13 +349,7 @@ fn iter_half_bytes(bytes: &[u8]) -> impl ExactSizeIterator + '_ { }) } -pub fn root_change_id() -> &'static ChangeId { - static ROOT_CHANGE_ID: Lazy = - Lazy::new(|| ChangeId::new(vec![0; CHANGE_ID_HASH_LENGTH])); - &ROOT_CHANGE_ID -} - -pub fn make_root_commit(empty_tree_id: TreeId) -> Commit { +pub fn make_root_commit(root_change_id: ChangeId, empty_tree_id: TreeId) -> Commit { let timestamp = Timestamp { timestamp: MillisSinceEpoch(0), tz_offset: 0, @@ -366,12 +359,11 @@ pub fn make_root_commit(empty_tree_id: TreeId) -> Commit { email: String::new(), timestamp, }; - let change_id = root_change_id().to_owned(); Commit { parents: vec![], predecessors: vec![], root_tree: empty_tree_id, - change_id, + change_id: root_change_id, description: String::new(), author: signature.clone(), committer: signature, @@ -398,6 +390,8 @@ pub trait Backend: Send + Sync + Debug { fn root_commit_id(&self) -> &CommitId; + fn root_change_id(&self) -> &ChangeId; + fn empty_tree_id(&self) -> &TreeId; fn read_tree(&self, path: &RepoPath, id: &TreeId) -> BackendResult; diff --git a/lib/src/git_backend.rs b/lib/src/git_backend.rs index 011d0cbaf..e9e76bf13 100644 --- a/lib/src/git_backend.rs +++ b/lib/src/git_backend.rs @@ -25,7 +25,7 @@ use prost::Message; use crate::backend::{ make_root_commit, Backend, BackendError, BackendResult, ChangeId, Commit, CommitId, Conflict, ConflictId, ConflictPart, FileId, MillisSinceEpoch, ObjectId, Signature, SymlinkId, Timestamp, - Tree, TreeId, TreeValue, + Tree, TreeId, TreeValue, CHANGE_ID_HASH_LENGTH, }; use crate::repo_path::{RepoPath, RepoPathComponent}; use crate::stacked_table::{ReadonlyTable, TableSegment, TableStore}; @@ -38,6 +38,7 @@ const CONFLICT_SUFFIX: &str = ".jjconflict"; pub struct GitBackend { repo: Mutex, root_commit_id: CommitId, + root_change_id: ChangeId, empty_tree_id: TreeId, extra_metadata_store: TableStore, cached_extra_metadata: Mutex>>, @@ -46,10 +47,12 @@ pub struct GitBackend { impl GitBackend { fn new(repo: git2::Repository, extra_metadata_store: TableStore) -> Self { let root_commit_id = CommitId::from_bytes(&[0; HASH_LENGTH]); + let root_change_id = ChangeId::from_bytes(&[0; CHANGE_ID_HASH_LENGTH]); let empty_tree_id = TreeId::from_hex("4b825dc642cb6eb9a060e54bf8d69288fbee4904"); GitBackend { repo: Mutex::new(repo), root_commit_id, + root_change_id, empty_tree_id, extra_metadata_store, cached_extra_metadata: Mutex::new(None), @@ -250,6 +253,10 @@ impl Backend for GitBackend { &self.root_commit_id } + fn root_change_id(&self) -> &ChangeId { + &self.root_change_id + } + fn empty_tree_id(&self) -> &TreeId { &self.empty_tree_id } @@ -382,7 +389,10 @@ impl Backend for GitBackend { fn read_commit(&self, id: &CommitId) -> BackendResult { if *id == self.root_commit_id { - return Ok(make_root_commit(self.empty_tree_id.clone())); + return Ok(make_root_commit( + self.root_change_id().clone(), + self.empty_tree_id.clone(), + )); } let git_commit_id = validate_git_object_id(id)?; diff --git a/lib/src/local_backend.rs b/lib/src/local_backend.rs index b8e33d5b3..ddd5ca32b 100644 --- a/lib/src/local_backend.rs +++ b/lib/src/local_backend.rs @@ -25,7 +25,7 @@ use tempfile::{NamedTempFile, PersistError}; use crate::backend::{ make_root_commit, Backend, BackendError, BackendResult, ChangeId, Commit, CommitId, Conflict, ConflictId, ConflictPart, FileId, MillisSinceEpoch, ObjectId, Signature, SymlinkId, Timestamp, - Tree, TreeId, TreeValue, + Tree, TreeId, TreeValue, CHANGE_ID_HASH_LENGTH, }; use crate::content_hash::blake2b_hash; use crate::file_util::persist_content_addressed_temp_file; @@ -69,6 +69,7 @@ fn map_not_found_err(err: std::io::Error, id: &impl ObjectId) -> BackendError { pub struct LocalBackend { path: PathBuf, root_commit_id: CommitId, + root_change_id: ChangeId, empty_tree_id: TreeId, } @@ -89,10 +90,12 @@ impl LocalBackend { pub fn load(store_path: &Path) -> Self { let root_commit_id = CommitId::from_bytes(&[0; 64]); + let root_change_id = ChangeId::from_bytes(&[0; CHANGE_ID_HASH_LENGTH]); let empty_tree_id = TreeId::from_hex("482ae5a29fbe856c7272f2071b8b0f0359ee2d89ff392b8a900643fbd0836eccd067b8bf41909e206c90d45d6e7d8b6686b93ecaee5fe1a9060d87b672101310"); LocalBackend { path: store_path.to_path_buf(), root_commit_id, + root_change_id, empty_tree_id, } } @@ -185,6 +188,10 @@ impl Backend for LocalBackend { &self.root_commit_id } + fn root_change_id(&self) -> &ChangeId { + &self.root_change_id + } + fn empty_tree_id(&self) -> &TreeId { &self.empty_tree_id } @@ -231,7 +238,10 @@ impl Backend for LocalBackend { fn read_commit(&self, id: &CommitId) -> BackendResult { if *id == self.root_commit_id { - return Ok(make_root_commit(self.empty_tree_id.clone())); + return Ok(make_root_commit( + self.root_change_id().clone(), + self.empty_tree_id.clone(), + )); } let path = self.commit_path(id); diff --git a/lib/src/repo.rs b/lib/src/repo.rs index a36fbe0a6..68bff5834 100644 --- a/lib/src/repo.rs +++ b/lib/src/repo.rs @@ -294,7 +294,7 @@ impl ReadonlyRepo { pub fn shortest_unique_id_prefix_len(&self, target_id_bytes: &[u8]) -> usize { let root_commit_id = self.store().root_commit_id(); - let root_change_id = backend::root_change_id(); + let root_change_id = self.store().root_change_id(); if target_id_bytes == root_commit_id.as_bytes() || target_id_bytes == root_change_id.as_bytes() { diff --git a/lib/src/store.rs b/lib/src/store.rs index 6892fda06..94df6f5e0 100644 --- a/lib/src/store.rs +++ b/lib/src/store.rs @@ -18,7 +18,7 @@ use std::sync::{Arc, RwLock}; use crate::backend; use crate::backend::{ - Backend, BackendResult, CommitId, Conflict, ConflictId, FileId, SymlinkId, TreeId, + Backend, BackendResult, ChangeId, CommitId, Conflict, ConflictId, FileId, SymlinkId, TreeId, }; use crate::commit::Commit; use crate::repo_path::RepoPath; @@ -59,6 +59,10 @@ impl Store { self.backend.root_commit_id() } + pub fn root_change_id(&self) -> &ChangeId { + self.backend.root_change_id() + } + pub fn root_commit(self: &Arc) -> Commit { self.get_commit(self.backend.root_commit_id()).unwrap() }