feat(git): enable posh-git from the git segment config

BREAKING CHANGE: To use the posh-git module output, you must now set the
`source` property to `pwsh` in the git segment configuration.

In case you are using the default configuration,
you don't need to change anything.
This commit is contained in:
Jan De Dobbeleer 2024-07-26 07:17:18 +02:00 committed by Jan De Dobbeleer
parent 15ab7783b7
commit 7081cac3a2
5 changed files with 51 additions and 32 deletions

View file

@ -124,6 +124,13 @@ func (cfg *Config) Features() shell.Features {
feats = append(feats, shell.Azure) feats = append(feats, shell.Azure)
} }
} }
if segment.Type == GIT {
source := segment.Properties.GetString(segments.Source, segments.Cli)
if source == segments.Pwsh {
feats = append(feats, shell.PoshGit)
}
}
} }
} }

View file

@ -179,7 +179,8 @@ func (g *Git) Enabled() bool {
return true return true
} }
if g.hasPoshGitStatus() { source := g.props.GetString(Source, Cli)
if source == Pwsh && g.hasPoshGitStatus() {
return true return true
} }

View file

@ -36,6 +36,7 @@ func (s *GitStatus) parsePoshGitStatus(p *poshGitStatus) {
if p == nil { if p == nil {
return return
} }
s.Added = len(p.Added) s.Added = len(p.Added)
s.Deleted = len(p.Deleted) s.Deleted = len(p.Deleted)
s.Modified = len(p.Modified) s.Modified = len(p.Modified)
@ -45,13 +46,17 @@ func (s *GitStatus) parsePoshGitStatus(p *poshGitStatus) {
func (g *Git) hasPoshGitStatus() bool { func (g *Git) hasPoshGitStatus() bool {
envStatus := g.env.Getenv(poshGitEnv) envStatus := g.env.Getenv(poshGitEnv)
if len(envStatus) == 0 { if len(envStatus) == 0 {
g.env.Error(fmt.Errorf("%s environment variable not set, do you have the posh-git module installed?", poshGitEnv))
return false return false
} }
var posh poshGit var posh poshGit
err := json.Unmarshal([]byte(envStatus), &posh) err := json.Unmarshal([]byte(envStatus), &posh)
if err != nil { if err != nil {
g.env.Error(err)
return false return false
} }
g.setDir(posh.GitDir) g.setDir(posh.GitDir)
g.Working = &GitStatus{} g.Working = &GitStatus{}
g.Working.parsePoshGitStatus(posh.Working) g.Working.parsePoshGitStatus(posh.Working)
@ -63,10 +68,13 @@ func (g *Git) hasPoshGitStatus() bool {
g.Behind = posh.BehindBy g.Behind = posh.BehindBy
g.UpstreamGone = len(posh.Upstream) == 0 g.UpstreamGone = len(posh.Upstream) == 0
g.Upstream = posh.Upstream g.Upstream = posh.Upstream
g.setBranchStatus() g.setBranchStatus()
if len(g.Upstream) != 0 && g.props.GetBool(FetchUpstreamIcon, false) { if len(g.Upstream) != 0 && g.props.GetBool(FetchUpstreamIcon, false) {
g.UpstreamIcon = g.getUpstreamIcon() g.UpstreamIcon = g.getUpstreamIcon()
} }
g.poshgit = true g.poshgit = true
return true return true
} }

View file

@ -8,6 +8,7 @@ import (
"github.com/jandedobbeleer/oh-my-posh/src/runtime/mock" "github.com/jandedobbeleer/oh-my-posh/src/runtime/mock"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
testify_ "github.com/stretchr/testify/mock"
) )
func TestPoshGitSegment(t *testing.T) { func TestPoshGitSegment(t *testing.T) {
@ -186,8 +187,10 @@ func TestPoshGitSegment(t *testing.T) {
env.On("Getenv", poshGitEnv).Return(tc.PoshGitJSON) env.On("Getenv", poshGitEnv).Return(tc.PoshGitJSON)
env.On("Home").Return("/Users/bill") env.On("Home").Return("/Users/bill")
env.On("GOOS").Return(runtime.LINUX) env.On("GOOS").Return(runtime.LINUX)
env.On("Error", testify_.Anything)
env.On("RunCommand", "git", []string{"-C", "", "--no-optional-locks", "-c", "core.quotepath=false", env.On("RunCommand", "git", []string{"-C", "", "--no-optional-locks", "-c", "core.quotepath=false",
"-c", "color.status=false", "remote", "get-url", "origin"}).Return("github.com/cli", nil) "-c", "color.status=false", "remote", "get-url", "origin"}).Return("github.com/cli", nil)
g := &Git{ g := &Git{
scm: scm{ scm: scm{
env: env, env: env,
@ -197,9 +200,11 @@ func TestPoshGitSegment(t *testing.T) {
command: GITCOMMAND, command: GITCOMMAND,
}, },
} }
if len(tc.Template) == 0 { if len(tc.Template) == 0 {
tc.Template = g.Template() tc.Template = g.Template()
} }
assert.Equal(t, tc.ExpectedEnabled, g.hasPoshGitStatus(), tc.Case) assert.Equal(t, tc.ExpectedEnabled, g.hasPoshGitStatus(), tc.Case)
if tc.ExpectedEnabled { if tc.ExpectedEnabled {
assert.Equal(t, tc.ExpectedString, renderTemplate(env, tc.Template, g), tc.Case) assert.Equal(t, tc.ExpectedString, renderTemplate(env, tc.Template, g), tc.Case)

View file

@ -10,12 +10,8 @@ Display git information when in a git repository. Also works for subfolders. For
make sure your `git` executable is up-to-date (when branch or status information is incorrect for example). make sure your `git` executable is up-to-date (when branch or status information is incorrect for example).
:::tip :::tip
PowerShell offers support for the [posh-git][poshgit] module for autocompletion, but it is disabled by default. If you want to display the default [posh-git][poshgit] output, **do not** use this segment
To enable this, set `$env:POSH_GIT_ENABLED = $true` in your `$PROFILE` after initializing Oh My Posh. but add the following snippet after initializing Oh My Posh in your `$PROFILE`:
This will also make use of the [posh-git][poshgit] output rather than do additional work to get the git status.
If you want to display the default [posh-git][poshgit] output, **do not** set the above environment variable
and add the following snippet after initializing Oh My Posh in your `$PROFILE`:
```powershell ```powershell
function Set-PoshGitStatus { function Set-PoshGitStatus {
@ -58,6 +54,7 @@ import Config from "@site/src/components/Config.js";
untracked_modes: { untracked_modes: {
"/Users/user/Projects/oh-my-posh/": "no", "/Users/user/Projects/oh-my-posh/": "no",
}, },
source: "cli",
}, },
}} }}
/> />
@ -80,6 +77,7 @@ You can set the following properties to `true` to enable fetching additional inf
| `native_fallback` | `boolean` | `false` | when set to `true` and `git.exe` is not available when inside a WSL2 shared Windows drive, we will fallback to the native git executable to fetch data. Not all information can be displayed in this case | | `native_fallback` | `boolean` | `false` | when set to `true` and `git.exe` is not available when inside a WSL2 shared Windows drive, we will fallback to the native git executable to fetch data. Not all information can be displayed in this case |
| `fetch_user` | [`User`](#user) | `false` | fetch the current configured user for the repository | | `fetch_user` | [`User`](#user) | `false` | fetch the current configured user for the repository |
| `status_formats` | `map[string]string` | | a key, value map allowing to override how individual status items are displayed. For example, `"status_formats": { "Added": "Added: %d" }` will display the added count as `Added: 1` instead of `+1`. See the [Status](#status) section for available overrides. | | `status_formats` | `map[string]string` | | a key, value map allowing to override how individual status items are displayed. For example, `"status_formats": { "Added": "Added: %d" }` will display the added count as `Added: 1` instead of `+1`. See the [Status](#status) section for available overrides. |
| `source` | `string` | `cli` | <ul><li>`cli`: fetch the information using the git CLI</li><li>`pwsh`: fetch the information from the [posh-git][poshgit] PowerShell Module</li></ul> |
### Icons ### Icons
@ -185,7 +183,7 @@ Local changes use the following syntax:
### Commit ### Commit
| Name | Type | Description | | Name | Type | Description |
| ------------ | ----------- | -------------------------------------- | | ------------ | ----------- | --------------------------------------- |
| `.Author` | `User` | the author of the commit (see below) | | `.Author` | `User` | the author of the commit (see below) |
| `.Committer` | `User` | the committer of the commit (see below) | | `.Committer` | `User` | the committer of the commit (see below) |
| `.Subject` | `string` | the commit subject | | `.Subject` | `string` | the commit subject |