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

Conditionally sync the branches #369

Merged
merged 1 commit into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions cmd/av/stack_sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ import (
)

var stackSyncFlags struct {
All bool
Current bool
Abort bool
Continue bool
Skip bool
Push string
Prune string
All bool
RebaseToTrunk bool
Current bool
Abort bool
Continue bool
Skip bool
Push string
Prune string
}

const (
Expand Down Expand Up @@ -543,7 +544,7 @@ func (vm *stackSyncViewModel) createState() (*savedStackSyncState, error) {
if currentBranch != "" {
currentBranchRef = plumbing.NewBranchReferenceName(currentBranch)
}
ops, err := planner.PlanForSync(vm.db.ReadTx(), vm.repo, currentBranchRef, stackSyncFlags.All, stackSyncFlags.Current)
ops, err := planner.PlanForSync(vm.db.ReadTx(), vm.repo, currentBranchRef, stackSyncFlags.All, stackSyncFlags.Current, stackSyncFlags.RebaseToTrunk)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -581,6 +582,10 @@ func init() {
"delete branches that have been merged into the parent branch\n(ask|yes|no)",
)
stackSyncCmd.Flags().Lookup("prune").NoOptDefVal = "ask"
stackSyncCmd.Flags().BoolVar(
&stackSyncFlags.RebaseToTrunk, "rebase-to-trunk", false,
"rebase the branches to the latest trunk always",
)

stackSyncCmd.Flags().BoolVar(
&stackSyncFlags.Continue, "continue", false,
Expand Down
20 changes: 20 additions & 0 deletions docs/av-stack-sync.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@ resolve the conflict, and continue with `av stack sync --continue`. This is
similar to `git rebase --continue`, but it continues with syncing the rest of
the branches.

## REBASING THE STACK ROOT TO TRUNK

By default, the branches are conditionally rebased if needed:

* If a part of the stack is merged, the rest of the stack is rebased to the
latest trunk commit.
* If a branch is a stack root (the first topic branch next to trunk), it's
rebased if `--rebase-to-trunk` option is specified.
* If a branch is not a stack root, it's rebased to the parent branch.

While you are developing in a topic branch, it's possible that the trunk branch
is updated by somebody else. In some cases, you may need to rebase onto that
latest trunk branch to resolve the conflicts. For example, if somebody else
updates the same file you are working on, you need to rebase your branch onto
the latest trunk branch. In this case, you can use `--rebase-to-trunk` option to
rebase the stacks to the latest trunk branch.

## OPTIONS

`--all`
Expand All @@ -40,6 +57,9 @@ the branches.
: Only sync changes to the current branch. (Don't recurse into descendant
branches.)

`--rebase-to-trunk`
: Rebase the branches to trunk.

`--push=(yes|no|ask)`
: Push the changes to the remote. If `ask`, it prompts to you when push is
needed. Default is `ask`.
Expand Down
14 changes: 12 additions & 2 deletions internal/sequencer/planner/planner.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ func PlanForRestack(tx meta.ReadTx, repo *git.Repo, currentBranch plumbing.Refer
// Skip rebasing branches that have merge commits.
continue
}
if avbr.Parent.Trunk {
// Skip rebasing the stack roots.
continue
}
ret = append(ret, sequencer.RestackOp{
Name: br,
NewParent: plumbing.NewBranchReferenceName(avbr.Parent.Name),
Expand All @@ -38,7 +42,7 @@ func PlanForRestack(tx meta.ReadTx, repo *git.Repo, currentBranch plumbing.Refer
return ret, nil
}

func PlanForSync(tx meta.ReadTx, repo *git.Repo, currentBranch plumbing.ReferenceName, restackAll, restackCurrent bool) ([]sequencer.RestackOp, error) {
func PlanForSync(tx meta.ReadTx, repo *git.Repo, currentBranch plumbing.ReferenceName, restackAll, restackCurrent, restackStackRoots bool) ([]sequencer.RestackOp, error) {
var targetBranches []plumbing.ReferenceName
var err error
if restackAll {
Expand All @@ -59,7 +63,13 @@ func PlanForSync(tx meta.ReadTx, repo *git.Repo, currentBranch plumbing.Referenc
// Skip rebasing branches that have merge commits.
continue
}
if !avbr.Parent.Trunk {

if avbr.Parent.Trunk {
if !restackStackRoots {
// Skip rebasing the stack roots.
continue
}
} else {
// Check if the parent branch is merged.
avpbr, _ := tx.Branch(avbr.Parent.Name)
if avpbr.MergeCommit != "" {
Expand Down