Skip to content

support av sync on checked out worktree branches#677

Merged
aviator-app[bot] merged 2 commits intomasterfrom
support_sync_in_worktrees
Apr 2, 2026
Merged

support av sync on checked out worktree branches#677
aviator-app[bot] merged 2 commits intomasterfrom
support_sync_in_worktrees

Conversation

@tulioz
Copy link
Copy Markdown
Contributor

@tulioz tulioz commented Mar 14, 2026

No description provided.

@tulioz tulioz requested a review from a team as a code owner March 14, 2026 00:59
@aviator-app
Copy link
Copy Markdown
Contributor

aviator-app bot commented Mar 14, 2026

Current Aviator status

Aviator will automatically update this comment as the status of the PR changes.
Comment /aviator refresh to force Aviator to re-examine your PR (or learn about other /aviator commands).

This PR was merged using Aviator.


See the real-time status of this PR on the Aviator webapp.
Use the Aviator Chrome Extension to see the status of your PR within GitHub.

@aviator-app
Copy link
Copy Markdown
Contributor

aviator-app bot commented Mar 14, 2026

✅ FlexReview Status

Common Owner: aviator-co/engineering (expert-load-balance assignment)
Owner and Assignment:

  • 🔒 aviator-co/engineering (expert-load-balance assignment)
    Owned Files
    • 🔒 internal/git/worktree.go
    • 🔒 internal/sequencer/sequencer.go
    • 🔒 internal/sequencer/sequencerui/ui.go

Review SLO: 7 business hours if PR size is <= 200 LOC for the first response.

@aviator-app aviator-app bot requested a review from davi-maciel March 14, 2026 00:59
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the av sync command by introducing robust support for Git worktrees. It ensures that branches checked out in worktrees are properly handled during synchronization operations. Before a rebase, the system will now detach the HEAD of relevant worktrees, and after the rebase, it will restore them to their original branch. Crucially, it also identifies and gracefully skips any worktrees with uncommitted changes, along with their dependent branches, providing clear communication to the user about which branches were skipped and why. This prevents data loss and provides a more predictable and user-friendly experience when working with av sync across multiple worktrees.

Highlights

  • Worktree Management Functions: Introduced new Git utility functions to programmatically detach HEAD, restore branches, and check for cleanliness in Git worktrees.
  • Sequencer Integration: The core sequencing logic now prepares worktrees before a rebase by detaching their HEADs and restores them afterward, ensuring a stable environment.
  • Dirty Worktree Handling: Implemented logic to detect dirty worktrees, skip them and their dependent branches from the sync operation, and provide user feedback.
  • User Interface Updates: The restack UI now displays messages related to worktree operations and clearly marks branches that were skipped due to dirty worktrees.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • .claude/worktrees/thirsty-kalam
    • Added a new file, likely for testing or internal tracking of a worktree.
  • internal/git/worktree.go
    • Imported os/exec and emperror.dev/errors.
    • Added DetachWorktreeHEAD to detach a worktree's HEAD.
    • Added RestoreWorktreeBranch to checkout a branch in a worktree.
    • Added IsWorktreeClean to check for unstaged changes.
  • internal/sequencer/sequencer.go
    • Added DetachedWorktrees and SkippedBranches maps to the Sequencer struct.
    • Modified Run to include checkNoUnstagedChanges and PrepareWorktrees.
    • Implemented PrepareWorktrees to manage worktree states.
    • Added skipDescendants to mark dependent branches as skipped.
    • Added removeSkippedOps to filter operations.
    • Added advancePastSkipped to update CurrentSyncRef.
    • Added RestoreWorktrees to restore branches in detached worktrees.
  • internal/sequencer/sequencerui/ui.go
    • Added worktreeMessages to RestackModel.
    • Updated Update to call RestoreWorktrees and append messages.
    • Modified View to display skipped branches with a warning and show worktree operation messages.
