just playing with tangled
at tmp-tutorial 160 lines 4.2 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::cmp::Ordering; 18use std::fmt::{Debug, Error, Formatter}; 19use std::hash::{Hash, Hasher}; 20use std::sync::Arc; 21 22use crate::backend; 23use crate::backend::{BackendError, ChangeId, CommitId, Signature, TreeId}; 24use crate::merged_tree::MergedTree; 25use crate::repo_path::RepoPath; 26use crate::store::Store; 27use crate::tree::Tree; 28 29#[derive(Clone)] 30pub struct Commit { 31 store: Arc<Store>, 32 id: CommitId, 33 data: Arc<backend::Commit>, 34} 35 36impl Debug for Commit { 37 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { 38 f.debug_struct("Commit").field("id", &self.id).finish() 39 } 40} 41 42impl PartialEq for Commit { 43 fn eq(&self, other: &Self) -> bool { 44 self.id == other.id 45 } 46} 47 48impl Eq for Commit {} 49 50impl Ord for Commit { 51 fn cmp(&self, other: &Self) -> Ordering { 52 self.id.cmp(&other.id) 53 } 54} 55 56impl PartialOrd for Commit { 57 fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 58 Some(self.cmp(other)) 59 } 60} 61 62impl Hash for Commit { 63 fn hash<H: Hasher>(&self, state: &mut H) { 64 self.id.hash(state) 65 } 66} 67 68impl Commit { 69 pub fn new(store: Arc<Store>, id: CommitId, data: Arc<backend::Commit>) -> Self { 70 Commit { store, id, data } 71 } 72 73 pub fn store(&self) -> &Arc<Store> { 74 &self.store 75 } 76 77 pub fn id(&self) -> &CommitId { 78 &self.id 79 } 80 81 pub fn parent_ids(&self) -> &[CommitId] { 82 &self.data.parents 83 } 84 85 pub fn parents(&self) -> Vec<Commit> { 86 self.data 87 .parents 88 .iter() 89 .map(|id| self.store.get_commit(id).unwrap()) 90 .collect() 91 } 92 93 pub fn predecessor_ids(&self) -> &[CommitId] { 94 &self.data.predecessors 95 } 96 97 pub fn predecessors(&self) -> Vec<Commit> { 98 self.data 99 .predecessors 100 .iter() 101 .map(|id| self.store.get_commit(id).unwrap()) 102 .collect() 103 } 104 105 // TODO(#1624): Delete when all callers use `merged_tree()` 106 pub fn tree(&self) -> Tree { 107 self.store 108 .get_tree(&RepoPath::root(), self.data.root_tree.as_legacy_tree_id()) 109 .unwrap() 110 } 111 112 pub fn merged_tree(&self) -> Result<MergedTree, BackendError> { 113 if self.data.uses_tree_conflict_format { 114 let tree_conflict = self 115 .data 116 .root_tree 117 .try_map(|tree_id| self.store.get_tree(&RepoPath::root(), tree_id))?; 118 Ok(MergedTree::new(tree_conflict)) 119 } else { 120 let tree_id = self.data.root_tree.as_legacy_tree_id(); 121 let tree = self.store.get_tree(&RepoPath::root(), tree_id)?; 122 Ok(MergedTree::legacy(tree)) 123 } 124 } 125 126 pub fn tree_id(&self) -> &TreeId { 127 self.data.root_tree.as_legacy_tree_id() 128 } 129 130 pub fn change_id(&self) -> &ChangeId { 131 &self.data.change_id 132 } 133 134 pub fn store_commit(&self) -> &backend::Commit { 135 &self.data 136 } 137 138 pub fn description(&self) -> &str { 139 &self.data.description 140 } 141 142 pub fn author(&self) -> &Signature { 143 &self.data.author 144 } 145 146 pub fn committer(&self) -> &Signature { 147 &self.data.committer 148 } 149 150 /// A commit is discardable if it has one parent, no change from its 151 /// parent, and an empty description. 152 pub fn is_discardable(&self) -> bool { 153 if self.description().is_empty() { 154 if let [parent_commit] = &*self.parents() { 155 return self.tree_id() == parent_commit.tree_id(); 156 } 157 } 158 false 159 } 160}