jujutsu_lib/
commit_builder.rs1use std::sync::Arc;
16
17use crate::backend::{self, BackendResult, ChangeId, CommitId, Signature, TreeId};
18use crate::commit::Commit;
19use crate::repo::{MutableRepo, Repo};
20use crate::settings::{JJRng, UserSettings};
21
22#[must_use]
23pub struct CommitBuilder<'repo> {
24 mut_repo: &'repo mut MutableRepo,
25 rng: Arc<JJRng>,
26 commit: backend::Commit,
27 rewrite_source: Option<Commit>,
28}
29
30impl CommitBuilder<'_> {
31 pub fn for_new_commit<'repo>(
32 mut_repo: &'repo mut MutableRepo,
33 settings: &UserSettings,
34 parents: Vec<CommitId>,
35 tree_id: TreeId,
36 ) -> CommitBuilder<'repo> {
37 let signature = settings.signature();
38 assert!(!parents.is_empty());
39 let rng = settings.get_rng();
40 let change_id = rng.new_change_id(mut_repo.store().change_id_length());
41 let commit = backend::Commit {
42 parents,
43 predecessors: vec![],
44 root_tree: tree_id,
45 change_id,
46 description: String::new(),
47 author: signature.clone(),
48 committer: signature,
49 };
50 CommitBuilder {
51 mut_repo,
52 rng,
53 commit,
54 rewrite_source: None,
55 }
56 }
57
58 pub fn for_rewrite_from<'repo>(
59 mut_repo: &'repo mut MutableRepo,
60 settings: &UserSettings,
61 predecessor: &Commit,
62 ) -> CommitBuilder<'repo> {
63 let mut commit = predecessor.store_commit().clone();
64 commit.predecessors = vec![predecessor.id().clone()];
65 commit.committer = settings.signature();
66 if commit.author.name == UserSettings::user_name_placeholder() {
69 commit.author.name = commit.committer.name.clone();
70 }
71 if commit.author.email == UserSettings::user_email_placeholder() {
72 commit.author.email = commit.committer.email.clone();
73 }
74 CommitBuilder {
75 mut_repo,
76 commit,
77 rng: settings.get_rng(),
78 rewrite_source: Some(predecessor.clone()),
79 }
80 }
81
82 pub fn set_parents(mut self, parents: Vec<CommitId>) -> Self {
83 assert!(!parents.is_empty());
84 self.commit.parents = parents;
85 self
86 }
87
88 pub fn set_predecessors(mut self, predecessors: Vec<CommitId>) -> Self {
89 self.commit.predecessors = predecessors;
90 self
91 }
92
93 pub fn set_tree(mut self, tree_id: TreeId) -> Self {
94 self.commit.root_tree = tree_id;
95 self
96 }
97
98 pub fn set_change_id(mut self, change_id: ChangeId) -> Self {
99 self.commit.change_id = change_id;
100 self
101 }
102
103 pub fn generate_new_change_id(mut self) -> Self {
104 self.commit.change_id = self
105 .rng
106 .new_change_id(self.mut_repo.store().change_id_length());
107 self
108 }
109
110 pub fn set_description(mut self, description: impl Into<String>) -> Self {
111 self.commit.description = description.into();
112 self
113 }
114
115 pub fn set_author(mut self, author: Signature) -> Self {
116 self.commit.author = author;
117 self
118 }
119
120 pub fn set_committer(mut self, committer: Signature) -> Self {
121 self.commit.committer = committer;
122 self
123 }
124
125 pub fn write(self) -> BackendResult<Commit> {
126 let mut rewrite_source_id = None;
127 if let Some(rewrite_source) = self.rewrite_source {
128 if *rewrite_source.change_id() == self.commit.change_id {
129 rewrite_source_id.replace(rewrite_source.id().clone());
130 }
131 }
132 let commit = self.mut_repo.write_commit(self.commit)?;
133 if let Some(rewrite_source_id) = rewrite_source_id {
134 self.mut_repo
135 .record_rewritten_commit(rewrite_source_id, commit.id().clone())
136 }
137 Ok(commit)
138 }
139}