mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-11 04:15:48 +02:00
Merge 9b9e12b4b9
into 223978eb82
This commit is contained in:
commit
d4583c5753
3 changed files with 105 additions and 4 deletions
|
@ -54,6 +54,62 @@ func (self *SubmoduleCommands) GetConfigs(parentModule *models.SubmoduleConfig)
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: unsure if this is the best way to go about this.
|
||||
// TODO: might be better to do a single `git submodule foreach git status` and parse the Output
|
||||
getSubmoduleHead := func(cmds *SubmoduleCommands, path string) (string, error) {
|
||||
// git -C </path/to/submodule> symbolic-ref -q HEAD
|
||||
// Output is empty in detached state
|
||||
// Output if on a branch: refs/heads/main
|
||||
cmdArgs := NewGitCmd("symbolic-ref").
|
||||
Dir(path).
|
||||
Arg("-q", "HEAD").
|
||||
ToArgv()
|
||||
|
||||
return cmds.cmd.New(cmdArgs).RunWithOutput()
|
||||
}
|
||||
|
||||
formatSubmoduleHead := func(head string, prefix string) string {
|
||||
// refs/heads/main ---> main
|
||||
if strings.HasPrefix(head, prefix) {
|
||||
return head[len(prefix) : len(head)-1]
|
||||
}
|
||||
return head
|
||||
}
|
||||
|
||||
getPorcelainStatus := func(cmds *SubmoduleCommands, path string) (int, int, int, error) {
|
||||
cmdArgs := NewGitCmd("status").
|
||||
Dir(path).
|
||||
Arg("--porcelain").
|
||||
ToArgv()
|
||||
|
||||
output, err := cmds.cmd.New(cmdArgs).RunWithOutput()
|
||||
if err != nil {
|
||||
return -1, -1, -1, err
|
||||
}
|
||||
lines := strings.Split(output, "\n")
|
||||
|
||||
stagedCount := 0
|
||||
unstagedCount := 0
|
||||
untrackedCount := 0
|
||||
|
||||
for _, line := range lines {
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
firstChar := line[0:1]
|
||||
switch firstChar {
|
||||
case " ":
|
||||
unstagedCount++
|
||||
case "?":
|
||||
untrackedCount++
|
||||
default:
|
||||
stagedCount++
|
||||
}
|
||||
|
||||
}
|
||||
return stagedCount, unstagedCount, untrackedCount, nil
|
||||
}
|
||||
|
||||
configs := []*models.SubmoduleConfig{}
|
||||
lastConfigIdx := -1
|
||||
for scanner.Scan() {
|
||||
|
@ -70,6 +126,17 @@ func (self *SubmoduleCommands) GetConfigs(parentModule *models.SubmoduleConfig)
|
|||
if lastConfigIdx != -1 {
|
||||
if path, ok := firstMatch(line, `\s*path\s*=\s*(.*)\s*`); ok {
|
||||
configs[lastConfigIdx].Path = path
|
||||
head, err := getSubmoduleHead(self, path)
|
||||
if err == nil {
|
||||
formattedHead := formatSubmoduleHead(head, "refs/heads/")
|
||||
configs[lastConfigIdx].Head = strings.TrimSpace(formattedHead)
|
||||
}
|
||||
stagedCount, unstagedCount, untrackedCount, err := getPorcelainStatus(self, path)
|
||||
if err == nil {
|
||||
configs[lastConfigIdx].NumStagedFiles = stagedCount
|
||||
configs[lastConfigIdx].NumUnstagedChanges = unstagedCount
|
||||
configs[lastConfigIdx].NumUntrackedChanges = untrackedCount
|
||||
}
|
||||
nestedConfigs, err := self.GetConfigs(configs[lastConfigIdx])
|
||||
if err == nil {
|
||||
configs = append(configs, nestedConfigs...)
|
||||
|
|
|
@ -3,9 +3,13 @@ package models
|
|||
import "path/filepath"
|
||||
|
||||
type SubmoduleConfig struct {
|
||||
Name string
|
||||
Path string
|
||||
Url string
|
||||
Name string
|
||||
Path string
|
||||
Url string
|
||||
Head string
|
||||
NumStagedFiles int
|
||||
NumUnstagedChanges int
|
||||
NumUntrackedChanges int
|
||||
|
||||
ParentModule *SubmoduleConfig // nil if top-level
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package presentation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/theme"
|
||||
"github.com/samber/lo"
|
||||
|
@ -13,7 +15,11 @@ func GetSubmoduleListDisplayStrings(submodules []*models.SubmoduleConfig) [][]st
|
|||
}
|
||||
|
||||
func getSubmoduleDisplayStrings(s *models.SubmoduleConfig) []string {
|
||||
name := s.Name
|
||||
// Pad right with some spaces to the end of the HEAD so that it (hopefully) aligns well.
|
||||
// Put the HEAD first because those are more likely to be similar lengths than the repo name.
|
||||
name := fmt.Sprintf("%-20s %s", s.Head,
|
||||
s.Name,
|
||||
)
|
||||
if s.ParentModule != nil {
|
||||
indentation := ""
|
||||
for p := s.ParentModule; p != nil; p = p.ParentModule {
|
||||
|
@ -23,5 +29,29 @@ func getSubmoduleDisplayStrings(s *models.SubmoduleConfig) []string {
|
|||
name = indentation + "- " + s.Name
|
||||
}
|
||||
|
||||
if s.NumStagedFiles != 0 {
|
||||
name = fmt.Sprintf(
|
||||
"%s +%d",
|
||||
name,
|
||||
s.NumStagedFiles,
|
||||
)
|
||||
}
|
||||
|
||||
if s.NumUnstagedChanges != 0 {
|
||||
name = fmt.Sprintf(
|
||||
"%s !%d",
|
||||
name,
|
||||
s.NumUnstagedChanges,
|
||||
)
|
||||
}
|
||||
|
||||
if s.NumUntrackedChanges != 0 {
|
||||
name = fmt.Sprintf(
|
||||
"%s ?%d ",
|
||||
name,
|
||||
s.NumUntrackedChanges,
|
||||
)
|
||||
}
|
||||
|
||||
return []string{theme.DefaultTextColor.Sprint(name)}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue