Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
There was a problem hiding this comment.
Pull request overview
Adds a deterministic commit-ordering utility to but-workspace that sorts selected commits parent-first (topological order) and uses workspace traversal order as the tie-breaker for unrelated commits—intended to support multi-commit in-memory graph mutations with fewer conflicts.
Changes:
- Introduce
but_workspace::ordering::order_commit_selectors_by_parentage(neworderingmodule). - Add integration tests covering linear chains, disjoint commits, mixed ancestry, deduplication, and singleton behavior.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/but-workspace/src/lib.rs | Exposes the new ordering module from the crate root. |
| crates/but-workspace/src/ordering/mod.rs | Defines the ordering module and re-exports the ordering function. |
| crates/but-workspace/src/ordering/commit_parentage.rs | Implements parentage-based ordering with workspace-order tie-breaks. |
| crates/but-workspace/tests/workspace/main.rs | Registers the new ordering test module. |
| crates/but-workspace/tests/workspace/ordering/mod.rs | Wires up commit-parentage ordering tests. |
| crates/but-workspace/tests/workspace/ordering/commit_parentage.rs | Adds test coverage for the ordering behavior and invariants. |
4c46bce to
e916590
Compare
e916590 to
b91d1b3
Compare
b91d1b3 to
9aa529c
Compare
| } | ||
| } | ||
|
|
||
| let merge_base = match editor.repo().merge_base(left.id, right.id) { |
There was a problem hiding this comment.
Something I’ve been thinking about in some of my graph overlay work is how to reconcile the fact that a pick statement’s OIDs may not imply the same history as the commit graph. For example, with editor.insert_below(target, pick, below), the target will still have the same OID, but the editor graph itself has changed relative to what git would be telling you.
In most cases, that divergence should be fine. However, if more drastic operations are being performed, such as reparenting commits, it could lead to unexpected issues.
In https://github.com/gitbutlerapp/gitbutler/pull/13080, I’ve actually removed public access to the workspace property from the editor, because it always reflects the version of the workspace at the time the editor was created and therefore isn’t representative of the current graph state.
I’ve also modified the functions that were using it so that they call .rebase() and retrieve the latest overlay graph from SuccessfulRebase. That means that when we call into_editor again, we can work with the most up-to-date graph, aligned with the editor’s current state.
I’d love @Byron’s thoughts on this, but I’ve been wondering more and more whether it would be helpful to have some graph-inspection operations that run specifically on the editor’s step graph, so we can find things like merge bases there as well.
It would mean an additional implementation of logic similar to what already exists in but_graph, but it would also let us operate without the same desync concerns.
Perhaps I’m missing some context here, though. Do let me know.
There was a problem hiding this comment.
I’d love @Byron’s thoughts on this, but I’ve been wondering more and more whether it would be helpful to have some graph-inspection operations that run specifically on the editor’s step graph, so we can find things like merge bases there as well.
It would mean an additional implementation of logic similar to what already exists in but_graph, but it would also let us operate without the same desync concerns.
@Caleb-T-Owens That's an interesting problem. The 'safest' way seems to be to provide workspace() or graph() so that the editor can ensure the graph is representing the latest edits. While its more expensive, I do fear de-sync a bit, but ultimately would also trust that it's probably fine. The but-graph version of the merge-base implementation is generated based on the implementation in gix, which was hand-implemented based on Git :D.
However, my preference right now is to do the super-simple and explicit thing that makes the data structure clear, i.e. editor.workspace().graph.merge_base…(). @estib-vega I'd also think that a method could be added that returns CommitIDs instead of SegmentIDs.
Byron
left a comment
There was a problem hiding this comment.
I only looked at it from an organizational perspective and think changes have to be made.
My second feeling is that but-rebase should probably have more native support for at least parts of what needs to be accomplished here, but it's nothing more than that (a feeling) either.
There was a problem hiding this comment.
There is actually a way to use this file as documentation for the Rust module itself by inclusion, tower does that a lot. That's definitely something I'd use to not have a loose file lying around in the source tree.
| pub mod ui; | ||
|
|
||
| /// Utilities for deterministic ordering operations. | ||
| pub mod ordering; |
There was a problem hiding this comment.
I'd definitely prefer this module to be in commit as it's about commit ordering.
There was a problem hiding this comment.
Hmmm maybe. The motivation is that this will be used by branch & by commits, and any API that should be able to take multiple commits as input parameters.
There was a problem hiding this comment.
If we later need branch ordering (e.g. for moving multiple branches at a time) we could add that method there. Even if we're ordering commits behind the scenes
There was a problem hiding this comment.
Ah, I see, maybe it's more about branches then? It's just that when I see but_workspace::ordering, I think of the ordering of workspaces. Is there any place that is more specific but still fitting?
There was a problem hiding this comment.
This could be maybe also part of but-graph? Maybe we let the graph sort things since it should have all the information there. Merge bases and topology information.
There was a problem hiding this comment.
If you think that would work, I am all for it. My question would be if it's better in the step-graph though as it is related to mutation, and it's technically a different graph which may (or may not) be better suited for this kind of thing.
In any case, it seems like this can move elsewhere then 🎉.
| pub(crate) fn find_commit_segment_index( | ||
| workspace: &Workspace, | ||
| commit_id: gix::ObjectId, | ||
| ) -> Option<SegmentIndex> { |
There was a problem hiding this comment.
This should certainly be in but-graph, given that it provides a way to find the actual segment owning a commit by ObjectId in a workspace. This is quite under-used right now, so a simple way to do this is missing.
There was a problem hiding this comment.
Yep, that's true
Create but-workspace commit ordering function that sorts the commits by their parentage, according to the workspace appearance.
9aa529c to
07e88ef
Compare
|
Update:
Addressed other feedback as well regarding the docs and where the |
Create but-workspace commit ordering function that sorts the commits by
their parentage, according to the workspace appearance.
Cool, but why?
In order to enable graph mutations with multiple commits, I need to sort the commits from parent-most to child-most.
That way I can do one operation at a time in memory, parent to child. And then materialize it at the very end.
Ordering should reduce the probability of running into conflicts.
Disclaimer
This heavily uses AI for the generation of this algorithm
Comprehensive docs
https://github.com/gitbutlerapp/gitbutler/pull/13153/changes#diff-bb49765eeedd900a433bba2fc60faf0d82730392d9053af079c8c1d2407aa905