abhinav / git-spice

Manage stacked Git branches
https://abhinav.github.io/git-spice/
GNU General Public License v3.0
220 stars 11 forks source link

Idea: Local Merge Queue #65

Open abhinav opened 4 months ago

abhinav commented 4 months ago

For repositories that use Merge for PRs, merging a stack of PRs is very easy. Given a stack main -> feature1 -> feature2, you can merge feature1, and then feature2. No additional work is needed.

For repositories that use Squash or Rebase for PRs, the workflow is: merge feature1, then rebase feature2 on new main, push, wait for CI, press merge again. This is annoying.

It's worth exploring a merge command that acts as a local merge queue: it merges the bottom-most PR, waits for the merge (e.g. if a GitHub Merge Queue is in use), rebases the next PR, pushes, merges, and so on.

Obviously, it stops as soon as the build fails (maybe with a build retry option for known flaky builds), or if there's a conflict rebasing, but otherwise it would be useful. e.g. hypothetically,

> gs downstack merge
Merging feature1 (#42)
Waiting for Merge Queue...
Rebasing feature2 (#43)
Waiting for builds...
Merging feature2 (#43)
Waiting for Merge Queue...
All PRs merged!
matthiasr commented 2 months ago

If feasible, it would be ideal if this could run in the background without depending on the local workspace state. That way, I could set a stack to merge, while continuing to work on other things (either on top of or in parallel to this stack).

jarviliam commented 2 months ago

Running in the background would be ideal but it may need to run in the foreground to report errors when it's unable to merge due to failing pr checks/conditions. Having a flag that controls if the merge queue is background tasked or not seems to be a good idea 👍

matthiasr commented 2 months ago

I don't need it to run in the background, I would open another terminal for parallel work, as long as that doesn't mess up the merge process.

abhinav commented 2 months ago

Let me prefix this by saying that this feature is currently in just-an-idea phase, so implementation details are super undecided.

The way I imagined this working, it would need access to a working copy of the repository so that it could restack upstack branches after the bottom-most PR merged. So it would need to hold onto the working tree while it's waiting to merge everything. However, it doesn't have to take over the working tree that you're working inside. We would be able to use the git-worktree command to get a secondary tree. So depending on how the implementation looked, the command could either always create a temporary working tree for rebasing or make it opt-in/opt-out with a flag[^1].

[^1]: Populating a new working tree can take long for really really large monorepos.

matthiasr commented 2 months ago

With #94 would a checkout still be needed? I've never used git replay but it seems like a good match here, and in case of conflicts you'd probably need to stop and tell the user anyway.

abhinav commented 2 months ago

Yeah, that's correct. If #94 is implemented, and the system has a recent enough version of Git, we would not need a worktree. Although the rebase-based workflow would still be something to do as a fallback when git isn't recent enough.

gedw99 commented 1 month ago

This is interesting for my use case .

I have 1,000 of gir reps , and need to automate pushing and pulling them remotely via NATS Jetstream whilst the user is also using the repo.

this allows git to be used as a real time collaboration tool. Any FS change is expressed immediately in the GUI the Scientists use