ok/jj
1
0
Fork 0
forked from mirrors/jj
jj/lib/src/commit.rs

149 lines
3.7 KiB
Rust

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use std::cmp::Ordering;
use std::fmt::{Debug, Error, Formatter};
use std::hash::{Hash, Hasher};
use std::sync::Arc;
use crate::repo_path::DirRepoPath;
use crate::store;
use crate::store::{ChangeId, CommitId, Signature};
use crate::store_wrapper::StoreWrapper;
use crate::tree::Tree;
#[derive(Clone)]
pub struct Commit {
store: Arc<StoreWrapper>,
id: CommitId,
data: Arc<store::Commit>,
}
impl Debug for Commit {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
f.debug_struct("Commit").field("id", &self.id).finish()
}
}
impl PartialEq for Commit {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl Eq for Commit {}
impl Ord for Commit {
fn cmp(&self, other: &Self) -> Ordering {
self.id.cmp(&other.id)
}
}
impl PartialOrd for Commit {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.id.cmp(&other.id))
}
}
impl Hash for Commit {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state)
}
}
impl Commit {
pub fn new(store: Arc<StoreWrapper>, id: CommitId, data: Arc<store::Commit>) -> Self {
Commit { store, id, data }
}
pub fn store(&self) -> &Arc<StoreWrapper> {
&self.store
}
pub fn id(&self) -> &CommitId {
&self.id
}
pub fn parent_ids(&self) -> Vec<CommitId> {
if self.data.parents.is_empty() && &self.id != self.store.root_commit_id() {
vec![self.store.root_commit_id().clone()]
} else {
self.data.parents.clone()
}
}
pub fn parents(&self) -> Vec<Commit> {
let mut parents = Vec::new();
for parent in &self.data.parents {
parents.push(self.store.get_commit(parent).unwrap());
}
if parents.is_empty() && &self.id != self.store.root_commit_id() {
parents.push(self.store.root_commit())
}
parents
}
pub fn predecessor_ids(&self) -> Vec<CommitId> {
self.data.predecessors.clone()
}
pub fn predecessors(&self) -> Vec<Commit> {
let mut predecessors = Vec::new();
for predecessor in &self.data.predecessors {
predecessors.push(self.store.get_commit(predecessor).unwrap());
}
predecessors
}
pub fn tree(&self) -> Tree {
self.store
.get_tree(&DirRepoPath::root(), &self.data.root_tree)
.unwrap()
}
pub fn change_id(&self) -> &ChangeId {
&self.data.change_id
}
pub fn store_commit(&self) -> &store::Commit {
&self.data
}
pub fn is_open(&self) -> bool {
self.data.is_open
}
pub fn is_pruned(&self) -> bool {
self.data.is_pruned
}
pub fn is_empty(&self) -> bool {
let parents = self.parents();
// TODO: Perhaps the root commit should also be considered empty.
parents.len() == 1 && parents[0].tree().id() == self.tree().id()
}
pub fn description(&self) -> &str {
&self.data.description
}
pub fn author(&self) -> &Signature {
&self.data.author
}
pub fn committer(&self) -> &Signature {
&self.data.committer
}
}