Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

git move: Add --exact option (closes #176) #450

Merged
merged 5 commits into from
Jul 19, 2022

Conversation

claytonrcarter
Copy link
Collaborator

@claytonrcarter claytonrcarter commented Jul 7, 2022

[reopening #448]

Still a WIP, but seems to be working. I've rebased my work onto #447 (which is also WIP) and I'll update this as that PR develops. I'll probably add some more tests, too, as I wrote all of these w/ a pre-revset mindset, so I was only thinking about moving single ranges/commits.

@claytonrcarter claytonrcarter force-pushed the move-range-exact branch 4 times, most recently from 4365291 to e2f71d7 Compare July 12, 2022 02:05
@claytonrcarter
Copy link
Collaborator Author

🤔 I could've sworn I commented on this already, but it looks like I forgot to press the big green submit button.

This is still WIP, and the code is full of untold horrors that I need to go back through and rethink/clean up (and remove my local working commits, like adding roots() to revsets, etc), but I think it's implementing the gist of what you asked about in #448 (comment)

It's been a long time since I've seriously thought about big O notation, so I'm hesitant to make any guesses about my get_connected_components implementations, but I have 2 of them just for fun. I think the second one is more efficient, and may operate in O(n), but if you factor in all of the DAG queries then it becomes O(over my head). 😄 Any comments you have on these would be great; thank you. (I figure we'd just keep 1, but I put in 2 in case 1 was more correct or performant or something.)

Working on this w/ connected components vs my previous approach (that only considered semi-linear "ranges") turned up a bunch of interesting edge cases, many of them involving merge commits. I've tried to document some or all of them in tests, and they may need further attention as this PR solidifies.

There are a few more edge cases that I need to code for (eg moving and inserting multiple components with various "non-stick" structures) but at this point I think I need to just dogfood it for a while to see how it feels and works, updating this as I do.

Thank you!

Copy link
Owner

@arxanas arxanas left a comment

Choose a reason for hiding this comment

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

Impressive work!

git-branchless-lib/src/core/dag.rs Outdated Show resolved Hide resolved
git-branchless-lib/src/core/dag.rs Outdated Show resolved Hide resolved
git-branchless-lib/src/core/dag.rs Outdated Show resolved Hide resolved
git-branchless/src/commands/move.rs Outdated Show resolved Hide resolved
git-branchless/src/commands/move.rs Outdated Show resolved Hide resolved
git-branchless/tests/command/test_move.rs Outdated Show resolved Hide resolved
git-branchless/tests/command/test_move.rs Show resolved Hide resolved
git-branchless/tests/command/test_move.rs Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
CHANGELOG.md Outdated Show resolved Hide resolved
@claytonrcarter claytonrcarter force-pushed the move-range-exact branch 2 times, most recently from 9982b28 to d590b6a Compare July 15, 2022 03:51
@claytonrcarter
Copy link
Collaborator Author

Sorry for the false start and all of the WIP artifacts you had to wade through on this. I still consider this WIP pending some more dogfooding and proofreading, but I think I've addressed all of your initial comments.

This has been a joy to use locally, but I have mostly been moving single commits. I haven't found myself moving multiple commits, ranges or "range trees" yet. I mean ... the tests say that it works, but I'll be interested in feedback on what happens IRL. 😄

@arxanas
Copy link
Owner

arxanas commented Jul 18, 2022

I've been using this for a bit and I haven't noticed any issues so far. What do you say we merge it and fix any issues in follow-up commits?

I think the second one is more efficient, and may operate in O(n)

I never answered this. I think both implementations are O(n^2) because you have one loop over the commits and a nested loop over the existing components to merge any intersecting components. You can do better with a data structure which can merge intersecting components efficiently (disjoint set), but otherwise I think you're likely to have O(n^2) complexity. Mostly we're hoping that we won't have to compute connected components for a large number of commits. If that happens, we can update it to use a better data structure in the future.

This avoids a cycle error, and provides a convenient way to restack other
sibling stacks onto the current stack via (for example)
`git move -I -b @ -d 'parents(stack()) - stack()'`
@claytonrcarter claytonrcarter changed the title git move: Add --range and --exact options (closes #176) git move: Add --exact option (closes #176) Jul 19, 2022
@claytonrcarter claytonrcarter marked this pull request as ready for review July 19, 2022 01:27
@claytonrcarter
Copy link
Collaborator Author

Thanks for the nudge. I've read through this again, pushed some clean up and I think it's good enough for now. A couple of notes on what I just pushed:

  • Mostly formatting and comments.
  • Moved some error checking earlier in the process (checking for 1 parent/component is now consistent w/ checking for 1 root and 1 head).
  • I've added a test for moving non-connected components, such as D&F in the following example.
    I'm still 😬 about merging my own code, but since you've signed off on this already, and what I pushed are just minor fixes, I've set it to rebase/merge when CI finishes. Thank you!

One thing that sticks out at me that I'd like to fix in a follow up is that I think the restriction to "only move components with 1 head" is lazy. I don't see any reason we can't move --exact the pink commits in something like this:

graph RL
D --> C --> B --> A
F --> E --> B

classDef pink fill:#f9f;
class B,C,E pink;
Loading

I think that restriction predates the component approach and will be straightforward to support. I'll see what I can do. *cracks knuckles*

@claytonrcarter claytonrcarter merged commit f893e54 into arxanas:master Jul 19, 2022
@claytonrcarter claytonrcarter deleted the move-range-exact branch July 19, 2022 11:13
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.

None yet

2 participants