aboutsummaryrefslogtreecommitdiff
path: root/apps/servers/octopus/supergit/src/commit.rs
diff options
context:
space:
mode:
Diffstat (limited to 'apps/servers/octopus/supergit/src/commit.rs')
-rw-r--r--apps/servers/octopus/supergit/src/commit.rs40
1 files changed, 39 insertions, 1 deletions
diff --git a/apps/servers/octopus/supergit/src/commit.rs b/apps/servers/octopus/supergit/src/commit.rs
index bc7383d1ed6d..99c4dbba6fce 100644
--- a/apps/servers/octopus/supergit/src/commit.rs
+++ b/apps/servers/octopus/supergit/src/commit.rs
@@ -1,4 +1,4 @@
-use crate::{FileTree, HashId};
+use crate::{Diff, FileTree, HashId};
use git2::Repository;
use std::sync::Arc;
@@ -71,6 +71,44 @@ impl Commit {
FileTree::new(&self.repo, self.id.clone())
}
+ /// Get the list of paths in the repository touched by this commit
+ ///
+ /// Using this function directly is often not what you want.
+ /// Instead, use the `get_history(...)` function on `FileTree`,
+ /// which uses this function.
+ pub fn get_paths(&self) -> Vec<String> {
+ self.get_diff()
+ .map(|d| Diff::from(d))
+ .map_or(vec![], |d| d.get_paths())
+ }
+
+ /// Utility function to get a merged diff from all parents
+ fn get_diff(&self) -> Option<git2::Diff> {
+ // Get all diffs with parents
+ let stree = self.find().tree().unwrap();
+ let mut vec = self
+ .parents()
+ .into_iter()
+ .filter_map(|p| {
+ self.repo
+ .diff_tree_to_tree(Some(&stree), Some(p.find().tree().as_ref().unwrap()), None)
+ .ok()
+ })
+ .collect::<Vec<_>>();
+
+ // If there are no parents
+ if vec.len() == 0 {
+ vec = vec![self.repo.diff_tree_to_tree(Some(&stree), None, None).ok()?];
+ }
+
+ // Take the first and merge onto
+ let first = vec.remove(0);
+ Some(vec.iter().fold(first, |mut acc, diff| {
+ acc.merge(diff).unwrap();
+ acc
+ }))
+ }
+
fn find(&self) -> git2::Commit {
self.repo.find_commit(self.id.to_oid()).unwrap()
}