Skip to content

Conversation

@ianhi
Copy link
Collaborator

@ianhi ianhi commented Dec 30, 2025

This required checking if a commit was anywhere in any branches history so I also had to update to storing a full commit history for each branch. I made a branchModel object to make it a bit nicer to do branch.head instead of grabbing the last item in a list.

I also added some more checks to the expiry that would have caught issues #1520 and #1534

This addresses most, but not all of @dcherian review comments from #1515 but I think this is a nice standalone change. I can work on deeper paramaterization of the model and spec separately if thats ok (ref #1515 (comment))

These tests currently fail due to #1534 and #1520

This is the first half of #1513

Comment on lines 654 to 655
# TODO: this should have failed earlier on the model step. the model to
# need to fix the model here as well
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure what this means

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

making sure people know this comment is by a human by making it incoherent :)

I think I mean that the incorrect branches should never be expired becuase that's all downstream of expiring the correct snapshots. The bug I was seeing was that we were overeager in expriing snapshots, which was then leading to overeager branch/tag expiration. This comment is overspecific to that bug. I'll remove it. Not really sure what I meant with the last sentence.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have removed this. I think i meant that I was surprised this wasn't catching the excessive expiration for v1 spec, delete_expired tags true case the model is not doing quite the right thing in these lines:

        expired_snaps = set()
        branch_pointees = set(self.branch_heads.values())
        tag_pointees = set(map(operator.attrgetter("commit_id"), self.tags.values()))
        for snap in self.commits.values():
            if (
                snap.written_at < older_than
                and snap.parent_id is not None
                and (delete_expired_tags or snap.id not in tag_pointees)
                and (
                    (delete_expired_branches and self.branch_heads["main"] != snap.id)
                    or snap.id not in branch_pointees
                )
            ):
                expired_snaps.add(snap.id)

but now im not 100% sure what the right expiration behavior is. If there is a branch that has the commit as it's head. should it not be expired?

of if there is a expired snapshot that is the head, but there is other history for that branch what should happen?

@ianhi
Copy link
Collaborator Author

ianhi commented Dec 30, 2025

I think this is ready now. I've temporarily had it skip the condition that causes expire_snapshots to fail which will be fixed by #1534 and #1520 neither of which I managed to get to today

has_tag = any(tag.commit_id == old_head for tag in self.tags.values())
# if none of the above then delete the commit
if not is_other_branch_head and not is_parent and not has_tag:
self.commits.pop(old_head)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this pop was wrong; amending keep the snapshot ID in the repo object file, so we shouldn't pop from commits.

def amend(self, snap: SnapshotInfo) -> None:
"""Amend the HEAD commit."""
# this is simpe because we aren't modeling the branch as a list of commits
self.commit(snap)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very simple now since we only model branch heads

self.commits[new_commit_id] = CommitModel.from_snapshot_and_store(
snap, copy.deepcopy(self.store)
)
self.commits[new_commit_id].parent_id = parent_id
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the error here is that we forgot to update self.ondisk_snaps I've chosen to just call self.commit to avoid such errors in the future.

assert actual.written_at == expected.written_at

@invariant()
def checks(self) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

making the output less verbose.

@dcherian dcherian requested a review from paraseba January 2, 2026 18:41
@paraseba paraseba merged commit 3b41d6b into main Jan 2, 2026
17 checks passed
@paraseba paraseba deleted the ian/stateful-add-amend branch January 2, 2026 19:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants