@@ -2,6 +2,7 @@ use crate::{CommitFlags, Graph, SegmentIndex, SegmentMetadata};
22use anyhow:: { Context , bail} ;
33use bitflags:: bitflags;
44use but_core:: ref_metadata;
5+ use gix:: reference:: Category ;
56use petgraph:: Direction ;
67use std:: fmt:: Formatter ;
78
@@ -80,9 +81,12 @@ pub struct StackSegment {
8081 ///
8182 /// The list could be empty for when this is a dedicated empty segment as insertion position of commits.
8283 pub commits : Vec < StackCommit > ,
83- /// Commits that are *only* reachable from the remote-tracking branch that is associated with this branch.
84+ /// Commits that are *only* reachable from the tip of the remote-tracking branch that is associated with this branch,
85+ /// down to the first (and possibly unrelated) non-remote commit.
8486 /// Note that these commits may not have an actual commit-graph connection to the local
8587 /// `commits` available above.
88+ /// Further, despite being in a simple list, their order is based on a simple topological walk, so
89+ /// this form doesn't imply a linear history.
8690 pub commits_on_remote : Vec < StackCommit > ,
8791 /// Read-only branch metadata with additional information, or `None` if nothing was present.
8892 pub metadata : Option < ref_metadata:: Branch > ,
@@ -127,6 +131,7 @@ impl StackSegment {
127131
128132 // TODO: copy the ReachableByMatchingRemote down to all segments from the first commit that has them,
129133 // as they are only detected (and set) on named commits, not their anonymous 'splits'.
134+ // Is this not sufficiently done below? I think so - needs test.
130135 let mut commits_by_segment = Vec :: new ( ) ;
131136 for s in segments {
132137 let mut stack_commits = Vec :: new ( ) ;
@@ -153,7 +158,12 @@ impl StackSegment {
153158
154159 let mut v = Vec :: new ( ) ;
155160 graph. visit_all_segments_until ( remote_sidx, Direction :: Outgoing , |s| {
156- let prune = !s. commits . iter ( ) . all ( |c| c. flags . is_remote ( ) ) ;
161+ let prune = !s. commits . iter ( ) . all ( |c| c. flags . is_remote ( ) )
162+ // Do not 'steal' commits from other known remote segments while they are officially connected.
163+ || ( s. id != remote_sidx
164+ && s. ref_name
165+ . as_ref ( )
166+ . is_some_and ( |orn| orn. category ( ) == Some ( Category :: RemoteBranch ) ) ) ;
157167 if prune {
158168 // See if this segment links to a commit we know as local, and mark it accordingly.
159169 // `s` may be in `segments`, let's find it and mark all its commits (and all that follow).
0 commit comments