Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prefix setting for posh-git default prompt. #393

Merged
merged 2 commits into from
Feb 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
[![Build status](https://ci.appveyor.com/api/projects/status/eb8erd5afaa01w80?svg=true)](https://ci.appveyor.com/project/dahlbyk/posh-git)
[![Join the chat at https://gitter.im/dahlbyk/posh-git](https://badges.gitter.im/dahlbyk/posh-git.svg)](https://gitter.im/dahlbyk/posh-git?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

posh-git is a PowerShell module that integrates Git and PowerShell by providing Git status summary information that can be displayed in the PowerShell prompt e.g.:
posh-git is a PowerShell module that integrates Git and PowerShell by providing Git status summary information that can be displayed in the PowerShell prompt, e.g.:
```
~\GitHub\dahlbyk\posh-git [master ≡ +0 ~1 -0 !]>
C:\Users\Keith\GitHub\posh-git [master ≡ +0 ~1 -0 !]>
```
posh-git also provides tab completion support for common git commands and branch names.
posh-git also provides tab completion support for common git commands, branch names, paths and more.
For example, with posh-git, PowerShell can tab complete git commands like `checkout` by typing `git ch` and pressing the <kbd>tab</kbd> key.
That will tab complete to `git checkout` and if you keep pressing <kbd>tab</kbd>, it will cycle through other command matches such as `cherry` and `cherry-pick`.
You can also tab complete remote names and branch names e.g.: `git pull or<tab> ma<tab>` tab completes to `git pull origin master`.
Expand Down Expand Up @@ -93,11 +93,11 @@ Type `git fe` and then press <kbd>tab</kbd>. If posh-git has been imported, that

### Step 3 (optional): Customize Your PowerShell Prompt
By default, posh-git will update your PowerShell prompt function to display Git status summary information when the current dir is inside a Git repository.
posh-git will not update your PowerShell prompt function if you have your own customized prompt function that has been defined before importing posh-git.
posh-git will not update your PowerShell prompt function if you have your own, customized prompt function that has been defined before importing posh-git.

The posh-git prompt is a single line prompt that looks like this:
```
~\GitHub\dahlbyk\posh-git [master ≡ +0 ~1 -0 !]>
C:\Users\Keith\GitHub\posh-git [master ≡ +0 ~1 -0 !]>
```
You can customize the posh-git prompt or define your own custom prompt function.
The most common customization for the posh-git provided prompt is to make it span two lines which can be done with the following command:
Expand All @@ -106,9 +106,26 @@ $GitPromptSettings.DefaultPromptSuffix = '`n$(''>'' * ($nestedPromptLevel + 1))
```
This will change the prompt to:
```
~\GitHub\dahlbyk\posh-git [master ≡ +0 ~1 -0 !]
C:\Users\Keith\GitHub\posh-git [master ≡ +0 ~1 -0 !]
>
```
You can also customize the default prompt prefix text e.g.:
```
$GitPromptSettings.DefaultPromptPrefix = '[$(hostname)] '
```
This will change the prompt to:
```
[KEITH1] C:\Users\Keith\GitHub\posh-git [master ≡ +0 ~1 -0 !]>
```
And if you would prefer to have any path under your home directory abbreviated with ~, you can change this setting:
```
$GitPromptSettings.DefaultPromptAbbreviateHomeDirectory = $true
```
This will change the prompt to the one shown below:
```
~\GitHub\posh-git [master ≡ +0 ~1 -0 !]>
```

You can also create your own prompt function to show whatever information you want.
See the [Customizing Your PowerShell Prompt](https://github.com/dahlbyk/posh-git/wiki/Customizing-Your-PowerShell-Prompt) wiki page for details.

Expand All @@ -127,9 +144,9 @@ By default, the status summary has the following format:
* Yellow means the branch is both ahead of and behind its remote
* S represents the branch status in relation to remote (tracked origin) branch. Note: This information reflects the state of the remote tracked branch after the last `git fetch/pull` of the remote.
* ≡ = The local branch in at the same commit level as the remote branch (`BranchIdenticalStatus`)
* ↑ = The local branch is ahead of the remote branch; a 'git push' is required to update the remote branch (`BranchAheadStatus`)
* ↓ = The local branch is behind the remote branch; a 'git pull' is required to update the local branch (`BranchBehindStatus`)
* = The local branch is both ahead and behind the remote branch; a rebase of the local branch is required before pushing local changes to the remote branch (`BranchBehindAndAheadStatus`)
* ↑`<num>` = The local branch is ahead of the remote branch by the specified number of commits; a 'git push' is required to update the remote branch (`BranchAheadStatus`)
* ↓`<num>` = The local branch is behind the remote branch by the specified number of commits; a 'git pull' is required to update the local branch (`BranchBehindStatus`)
* `<a>`↕`<b>` = The local branch is both ahead of the remote branch by the specified number of commits (a) and behind by the specified number of commits (b); a rebase of the local branch is required before pushing local changes to the remote branch (`BranchBehindAndAheadStatus`). NOTE: this status is only available if $GitPromptSettings.BranchBehindAndAheadDisplay is set to 'Compact'.
* × = The local branch is tracking a branch that is gone from the remote (`BranchGoneStatus')
* ABCD represent the index; ` | ` (`DelimText`); EFGH represent the working directory
* `+` = Added files
Expand Down
1 change: 1 addition & 0 deletions src/GitPrompt.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ $global:GitPromptSettings = [pscustomobject]@{

EnableWindowTitle = 'posh~git ~ '

DefaultPromptPrefix = ''
DefaultPromptSuffix = '$(''>'' * ($nestedPromptLevel + 1)) '
DefaultPromptDebugSuffix = ' [DBG]$(''>'' * ($nestedPromptLevel + 1)) '
DefaultPromptEnableTiming = $false
Expand Down
86 changes: 64 additions & 22 deletions src/en-US/about_posh-git.help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
posh-git

SHORT DESCRIPTION
posh-git integrates Git and PowerShell with tab completion and Git
status summary information displayed in the PowerShell prompt.
posh-git integrates Git and PowerShell providing tab completion of Git
commands, branch names, paths and more. It also provides Git status
summary information that can be displayed in the PowerShell prompt.

LONG DESCRIPTION
posh-git integrates Git and PowerShell. Tab completion is supported for
Expand All @@ -14,6 +15,10 @@ LONG DESCRIPTION
via the Get-GitStatus command. Then you can display the information in
your prompt however you would like.

posh-git will install a prompt function if it detects the user does not
have their own, customized prompt. This prompt displays Git status summary
information when the current directory is located in a Git repository.

GIT TAB COMPLETION
You can tab complete most common Git subcommands e.g.:

Expand All @@ -34,14 +39,29 @@ GIT TAB COMPLETION
"git ch" and press the tab key multiple times to cycle through "checkout",
"cherry" and "cherry-pick".

GIT STATUS PROMPT
PowerShell generates its prompt by executing a prompt function, if one
exists. posh-git defines such a function in the included
profile.example.ps1 script file that outputs the current working directory
followed by an abbreviated git status summary e.g.:
POWERSHELL PROMPT
PowerShell generates its prompt by executing a function named "prompt", if
one exists. posh-git will install its prompt function if it detects the
user does not have their own, customized prompt function. This prompt
displays the current working directory followed by git status summary
information if the current directory is located in a Git repository, e.g.:

C:\GitHub\posh-git [master ≡]>

You can customize the posh-git prompt with the following settings:

$GitPromptSettings.DefaultPromptPrefix
$GitPromptSettings.DefaultPromptSuffix
$GitPromptSettings.DefaultPromptDebugSuffix
$GitPromptSettings.DefaultPromptEnableTiming
$GitPromptSettings.DefaultPromptAbbreviateHomeDirectory

For more information on customizing the posh-git prompt or creating your
own custom PowerShell prompt see:

https://github.com/dahlbyk/posh-git/wiki/Customizing-Your-PowerShell-Prompt

GIT STATUS SUMMARY
[{HEAD-name} S +A ~B -C !D | +E ~F -G !H W]

* [ (BeforeText)
Expand All @@ -52,17 +72,24 @@ GIT STATUS PROMPT
* Yellow means the branch is both ahead of and behind its remote

* S represents the branch status in relation to remote (tracked origin) branch
* ≡ = Local branch is at the same commit level as the remote branch
(BranchIdenticalStatus)
* ↑ = Local branch is ahead of the remote branch; a 'git push' is
required to update the remote branch (BranchAheadStatus)
* ↓ = Local branch is behind the remote branch; a 'git pull' is
required to update the local branch (BranchBehindStatus)
* ↕ = Local branch is both ahead and behind the remote branch; a
rebase of the local branch is required before pushing local
changes to the remote branch (BranchBehindAndAheadStatus)
* × = The local branch is tracking a branch that is gone from the remote
(BranchGoneStatus)
* ≡ = Local branch is at the same commit level as the remote
branch (BranchIdenticalStatus).
* ↑<num> = Local branch is ahead of the remote branch by the specified
number of commits; a 'git push' is required to update the
remote branch (BranchAheadStatus).
* ↓<num> = Local branch is behind the remote branch by the specified
number of commits; a 'git pull' is required to update the
local branch (BranchBehindStatus).
* <a>↕<b>= Local branch is both ahead of the remote branch by the
specified number of commits (<a>) and behind by the
specified number of commits (<b>); a rebase of the local
branch is required before pushing local changes to the
remote branch (BranchBehindAndAheadStatus). NOTE: this
status is only available if
$GitPromptSettings.BranchBehindAndAheadDisplay is set to
'Compact'.
* × = The local branch is tracking a branch that is gone from the
remote (BranchGoneStatus).

* ABCD represents the index | EFGH represents the working directory
* + = Added files
Expand Down Expand Up @@ -105,10 +132,25 @@ GIT STATUS PROMPT
# new.file

USAGE AND CUSTOMIZATION
See profile.example.ps1 for an example of how you can integrate the tab
completion and/or git prompt into your own profile. Prompt formatting,
among other things, can be customized using the global variables
$GitPromptSettings, $GitTabSettings and $TortoiseGitSettings.
You need to import the posh-git module into your PowerShell session to
use it. Execute "Import-Module posh-git" to do this. After posh-git has
been imported, you can execute the command "Add-PoshGitToProfile" to have
your PowerShell profile updated to import posh-git whenever PowerShell
starts.

When posh-git is imported it will provide a basic prompt function that
displays Git status summary information, unless you have your own, custom
prompt function. Prompt formatting, among other things, can be customized
using the global variables: $GitPromptSettings, $GitTabSettings and
$TortoiseGitSettings. To see the available settings, simply type the
variable name at the PowerShell prompt (after posh-git has been imported)
and press Enter.

For more information on customizing the posh-git default prompt or creating
your own prompt fuction see:

https://github.com/dahlbyk/posh-git/wiki/Customizing-Your-PowerShell-Prompt


PERFORMANCE
Displaying Git status in your prompt for a very large repository can
Expand Down
14 changes: 11 additions & 3 deletions src/posh-git.psm1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
param([switch]$NoVersionWarn)
param([switch]$NoVersionWarn,[switch]$ForcePoshGitPrompt)

if (Get-Module posh-git) { return }

Expand Down Expand Up @@ -42,7 +42,7 @@ if (!$currentPromptDef) {
function global:prompt { ' ' }
}

if (!$currentPromptDef -or ($currentPromptDef -eq $defaultPromptDef)) {
if ($ForcePoshGitPrompt -or !$currentPromptDef -or ($currentPromptDef -eq $defaultPromptDef)) {
# Have to use [scriptblock]::Create() to get debugger detection to work in PS v2
$poshGitPromptScriptBlock = [scriptblock]::Create(@'
if ($GitPromptSettings.DefaultPromptEnableTiming) {
Expand All @@ -66,11 +66,19 @@ if (!$currentPromptDef -or ($currentPromptDef -eq $defaultPromptDef)) {
}

# Abbreviate path by replacing beginning of path with ~ *iff* the path is in the user's home dir
if ($GitPromptSettings.DefaultPromptAbbreviateHomeDirectory -and $currentPath -and $currentPath.StartsWith($Home, $stringComparison))
$abbrevHomeDir = $GitPromptSettings.DefaultPromptAbbreviateHomeDirectory
if ($abbrevHomeDir -and $currentPath -and $currentPath.StartsWith($Home, $stringComparison))
{
$currentPath = "~" + $currentPath.SubString($Home.Length)
}

# Display default prompt prefix if not empty.
$defaultPromptPrefix = [string]$GitPromptSettings.DefaultPromptPrefix
if ($defaultPromptPrefix) {
$expandedDefaultPromptPrefix = $ExecutionContext.SessionState.InvokeCommand.ExpandString($defaultPromptPrefix)
Write-Host $expandedDefaultPromptPrefix -NoNewline
}

# Write the abbreviated current path
Write-Host $currentPath -NoNewline

Expand Down
95 changes: 95 additions & 0 deletions test/DefaultPrompt.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
. $PSScriptRoot\Shared.ps1

Describe 'Default Prompt Tests' {
BeforeAll {
$prompt = Get-Item Function:\prompt
$OFS = ''
}
BeforeEach {
# Ensure these settings start out set to the default values
$GitPromptSettings.DefaultPromptPrefix = ''
$GitPromptSettings.DefaultPromptSuffix = '$(''>'' * ($nestedPromptLevel + 1)) '
$GitPromptSettings.DefaultPromptDebugSuffix = ' [DBG]$(''>'' * ($nestedPromptLevel + 1)) '
$GitPromptSettings.DefaultPromptAbbreviateHomeDirectory = $false
$GitPromptSettings.DefaultPromptEnableTiming = $false
}

Context 'Prompt with no Git summary' {
It 'Returns the expected prompt string' {
Set-Location $env:windir -ErrorAction Stop
$res = [string](&$prompt 6>&1)
$res | Should BeExactly "$env:windir> "
}
It 'Returns the expected prompt string with changed DefaultPromptPrefix' {
Set-Location $Home -ErrorAction Stop
$GitPromptSettings.DefaultPromptPrefix = 'PS '
$res = [string](&$prompt 6>&1)
$res | Should BeExactly "PS $Home> "
}
It 'Returns the expected prompt string with expanded DefaultPromptPrefix' {
Set-Location $Home -ErrorAction Stop
$GitPromptSettings.DefaultPromptPrefix = '[$(hostname)] '
$res = [string](&$prompt 6>&1)
$res | Should BeExactly "[$(hostname)] $Home> "
}
It 'Returns the expected prompt string with changed DefaultPromptSuffix' {
Set-Location $Home -ErrorAction Stop
$GitPromptSettings.DefaultPromptSuffix = '`n> '
$res = [string](&$prompt 6>&1)
$res | Should BeExactly "$Home`n> "
}
It 'Returns the expected prompt string with expanded DefaultPromptSuffix' {
Set-Location $Home -ErrorAction Stop
$GitPromptSettings.DefaultPromptSuffix = ' - $(6*7)> '
$res = [string](&$prompt 6>&1)
$res | Should BeExactly "$Home - 42> "
}
It 'Returns the expected prompt string with DefaultPromptAbbreviateHomeDirectory enabled' {
Set-Location $Home -ErrorAction Stop
$GitPromptSettings.DefaultPromptAbbreviateHomeDirectory = $true
$res = [string](&$prompt 6>&1)
$res | Should BeExactly "~> "
}
It 'Returns the expected prompt string with prefix, suffix and abbrev home set' {
Set-Location $Home -ErrorAction Stop
$GitPromptSettings.DefaultPromptPrefix = '[$(hostname)] '
$GitPromptSettings.DefaultPromptSuffix = ' - $(6*7)> '
$GitPromptSettings.DefaultPromptAbbreviateHomeDirectory = $true
$res = [string](&$prompt 6>&1)
$res | Should BeExactly "[$(hostname)] ~ - 42> "
}
It 'Returns the expected prompt string with prompt timing enabled' {
Set-Location $Home -ErrorAction Stop
$GitPromptSettings.DefaultPromptEnableTiming = $true
$res = [string](&$prompt 6>&1)
$escapedHome = [regex]::Escape($Home)
$res | Should Match "$escapedHome \d+ms> "
}
}

Context 'Prompt with Git summary' {
BeforeAll {
Set-Location $PSScriptRoot
}

It 'Returns the expected prompt string with status' {
Mock git {
if ($args -contains 'rev-parse') {
$res = Invoke-Expression "git.exe $args"
return $res
}
return @'
## master
A test/Foo.Tests.ps1
D test/Bar.Tests.ps1
M test/Baz.Tests.ps1

'@ -split [System.Environment]::NewLine
} -ModuleName posh-git

$res = [string](&$prompt 6>&1)
Assert-MockCalled git -ModuleName posh-git
$res | Should BeExactly "$PSScriptRoot [master +1 ~0 -0 | +0 ~1 -1 !]> "
}
}
}
15 changes: 0 additions & 15 deletions test/Get-GitStatus.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,6 @@ Describe 'Get-GitStatus Tests' {
Context 'Get-GitStatus Working Directory Tests' {
BeforeAll {
Set-Location $PSScriptRoot

function global:git {
$cmdline = "$args"
switch ($cmdline) {
'--version' { 'git version 2.11.0.windows.1' }
'help' { Get-Content $PSScriptRoot\git-help.txt }
default {
$res = Invoke-Expression "git.exe $cmdline"
$res
}
}
}

# Import module after we've overriden git command to return version, etc
. $PSScriptRoot\Shared.ps1
}

It 'Returns the correct branch name' {
Expand Down
19 changes: 18 additions & 1 deletion test/Shared.ps1
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
$modulePath = Convert-Path $PSScriptRoot\..\src
$moduleManifestPath = "$modulePath\posh-git.psd1"
$module = Import-Module $moduleManifestPath -PassThru

# We need this or the Git mocks don't work
function global:git {
$OFS = ' '
$cmdline = "$args"
switch ($cmdline) {
'--version' { 'git version 2.11.0.windows.1' }
'help' { Get-Content $PSScriptRoot\git-help.txt }
default {
$res = Invoke-Expression "git.exe $cmdline"
$res
}
}
}

# Force the posh-git prompt to be installed. Could be runnng on dev system where
# user has customized the prompt.
$module = Import-Module $moduleManifestPath -ArgumentList $true,$true -Force -PassThru

function MakeNativePath([string]$Path) {
$Path -replace '\\|/', [System.IO.Path]::DirectorySeparatorChar
Expand Down