temp for tree extraction
This commit is contained in:
139
internal/commands/switch.go
Normal file
139
internal/commands/switch.go
Normal file
@ -0,0 +1,139 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"git.dws.rip/DWS/onyx/internal/core"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// NewSwitchCmd creates the switch command
|
||||
func NewSwitchCmd() *cobra.Command {
|
||||
var force bool
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "switch <name>",
|
||||
Short: "Switch to a different workstream",
|
||||
Long: `Switch to a different workstream.
|
||||
|
||||
This command will:
|
||||
1. Check for uncommitted changes (unless --force is used)
|
||||
2. Load the target workstream
|
||||
3. Checkout the latest commit in the target workstream
|
||||
4. Update the current workstream pointer
|
||||
|
||||
⚠️ Warning: Switching discards uncommitted changes in your working directory.
|
||||
Use 'onx save' to commit your work before switching, or use --force to bypass the safety check.`,
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runSwitch(args[0], force)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&force, "force", "f", false, "Force switch even with uncommitted changes")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
// runSwitch executes the switch command
|
||||
func runSwitch(name string, force bool) error {
|
||||
// Get current directory
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get current directory: %w", err)
|
||||
}
|
||||
|
||||
// Check if this is an Onyx repository
|
||||
if !core.IsOnyxRepo(cwd) {
|
||||
return fmt.Errorf("not an Onyx repository")
|
||||
}
|
||||
|
||||
// Open the repository
|
||||
repo, err := core.Open(cwd)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open repository: %w", err)
|
||||
}
|
||||
defer repo.Close()
|
||||
|
||||
// Create workstream manager
|
||||
wsManager := core.NewWorkstreamManager(repo)
|
||||
|
||||
// Get current workstream name before switching
|
||||
currentName, err := wsManager.GetCurrentWorkstreamName()
|
||||
if err != nil {
|
||||
currentName = "none"
|
||||
}
|
||||
|
||||
// Check if we're already on the target workstream
|
||||
if currentName == name {
|
||||
fmt.Printf("Already on workstream '%s'\n", name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check for uncommitted changes unless force is enabled
|
||||
if !force {
|
||||
gitRepo := repo.GetGitRepo()
|
||||
worktree, err := gitRepo.Worktree()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get worktree: %w", err)
|
||||
}
|
||||
|
||||
status, err := worktree.Status()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check status: %w", err)
|
||||
}
|
||||
|
||||
if !status.IsClean() {
|
||||
// Show which files have changes
|
||||
fmt.Println("Error: You have uncommitted changes:")
|
||||
for file, fileStatus := range status {
|
||||
if fileStatus.Worktree != ' ' || fileStatus.Staging != ' ' {
|
||||
fmt.Printf(" %c%c %s\n", fileStatus.Staging, fileStatus.Worktree, file)
|
||||
}
|
||||
}
|
||||
fmt.Println("\nPlease commit your changes or use --force to discard them:")
|
||||
fmt.Printf(" onx save -m \"WIP\" # Save your work\n")
|
||||
fmt.Printf(" onx switch %s --force # Discard changes and switch\n", name)
|
||||
return fmt.Errorf("uncommitted changes present")
|
||||
}
|
||||
}
|
||||
|
||||
// Use ExecuteWithTransaction to capture state_before and state_after
|
||||
err = core.ExecuteWithTransaction(repo, "switch", fmt.Sprintf("Switched from '%s' to '%s'", currentName, name), func() error {
|
||||
return wsManager.SwitchWorkstream(name)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Get the workstream we just switched to
|
||||
targetWorkstream, err := wsManager.GetCurrentWorkstream()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get workstream after switch: %w", err)
|
||||
}
|
||||
|
||||
// Display success message
|
||||
fmt.Printf("Switched to workstream '%s'\n", name)
|
||||
|
||||
// Show workstream info
|
||||
commitCount := targetWorkstream.GetCommitCount()
|
||||
if commitCount == 0 {
|
||||
fmt.Printf("\nThis is a new workstream based on '%s' with no commits yet.\n", targetWorkstream.BaseBranch)
|
||||
fmt.Printf("Make changes and save them with 'onx save -m \"message\"'\n")
|
||||
} else {
|
||||
commitText := "commit"
|
||||
if commitCount != 1 {
|
||||
commitText = "commits"
|
||||
}
|
||||
fmt.Printf("\nThis workstream has %d %s.\n", commitCount, commitText)
|
||||
|
||||
// Show the latest commit
|
||||
if latestCommit, err := targetWorkstream.GetLatestCommit(); err == nil {
|
||||
fmt.Printf("Latest commit: %s\n", latestCommit.Message)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user