Activity
  • No human activity has been recorded for this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds support for av sync on branches that are checked out in separate Git worktrees. The implementation is robust, correctly identifying branches in worktrees, skipping those with uncommitted changes, and detaching the HEAD for clean ones before proceeding with the rebase. After the operation, it correctly restores the branches. The overall approach is solid. I've identified a high-severity issue regarding context propagation for cancellation handling, and a few medium-severity suggestions to enhance performance and code clarity in the new sequencer logic.

case *RestackProgress:
if msg.err == nil && msg.result == nil {
// Finished the sequence.
restoreMessages := vm.state.Seq.RestoreWorktrees(context.Background())
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Using context.Background() here (and on line 94, and in runSeq* methods) prevents proper cancellation of the git operations. If the user cancels the command (e.g., with Ctrl-C), the context passed from cobra will be canceled, but since a background context is used here, the underlying git commands will continue to run detached from the UI. This can lead to a confusing state for the user.

To fix this, you should propagate the context.Context from the cobra.Command down into the RestackModel. The model can then use this context when calling long-running operations like RestoreWorktrees and repo.CheckoutBranch. This will ensure that if the main process is cancelled, all child operations are cancelled as well.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Probably you should. But for now, you can use context.TODO()

return messages, nil
}

func (seq *Sequencer) skipDescendants(skippedSet map[string]bool) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The current implementation for finding descendant branches to skip is correct, but it could be inefficient for stacks with many branches. It repeatedly iterates over all operations in a loop until no more changes are detected, which can lead to a quadratic time complexity in the worst case (O(number of branches in stack ^ 2)).

A more performant approach would be to first build a parent-to-children map of the branch hierarchy. Then, you can perform a single graph traversal (like Breadth-First Search or Depth-First Search) starting from the initially skipped branches to find all their descendants. This would reduce the complexity to be linear in the number of branches and relationships, which is more scalable.

Comment on lines +378 to +384
var filtered []RestackOp
for _, op := range seq.Operations {
if seq.SkippedBranches[op.Name.Short()] == "" {
filtered = append(filtered, op)
}
}
seq.Operations = filtered
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This implementation for filtering the Operations slice allocates a new slice (filtered) and then copies the elements. For better performance and memory efficiency, you can filter the slice in-place. This is a common Go idiom that avoids unnecessary allocations by reusing the underlying array of the original slice.

Suggested change
var filtered []RestackOp
for _, op := range seq.Operations {
if seq.SkippedBranches[op.Name.Short()] == "" {
filtered = append(filtered, op)
}
}
seq.Operations = filtered
filtered := seq.Operations[:0]
for _, op := range seq.Operations {
if seq.SkippedBranches[op.Name.Short()] == "" {
filtered = append(filtered, op)
}
}
seq.Operations = filtered

seq.CurrentSyncRef = ""
}

func (seq *Sequencer) RestoreWorktrees(ctx context.Context) []string {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

This function has a side effect: it clears seq.DetachedWorktrees after restoring the branches. This mutation of the Sequencer state is not obvious from the function name RestoreWorktrees. This can make the code harder to understand and maintain.

To improve clarity, consider renaming the function to be more explicit about its side effects, for example, RestoreAndClearWorktrees. Alternatively, you could move the responsibility of clearing the map to the caller.

@tulioz tulioz force-pushed the support_sync_in_worktrees branch from 35e7908 to 7f38a38 Compare March 14, 2026 01:02
@davi-maciel davi-maciel requested review from jainankit and removed request for davi-maciel March 14, 2026 01:31
@jainankit jainankit requested a review from draftcode March 22, 2026 17:38
@tulioz tulioz force-pushed the support_sync_in_worktrees branch from 7f38a38 to c1fb68b Compare March 23, 2026 17:15
@tulioz tulioz force-pushed the support_sync_in_worktrees branch from c1fb68b to e4ba3ad Compare March 23, 2026 20:57
@aviator-app aviator-app bot merged commit 2cd64f8 into master Apr 2, 2026
4 checks passed
@aviator-app aviator-app bot deleted the support_sync_in_worktrees branch April 2, 2026 00:01
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.

2 participants