Skip to content

Commit

Permalink
Merge pull request #1895 from rsteube/git-fix-reset
Browse files Browse the repository at this point in the history
git: fix reset
  • Loading branch information
rsteube authored Oct 9, 2023
2 parents 5f62012 + bea8d94 commit 111d153
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 6 deletions.
44 changes: 40 additions & 4 deletions completers/git_completer/cmd/reset.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cmd

import (
"strings"

"github.com/rsteube/carapace"
"github.com/rsteube/carapace-bin/pkg/actions/tools/git"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -31,20 +33,54 @@ func init() {

resetCmd.Flag("recurse-submodules").NoOptDefVal = " "

modeFlags := []string{"soft", "mixed", "hard", "merge", "keep"}
resetCmd.MarkFlagsMutuallyExclusive(
append(modeFlags, "patch")..., // TODO verify - either one of the "modes" above or patch allowed
)

carapace.Gen(resetCmd).FlagCompletion(carapace.ActionMap{
"pathspec-from-file": carapace.ActionFiles(),
})

carapace.Gen(resetCmd).PositionalCompletion(
git.ActionRefs(git.RefOption{}.Default()),
carapace.ActionCallback(func(c carapace.Context) carapace.Action {
if strings.HasPrefix(c.Value, ".") {
for _, name := range modeFlags {
if f := resetCmd.Flag(name); f != nil && f.Changed {
return carapace.ActionValues() // complete only commits for these flags
}
}
return git.ActionRefDiffs()
}
return git.ActionRefs(git.RefOption{}.Default())
}),
)

carapace.Gen(resetCmd).PositionalAnyCompletion(
carapace.ActionCallback(func(c carapace.Context) carapace.Action {
if resetCmd.Flags().ArgsLenAtDash() != -1 {
return carapace.ActionFiles()
toFilter := make([]string, 0)
for _, arg := range c.Args {
// TODO directories? globs possible? should work for most cases though
switch {
case !strings.HasPrefix(c.Value, "."):
toFilter = append(toFilter, strings.TrimPrefix(arg, "./"))
case !strings.HasPrefix(arg, "."):
toFilter = append(toFilter, "./"+arg)
default:
toFilter = append(toFilter, arg)
}
}

switch {
case strings.HasPrefix(c.Args[0], "."):
return git.ActionRefDiffs().Filter(toFilter...)
default:
return git.ActionRefDiffs(c.Args[0]).Filter(toFilter[1:]...)
}
return carapace.ActionValues()
}),
)

carapace.Gen(resetCmd).DashAnyCompletion(
carapace.ActionPositional(resetCmd),
)
}
2 changes: 1 addition & 1 deletion pkg/actions/tools/git/change.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func ActionChanges(opts ChangeOpts) carapace.Action {
})
}

// ActionRefChanges completes changes compared to given ref
// ActionRefChanges completes changes made in given ref
//
// go.mod
// cmd/carapace/main.go
Expand Down
62 changes: 61 additions & 1 deletion pkg/actions/tools/git/diff.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package git

import "github.com/rsteube/carapace"
import (
"path/filepath"
"strings"

"github.com/rsteube/carapace"
"github.com/rsteube/carapace/pkg/style"
)

// ActionDiffAlgorithms completes diff algorithms
//
Expand Down Expand Up @@ -102,3 +108,57 @@ func ActionDiffTools() carapace.Action {
"xxdiff",
)
}

// ActionRefDiffs completes changes beetween refs
// Accepts up to two refs
// 0: compare current workspace to HEAD
// 1: compare current workspace to given ref
// 2: compare first ref to second ref
func ActionRefDiffs(refs ...string) carapace.Action {
return carapace.ActionCallback(func(c carapace.Context) carapace.Action {
args := []string{"diff", "--name-status"}
switch len(refs) {
case 0:
args = append(args, "HEAD")
case 1:
args = append(args, refs[0])
case 2:
args = append(args, refs[0], refs[1])
default:
return carapace.ActionMessage("only up to two refs allowed [ActionRefDiffs]")
}

return carapace.ActionExecCommand("git", args...)(func(output []byte) carapace.Action {
lines := strings.Split(string(output), "\n")

root, err := rootDir(c)
if err != nil {
return carapace.ActionMessage(err.Error())
}

vals := make([]string, 0)
for _, line := range lines {
splitted := strings.Split(line, "\t")
if len(splitted) < 2 {
continue
}

relativePath, err := filepath.Rel(c.Dir, root+"/"+splitted[1])
if err != nil {
return carapace.ActionMessage(err.Error())
}

switch {
case strings.HasPrefix(relativePath, "../"):
vals = append(vals, relativePath, splitted[0])
case strings.HasPrefix(c.Value, "."):
vals = append(vals, "./"+relativePath, splitted[0])
default:
vals = append(vals, relativePath, splitted[0])
}

}
return carapace.ActionValuesDescribed(vals...).StyleF(style.ForPathExt)
})
})
}

0 comments on commit 111d153

Please sign in to comment.