just playing with tangled
at tmp-tutorial 172 lines 5.3 kB view raw
1// Copyright 2020 The Jujutsu Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#![allow(missing_docs)] 16 17use std::sync::Arc; 18 19use crate::backend::{self, BackendResult, ChangeId, CommitId, Signature, TreeId}; 20use crate::commit::Commit; 21use crate::conflicts::Conflict; 22use crate::repo::{MutableRepo, Repo}; 23use crate::settings::{JJRng, UserSettings}; 24 25#[must_use] 26pub struct CommitBuilder<'repo> { 27 mut_repo: &'repo mut MutableRepo, 28 rng: Arc<JJRng>, 29 commit: backend::Commit, 30 rewrite_source: Option<Commit>, 31} 32 33impl CommitBuilder<'_> { 34 pub fn for_new_commit<'repo>( 35 mut_repo: &'repo mut MutableRepo, 36 settings: &UserSettings, 37 parents: Vec<CommitId>, 38 tree_id: TreeId, 39 ) -> CommitBuilder<'repo> { 40 let signature = settings.signature(); 41 assert!(!parents.is_empty()); 42 let rng = settings.get_rng(); 43 let change_id = rng.new_change_id(mut_repo.store().change_id_length()); 44 let commit = backend::Commit { 45 parents, 46 predecessors: vec![], 47 // TODO(#1624): set this when appropriate 48 root_tree: Conflict::from_legacy_tree_id(tree_id), 49 uses_tree_conflict_format: false, 50 change_id, 51 description: String::new(), 52 author: signature.clone(), 53 committer: signature, 54 }; 55 CommitBuilder { 56 mut_repo, 57 rng, 58 commit, 59 rewrite_source: None, 60 } 61 } 62 63 pub fn for_rewrite_from<'repo>( 64 mut_repo: &'repo mut MutableRepo, 65 settings: &UserSettings, 66 predecessor: &Commit, 67 ) -> CommitBuilder<'repo> { 68 let mut commit = predecessor.store_commit().clone(); 69 commit.predecessors = vec![predecessor.id().clone()]; 70 commit.committer = settings.signature(); 71 // If the user had not configured a name and email before but now they have, 72 // update the author fields with the new information. 73 if commit.author.name == UserSettings::user_name_placeholder() { 74 commit.author.name = commit.committer.name.clone(); 75 } 76 if commit.author.email == UserSettings::user_email_placeholder() { 77 commit.author.email = commit.committer.email.clone(); 78 } 79 CommitBuilder { 80 mut_repo, 81 commit, 82 rng: settings.get_rng(), 83 rewrite_source: Some(predecessor.clone()), 84 } 85 } 86 87 pub fn parents(&self) -> &[CommitId] { 88 &self.commit.parents 89 } 90 91 pub fn set_parents(mut self, parents: Vec<CommitId>) -> Self { 92 assert!(!parents.is_empty()); 93 self.commit.parents = parents; 94 self 95 } 96 97 pub fn predecessors(&self) -> &[CommitId] { 98 &self.commit.predecessors 99 } 100 101 pub fn set_predecessors(mut self, predecessors: Vec<CommitId>) -> Self { 102 self.commit.predecessors = predecessors; 103 self 104 } 105 106 pub fn tree(&self) -> &TreeId { 107 self.commit.root_tree.as_legacy_tree_id() 108 } 109 110 pub fn set_tree(mut self, tree_id: TreeId) -> Self { 111 self.commit.root_tree = Conflict::from_legacy_tree_id(tree_id); 112 self 113 } 114 115 pub fn change_id(&self) -> &ChangeId { 116 &self.commit.change_id 117 } 118 119 pub fn set_change_id(mut self, change_id: ChangeId) -> Self { 120 self.commit.change_id = change_id; 121 self 122 } 123 124 pub fn generate_new_change_id(mut self) -> Self { 125 self.commit.change_id = self 126 .rng 127 .new_change_id(self.mut_repo.store().change_id_length()); 128 self 129 } 130 131 pub fn description(&self) -> &str { 132 &self.commit.description 133 } 134 135 pub fn set_description(mut self, description: impl Into<String>) -> Self { 136 self.commit.description = description.into(); 137 self 138 } 139 140 pub fn author(&self) -> &Signature { 141 &self.commit.author 142 } 143 144 pub fn set_author(mut self, author: Signature) -> Self { 145 self.commit.author = author; 146 self 147 } 148 149 pub fn committer(&self) -> &Signature { 150 &self.commit.committer 151 } 152 153 pub fn set_committer(mut self, committer: Signature) -> Self { 154 self.commit.committer = committer; 155 self 156 } 157 158 pub fn write(self) -> BackendResult<Commit> { 159 let mut rewrite_source_id = None; 160 if let Some(rewrite_source) = self.rewrite_source { 161 if *rewrite_source.change_id() == self.commit.change_id { 162 rewrite_source_id.replace(rewrite_source.id().clone()); 163 } 164 } 165 let commit = self.mut_repo.write_commit(self.commit)?; 166 if let Some(rewrite_source_id) = rewrite_source_id { 167 self.mut_repo 168 .record_rewritten_commit(rewrite_source_id, commit.id().clone()) 169 } 170 Ok(commit) 171 } 172}