diff options
Diffstat (limited to 'apps/servers/octopus/supergit/src/branch.rs')
-rw-r--r-- | apps/servers/octopus/supergit/src/branch.rs | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/apps/servers/octopus/supergit/src/branch.rs b/apps/servers/octopus/supergit/src/branch.rs index dd92aea93cba..432227900247 100644 --- a/apps/servers/octopus/supergit/src/branch.rs +++ b/apps/servers/octopus/supergit/src/branch.rs @@ -4,7 +4,26 @@ use std::{mem, sync::Arc}; /// Abstraction for a branch history slice /// +/// Git implements an acyclical graph, where branches can be split, +/// and re-merge later. Traversal always happens from some point +/// onwards, backwards through the history. Because git repositories +/// can get quite large and this is a recursive process, it's very +/// quickly possible to overflow your program stack. To avoid this, +/// `supergit` uses an iterator design to enumerate commits. /// +/// Use the API on this type to specify your starting point. By +/// default, it will be the head of the branch you are looking at. +/// Note: not all branches have names! +/// +/// After creating a `BranchIter` you can then call `next()` on it, +/// yielding `BranchCommit` objects. These can either be single +/// commits, or various types of merge commits. Each merge commit +/// yields some set of `Branch` handles, that you can either traverse +/// by building another `BranchIter`. +/// +/// A branch iterator is therefore always first-parent, meaning that +/// merged branches can simply be ignored by only ever inspecting the +/// current `Commit` contained by a `BranchCommit`. #[derive(Clone)] pub struct Branch { repo: Arc<Repository>, @@ -56,6 +75,7 @@ impl Branch { } } + /// Create a branch iterator that stops when reaching a commit pub fn get_to(&self, commit: HashId) -> BranchIter { BranchIter::new( Arc::clone(&self.repo), @@ -64,12 +84,10 @@ impl Branch { ) } - /// Get the primary branch history as far back as it goes - pub fn get_all(&self) -> BranchIter { - BranchIter::new(Arc::clone(&self.repo), self.head.clone(), SegLimit::None) - } - - /// Get a branch segment of a certain length + /// Create a step-limited branch iterator + /// + /// This type of iterator is especially useful when combined with + /// `skip()`, to create a paginated view onto commits. pub fn get(&self, num: usize) -> BranchIter { BranchIter::new( Arc::clone(&self.repo), @@ -78,7 +96,17 @@ impl Branch { ) } - /// Get the commit pointed at by HEAD + /// Create an endless branch iterator + /// + /// While the creation of the iterator is instantanious, actually + /// enumerating all commits in a repository can be quite + /// computationally intensive and is almost never what you + /// actually want. + pub fn get_all(&self) -> BranchIter { + BranchIter::new(Arc::clone(&self.repo), self.head.clone(), SegLimit::None) + } + + /// Get the current HEAD commit pub fn get_head(&self) -> Commit { Commit::new(&self.repo, self.head.clone()).unwrap() } @@ -89,10 +117,12 @@ impl Branch { } } -/// A branch segment iterator +/// A branch slice iterator, created via `Branch` handle /// -/// Each iterator is first-parent, but will notify you about a split -/// parent by setting +/// This iterator yields `BranchCommit` objects, that can either be +/// simple commits, or various types of merge commits with new Branch +/// handles. This means that without explicitly branching, this +/// iterator is first-parent. pub struct BranchIter { repo: Arc<Repository>, curr: Option<HashId>, |