diff options
| author | Fuwn <[email protected]> | 2026-01-26 05:51:25 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-01-26 05:51:25 +0000 |
| commit | 58efa86227d91981f38b8b51d73b8716acd749d8 (patch) | |
| tree | ad986a1d85a81be6830bcb10392c7d6e5c8b773e | |
| parent | docs(README): Add example output screenshot (diff) | |
| download | mugi-58efa86227d91981f38b8b51d73b8716acd749d8.tar.xz mugi-58efa86227d91981f38b8b51d73b8716acd749d8.zip | |
feat: Add force push flag
| -rw-r--r-- | cmd/mugi/main.go | 2 | ||||
| -rw-r--r-- | internal/cli/cli.go | 20 | ||||
| -rw-r--r-- | internal/git/git.go | 11 | ||||
| -rw-r--r-- | internal/ui/ui.go | 10 |
4 files changed, 35 insertions, 8 deletions
diff --git a/cmd/mugi/main.go b/cmd/mugi/main.go index 6caed07..f1af065 100644 --- a/cmd/mugi/main.go +++ b/cmd/mugi/main.go @@ -46,5 +46,5 @@ func run() error { return fmt.Errorf("no matching repositories or remotes found") } - return ui.Run(cmd.Operation, tasks, cmd.Verbose) + return ui.Run(cmd.Operation, tasks, cmd.Verbose, cmd.Force) } diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 1ab54b2..1bee391 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -15,6 +15,7 @@ type Command struct { Remotes []string ConfigPath string Verbose bool + Force bool Help bool Version bool } @@ -34,6 +35,7 @@ func Parse(args []string) (Command, error) { args, cmd.ConfigPath = extractConfigFlag(args) args, cmd.Verbose = extractVerboseFlag(args) + args, cmd.Force = extractForceFlag(args) for _, arg := range args { if arg == "-h" || arg == "--help" || arg == "help" { @@ -100,6 +102,7 @@ Commands: Flags: -c, --config <path> Override config file path -V, --verbose Show detailed output + -f, --force Force push (use with caution) Examples: mugi pull Pull all repositories from all remotes @@ -174,3 +177,20 @@ func extractVerboseFlag(args []string) ([]string, bool) { return remaining, verbose } + +func extractForceFlag(args []string) ([]string, bool) { + var remaining []string + var force bool + + for _, arg := range args { + if arg == "-f" || arg == "--force" { + force = true + + continue + } + + remaining = append(remaining, arg) + } + + return remaining, force +} diff --git a/internal/git/git.go b/internal/git/git.go index 13e9cb2..2455977 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -41,13 +41,13 @@ func (r *Result) setError(err error) { } } -func Execute(ctx context.Context, op remote.Operation, repoPath, remoteName string) Result { +func Execute(ctx context.Context, op remote.Operation, repoPath, remoteName string, force bool) Result { result := Result{ Repo: repoPath, Remote: remoteName, } - args := buildArgs(op, remoteName, repoPath) + args := buildArgs(op, remoteName, repoPath, force) cmd := exec.CommandContext(ctx, "git", args...) cmd.Dir = repoPath cmd.Env = gitEnv() @@ -66,15 +66,20 @@ func Execute(ctx context.Context, op remote.Operation, repoPath, remoteName stri return result } -func buildArgs(op remote.Operation, remoteName, repoPath string) []string { +func buildArgs(op remote.Operation, remoteName, repoPath string, force bool) []string { switch op { case remote.Pull: branch := currentBranch(repoPath) if branch == "" { branch = "HEAD" } + return []string{"pull", remoteName, branch} case remote.Push: + if force { + return []string{"push", "--force", remoteName} + } + return []string{"push", remoteName} case remote.Fetch: return []string{"fetch", remoteName} diff --git a/internal/ui/ui.go b/internal/ui/ui.go index cee3442..e6e6ab2 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -44,10 +44,11 @@ type Model struct { spinner spinner.Model operation remote.Operation verbose bool + force bool done bool } -func NewModel(op remote.Operation, tasks []Task, verbose bool) Model { +func NewModel(op remote.Operation, tasks []Task, verbose, force bool) Model { s := spinner.New() s.Spinner = spinner.Dot s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205")) @@ -65,6 +66,7 @@ func NewModel(op remote.Operation, tasks []Task, verbose bool) Model { spinner: s, operation: op, verbose: verbose, + force: force, } } @@ -180,7 +182,7 @@ func (m *Model) runTask(task Task) tea.Cmd { op = m.operation } - result := git.Execute(context.Background(), op, task.RepoPath, task.RemoteName) + result := git.Execute(context.Background(), op, task.RepoPath, task.RemoteName, m.force) return taskResult{task: task, result: result} } @@ -226,7 +228,7 @@ func indentOutput(s string, style lipgloss.Style) string { return strings.Join(lines, "\n") } -func Run(op remote.Operation, tasks []Task, verbose bool) error { +func Run(op remote.Operation, tasks []Task, verbose, force bool) error { if op == remote.Pull { inits := NeedsInit(tasks) if len(inits) > 0 { @@ -242,7 +244,7 @@ func Run(op remote.Operation, tasks []Task, verbose bool) error { tasks = adjustPullTasks(tasks) } - model := NewModel(op, tasks, verbose) + model := NewModel(op, tasks, verbose, force) p := tea.NewProgram(model) _, err := p.Run() |