Skip to content

Commit 40f096f

Browse files
committed
A first shot at producing stacks from a graph
1 parent 091661f commit 40f096f

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

crates/but-graph/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ pub use segment::{Commit, CommitDetails, CommitFlags, Segment, SegmentMetadata};
4343
mod api;
4444
/// Produce a graph from a Git repository.
4545
pub mod init;
46+
pub mod projection;
4647

4748
mod ref_metadata_legacy;
4849
pub use ref_metadata_legacy::{VirtualBranchesTomlMetadata, is_workspace_ref_name};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//! A way to represent the graph in a simplified (but more usable) form.
2+
//!
3+
//! This is the current default way of GitButler to perceive its world, but most inexpensively generated to stay
4+
//! close to the source of truth, [The Graph](crate::Graph).
5+
//!
6+
//! These types are not for direct consumption, but should be processed further for consumption by the user.
7+
8+
/// Types related to the stack representation for graphs.
9+
///
10+
/// Note that these are always a simplification, degenerating information, while maintaining a link back to the graph.
11+
mod stack;
12+
13+
use but_core::ref_metadata;
14+
pub use stack::{Stack, StackCommit, StackSegment};
15+
16+
/// A workspace is a list of [Stacks](Stack).
17+
#[derive(Debug, Clone)]
18+
pub struct Workspace {
19+
/// One or more stacks that live in the workspace.
20+
pub stacks: Vec<Stack>,
21+
/// Read-only workspace metadata with additional information, or `None` if nothing was present.
22+
pub metadata: Option<ref_metadata::Workspace>,
23+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use crate::{CommitFlags, SegmentIndex, SegmentMetadata};
2+
use bstr::BString;
3+
use but_core::ref_metadata;
4+
5+
/// A list of segments that together represent a list of dependent branches, stacked on top of each other.
6+
#[derive(Debug, Clone)]
7+
pub struct Stack {
8+
/// If there is an integration branch, we know a base commit shared with the integration branch from
9+
/// which we branched off.
10+
/// It is `None` if this is a stack derived from a branch without relation to any other branch.
11+
pub base: Option<gix::ObjectId>,
12+
/// The branch-name denoted segments of the stack from its tip to the point of reference, typically a merge-base.
13+
/// This array is never empty.
14+
pub segments: Vec<StackSegment>,
15+
}
16+
17+
/// A typically named set of linearized commits, obtained by first-parent-only traversal.
18+
///
19+
/// Note that this maybe an aggregation of multiple [graph segments](crate::Segment).
20+
#[derive(Debug, Clone)]
21+
pub struct StackSegment {
22+
/// The unambiguous or disambiguated name of the branch at the tip of the segment, i.e. at the first commit.
23+
///
24+
/// It is `None` if this branch is the top-most stack segment and the `ref_name` wasn't pointing to
25+
/// a commit anymore that was reached by our rev-walk.
26+
/// This can happen if the ref is deleted, or if it was advanced by other means.
27+
/// Alternatively, the naming could have been ambiguous while this is the first segment in the stack.
28+
/// named segment.
29+
pub ref_name: Option<gix::refs::FullName>,
30+
/// An ID which uniquely identifies the first [graph segment](crate::Segment) that is contained
31+
/// in this instance.
32+
/// Note that it's not suitable to permanently identify the segment, so should not be persisted.
33+
pub id: SegmentIndex,
34+
/// The name of the remote tracking branch of this segment, if present, i.e. `refs/remotes/origin/main`.
35+
/// Its presence means [`commits_unique_in_remote_tracking_branch`] are possibly available.
36+
pub remote_tracking_ref_name: Option<gix::refs::FullName>,
37+
/// The portion of commits that can be reached from the tip of the *branch* downwards to the next [StackSegment],
38+
/// so that they are unique for this stack segment and not included in any other stack or stack segment.
39+
///
40+
/// The list could be empty for when this is a dedicated empty segment as insertion position of commits.
41+
pub commits: Vec<StackCommit>,
42+
/// Commits that are reachable from the remote-tracking branch that is associated with this branch,
43+
/// but are not reachable from this branch or duplicated by a commit in it if comparing their hash-identity.
44+
///
45+
/// No further processing was done to deduplicate these.
46+
pub commits_unique_in_remote_tracking_branch: Vec<StackCommit>,
47+
/// Read-only branch metadata with additional information, or `None` if nothing was present.
48+
pub metadata: Option<ref_metadata::Branch>,
49+
}
50+
51+
/// A combination of [Commits](crate::Commit) and [CommitDetails](crate::CommitDetails).
52+
#[derive(Debug, Clone, Eq, PartialEq)]
53+
pub struct StackCommit {
54+
/// The hash of the commit.
55+
pub id: gix::ObjectId,
56+
/// The IDs of the parent commits, but may be empty if this is the first commit.
57+
pub parent_ids: Vec<gix::ObjectId>,
58+
/// Additional properties to help classify this commit.
59+
pub flags: CommitFlags,
60+
/// The references pointing to this commit, even after dereferencing tag objects.
61+
/// These can be names of tags and branches.
62+
pub refs: Vec<gix::refs::FullName>,
63+
/// The complete message, verbatim.
64+
pub message: BString,
65+
/// The signature at which the commit was authored.
66+
pub author: gix::actor::Signature,
67+
/// Whether the commit is in a conflicted state, a GitButler concept.
68+
/// GitButler will perform rebasing/reordering etc. without interruptions and flag commits as conflicted if needed.
69+
/// Conflicts are resolved via the Edit Mode mechanism.
70+
///
71+
/// Note that even though GitButler won't push branches with conflicts, the user can still push such branches at will.
72+
pub has_conflicts: bool,
73+
/// If `true`, the commit was pushed and is included in a [remote tracking branch](StackSegment::remote_tracking_ref_name).
74+
///
75+
/// These commits should be considered frozen and not be manipulated casually.
76+
pub is_reachable_by_remote: bool,
77+
}

0 commit comments

Comments
 (0)