D5: indexer_drop_pending counts a later pending merge as covering only when its commit has the pending merge's as an ancestor (issue 1966, ADR 0668 §6, ADR 0633 §5)
Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -1307,7 +1307,23 @@ func (ix *Indexer) DropPending(ctx context.Context, key, by, why string, abandon
|
||||
}
|
||||
e := entries[at]
|
||||
if !abandon {
|
||||
covered := slices.ContainsFunc(entries[at+1:], func(o PendingEntry) bool { return o.Forge.Repository == e.Forge.Repository })
|
||||
// Covered: a later merge of the same repository, pending or taken in, has this merge's commit as an ancestor (ADR
|
||||
// 0668 §6), asked of the forge (older); a later merge whose history does not hold it covers nothing.
|
||||
covered := false
|
||||
for _, o := range entries[at+1:] {
|
||||
if o.Forge.Repository != e.Forge.Repository {
|
||||
continue
|
||||
}
|
||||
in, err := ix.older(ctx, e.Forge.Repository, e.Forge.Merge, o.Forge.Merge)
|
||||
if err != nil {
|
||||
r.Answer = fmt.Sprintf("%s is not dropped: whether the later pending merge %s covers it is not read: %v", key, o.Key, err)
|
||||
return r
|
||||
}
|
||||
if in {
|
||||
covered = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !covered {
|
||||
taken, err := ix.takenAlready(ctx, forgemsg.GroupMerge{Repository: e.Forge.Repository, Number: e.Forge.Number, Merge: e.Forge.Merge})
|
||||
if err != nil {
|
||||
@@ -1317,7 +1333,7 @@ func (ix *Indexer) DropPending(ctx context.Context, key, by, why string, abandon
|
||||
covered = taken
|
||||
}
|
||||
if !covered {
|
||||
r.Answer = fmt.Sprintf("%s is not dropped: no later merge of %s is pending and its taken merge does not cover %s, so its "+
|
||||
r.Answer = fmt.Sprintf("%s is not dropped: no later merge of %s, pending or taken in, has %s as an ancestor, so its "+
|
||||
"changes would never be taken in (ADR 0633 §5); %s reads its message again, or abandon: true drops it all the same",
|
||||
key, e.Forge.Repository, e.Forge.Merge, TakeInPendingTool)
|
||||
return r
|
||||
|
||||
@@ -711,6 +711,17 @@ func TestTakeIn(t *testing.T) { // 1585/T3-T13 (ADR 0633)
|
||||
answer.Waits[0].Said != takein.TakeInPendingEvent || len(answer.Waits[0].Keys) != 2 {
|
||||
t.Fatalf("indexer_pending = %+v", answer)
|
||||
}
|
||||
// ADR 0668 §6: a later merge covers a pending one only when its commit has the pending merge's as an ancestor.
|
||||
history := "cd"
|
||||
b.ix.Contains = func(_ context.Context, _, commit, in string) (bool, error) {
|
||||
i, j := strings.IndexByte(history, commit[0]), strings.IndexByte(history, in[0])
|
||||
return i >= 0 && j >= 0 && i <= j, nil
|
||||
}
|
||||
history = "dc" // m.3's commit is not in m.2's later history (a history rewritten)
|
||||
if r := b.ix.DropPending(ctx, takein.PendingKey(2), "lead@shanks", "replaced by m.3", false); r.Stored || !strings.Contains(r.Answer, "as an ancestor") {
|
||||
t.Fatalf("a drop a later merge not holding it would cover: %+v", r)
|
||||
}
|
||||
history = "cd"
|
||||
b.said = nil
|
||||
if r := b.ix.DropPending(ctx, takein.PendingKey(2), "lead@shanks", "replaced by m.3", false); !r.Stored {
|
||||
t.Fatalf("drop: %+v", r)
|
||||
|
||||
Reference in New Issue
Block a user