@@ -505,7 +505,7 @@ func (r *Repository) Affected(ctx context.Context, introStrs, fixedStrs, laStrs
505505 for _ , intro := range introduced {
506506 // BFS from intro
507507 queue := []SHA1 {intro }
508- terminateMap := maps . Clone ( fixedMap )
508+ unaffectableMap := make ( map [ SHA1 ] struct {} )
509509 affectedFromIntro := make (map [SHA1 ]struct {})
510510 visited := make (map [SHA1 ]struct {})
511511
@@ -518,25 +518,31 @@ func (r *Repository) Affected(ctx context.Context, introStrs, fixedStrs, laStrs
518518 }
519519 visited [curr ] = struct {}{}
520520
521- // When we hit a fixed commit (or its descendants), we aggressively map its
522- // entire downstream tree as terminated to satisfy the "any path blocked" rule.
523- if _ , ok := terminateMap [curr ]; ok {
524- // Inline DFS from current node to make all descendants unaffected / unaffectable
525- // 1. If a previous path added it to affected list, remove
526- // 2. Add to terminate set
521+ // Descendant of a fixed commit
522+ if _ , ok := unaffectableMap [curr ]; ok {
523+ continue
524+ }
525+
526+ // If we hit a fixed commit, its entire tree is treated as a unaffectable
527+ // as any downstream commit can go through this fixed commit to become unaffected
528+ if _ , ok := fixedMap [curr ]; ok {
529+ unaffectableMap [curr ] = struct {}{}
530+ // Inline DFS from current (fixed) node to make all descendants as unaffected / unaffectable
531+ // 1. If a previous path added the descendant to affected list, remove it
532+ // 2. Add to the unaffectable set to block future paths
527533 stack := []SHA1 {curr }
528534 for len (stack ) > 0 {
529535 unaffected := stack [len (stack )- 1 ]
530536 stack = stack [:len (stack )- 1 ]
531537
532- // Remove from affected list if a bypass path added it previously
538+ // Remove from affected list if it was reached via a previous non-fixed path.
533539 delete (affectedFromIntro , unaffected )
534540
535541 if children , ok := r .commitGraph [unaffected ]; ok {
536542 for _ , child := range children {
537- // If child is not already in the terminateSet, we want to traverse that path and mark descendants as unaffectable
538- if _ , ok := terminateMap [child ]; ! ok {
539- terminateMap [child ] = struct {}{}
543+ // Continue down the path if the child isn't already blocked.
544+ if _ , ok := unaffectableMap [child ]; ! ok {
545+ unaffectableMap [child ] = struct {}{}
540546 stack = append (stack , child )
541547 }
542548 }
@@ -546,7 +552,7 @@ func (r *Repository) Affected(ctx context.Context, introStrs, fixedStrs, laStrs
546552 continue
547553 }
548554
549- // If not in terminateSet , add to the intro-specific affected list and continue
555+ // Otherwise , add to the intro-specific affected list and continue
550556 affectedFromIntro [curr ] = struct {}{}
551557 if children , ok := r .commitGraph [curr ]; ok {
552558 queue = append (queue , children ... )
0 commit comments