如何在 PowerShell 提示符中显示当前的 git 分支名称?
-
18-09-2019 - |
题
基本上我在追求 这 但对于 PowerShell 而不是 bash。
我通过 PowerShell 在 Windows 上使用 git。如果可能,我希望将当前的分支名称显示为命令提示符的一部分。
解决方案
一种更简单的方法是安装 Powershell 模块 豪华git. 。它开箱即用,并带有所需的提示:
提示
PowerShell 通过执行提示函数(如果存在)来生成提示符。posh-git 在 profile.example.ps1 中定义了这样一个函数,它输出当前工作目录,后跟缩写的 git status:
C:\Users\Keith [master]>
默认情况下,状态摘要具有以下格式:
[{HEAD-name} +A ~B -C !D | +E ~F -G !H]
(为了安装 posh-git 我建议使用 PSGET)
如果您没有 psget,请使用以下命令:
(new-object Net.WebClient).DownloadString("http://psget.net/GetPsGet.ps1") | iex
要安装 posh-git 使用命令:Install-Module posh-git
为了确保 posh-git 加载每个 shell,请使用 Add-PoshGitToPrompt
命令.
其他提示
@保罗
我PowerShell配置需导是基于一个脚本我在这里找到:
http://techblogging.wordpress.com/2008/10/12/displaying-git-branch-on-your-powershell-prompt/
我已经修改这一点,以显示目录的道路和一些格式。它还设置的路径到我的混站的位置,因为我使用PortableGit.
# General variables
$pathToPortableGit = "D:\shared_tools\tools\PortableGit"
$scripts = "D:\shared_tools\scripts"
# Add Git executables to the mix.
[System.Environment]::SetEnvironmentVariable("PATH", $Env:Path + ";" + (Join-Path $pathToPortableGit "\bin") + ";" + $scripts, "Process")
# Setup Home so that Git doesn't freak out.
[System.Environment]::SetEnvironmentVariable("HOME", (Join-Path $Env:HomeDrive $Env:HomePath), "Process")
$Global:CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$UserType = "User"
$CurrentUser.Groups | foreach {
if ($_.value -eq "S-1-5-32-544") {
$UserType = "Admin" }
}
function prompt {
# Fun stuff if using the standard PowerShell prompt; not useful for Console2.
# This, and the variables above, could be commented out.
if($UserType -eq "Admin") {
$host.UI.RawUI.WindowTitle = "" + $(get-location) + " : Admin"
$host.UI.RawUI.ForegroundColor = "white"
}
else {
$host.ui.rawui.WindowTitle = $(get-location)
}
Write-Host("")
$status_string = ""
$symbolicref = git symbolic-ref HEAD
if($symbolicref -ne $NULL) {
$status_string += "GIT [" + $symbolicref.substring($symbolicref.LastIndexOf("/") +1) + "] "
$differences = (git diff-index --name-status HEAD)
$git_update_count = [regex]::matches($differences, "M`t").count
$git_create_count = [regex]::matches($differences, "A`t").count
$git_delete_count = [regex]::matches($differences, "D`t").count
$status_string += "c:" + $git_create_count + " u:" + $git_update_count + " d:" + $git_delete_count + " | "
}
else {
$status_string = "PS "
}
if ($status_string.StartsWith("GIT")) {
Write-Host ($status_string + $(get-location) + ">") -nonewline -foregroundcolor yellow
}
else {
Write-Host ($status_string + $(get-location) + ">") -nonewline -foregroundcolor green
}
return " "
}
迄今为止,这个工作真的很好。虽然在一个仓库,提示高兴地看起来是:
GIT[高级]c:0u:1d:0|J:\Projects\forks\fluent-nhibernate>
*注意:更新的建议Jakub Narębski.
- 除去跟踪过去状态的呼吁。
- 解决问题'混帐config--全球会失败,因为$家不是集中。
- 解决的一个问题,浏览的目录,也没有.git目录将导致格式,以恢复到PS提示。
下面是我采取它。我已经编辑的颜色有点以使其更具有可读性。
<强> Microsoft.PowerShell_profile.ps1 强>
function Write-BranchName () {
try {
$branch = git rev-parse --abbrev-ref HEAD
if ($branch -eq "HEAD") {
# we're probably in detached HEAD state, so print the SHA
$branch = git rev-parse --short HEAD
Write-Host " ($branch)" -ForegroundColor "red"
}
else {
# we're on an actual branch, so print it
Write-Host " ($branch)" -ForegroundColor "blue"
}
} catch {
# we'll end up here if we're in a newly initiated git repo
Write-Host " (no branches yet)" -ForegroundColor "yellow"
}
}
function prompt {
$base = "PS "
$path = "$($executionContext.SessionState.Path.CurrentLocation)"
$userPrompt = "$('>' * ($nestedPromptLevel + 1)) "
Write-Host "`n$base" -NoNewline
if (Test-Path .git) {
Write-Host $path -NoNewline -ForegroundColor "green"
Write-BranchName
}
else {
# we're not in a repo so don't bother displaying branch name/sha
Write-Host $path -ForegroundColor "green"
}
return $userPrompt
}
示例1:强>
示例2:强>
我调整的提示码(从@david-longnecker的答复)是一个有点更加丰富多彩。
编辑: 六月2019年-展示更新未跟踪,储藏,重新命名.调整的视觉显示指标。
为什么 我 使用这个 (通过的辣妹-git等):
- 学习:学习的东西git/SCM概念当作为我调整
- 结束了固定的问题,解决通过的辣妹-git,但我了解更多的是通过这个
- 交叉平台:具有同样的提示在POSIX炮弹,代码是几乎完全相同。
- 灵活性:我已经调整了我的提示表明未跟踪/储藏/index/重新命名.
- 轻巧便携式:没有获取外部模块(这是未成年人的利益,但不错的)
Powershell码:
注: 一些命令使用的都是瓷器(不建议脚本/析,例如 git status
).最终将迁移到 管道 命令,但是这一工作。
Function Prompt {
$SYMBOL_GIT_BRANCH='⑂'
$SYMBOL_GIT_MODIFIED='*'
$SYMBOL_GIT_PUSH='↑'
$SYMBOL_GIT_PULL='↓'
if (git rev-parse --git-dir 2> $null) {
$symbolicref = $(git symbolic-ref --short HEAD 2>$NULL)
if ($symbolicref) {#For branches append symbol
$branch = $symbolicref.substring($symbolicref.LastIndexOf("/") +1)
$branchText=$SYMBOL_GIT_BRANCH + ' ' + $branch
} else {#otherwise use tag/SHA
$symbolicref=$(git describe --tags --always 2>$NULL)
$branch=$symbolicref
$branchText=$symbolicref
}
} else {$symbolicref = $NULL}
if ($symbolicref -ne $NULL) {
# Tweak:
# When WSL and Powershell terminals concurrently viewing same repo
# Stops from showing CRLF/LF differences as updates
git status > $NULL
#Do git fetch if no changes in last 10 minutes
# Last Reflog: Last time upstream was updated
# Last Fetch: Last time fetch/pull was ATTEMPTED
# Between the two can identify when last updated or attempted a fetch.
$MaxFetchSeconds = 600
$upstream = $(git rev-parse --abbrev-ref "@{upstream}")
$lastreflog = $(git reflog show --date=iso $upstream -n1)
if ($lastreflog -eq $NULL) {
$lastreflog = (Get-Date).AddSeconds(-$MaxFetchSeconds)
}
else {
$lastreflog = [datetime]$($lastreflog | %{ [Regex]::Matches($_, "{(.*)}") }).groups[1].Value
}
$gitdir = $(git rev-parse --git-dir)
$TimeSinceReflog = (New-TimeSpan -Start $lastreflog).TotalSeconds
if (Test-Path $gitdir/FETCH_HEAD) {
$lastfetch = (Get-Item $gitdir/FETCH_HEAD).LastWriteTime
$TimeSinceFetch = (New-TimeSpan -Start $lastfetch).TotalSeconds
} else {
$TimeSinceFetch = $MaxFetchSeconds + 1
}
#Write-Host "Time since last reflog: $TimeSinceReflog"
#Write-Host "Time since last fetch: $TimeSinceFetch"
if (($TimeSinceReflog -gt $MaxFetchSeconds) -AND ($TimeSinceFetch -gt $MaxFetchSeconds)) {
git fetch --all | Out-Null
}
#Identify stashes
$stashes = $(git stash list 2>$NULL)
if ($stashes -ne $NULL) {
$git_stashes_count=($stashes | Measure-Object -Line).Lines
}
else {$git_stashes_count=0}
#Identify how many commits ahead and behind we are
#by reading first two lines of `git status`
#Identify how many untracked files (matching `?? `)
$marks=$NULL
(git status --porcelain --branch 2>$NULL) | ForEach-Object {
If ($_ -match '^##') {
If ($_ -match 'ahead\ ([0-9]+)') {$git_ahead_count=[int]$Matches[1]}
If ($_ -match 'behind\ ([0-9]+)') {$git_behind_count=[int]$Matches[1]}
}
#Identify Added/UnTracked files
elseIf ($_ -match '^A\s\s') {
$git_index_added_count++
}
elseIf ($_ -match '^\?\?\ ') {
$git_untracked_count++
}
#Identify Modified files
elseIf ($_ -match '^MM\s') {
$git_index_modified_count++
$git_modified_count++
}
elseIf ($_ -match '^M\s\s') {
$git_index_modified_count++
}
elseIf ($_ -match '^\sM\s') {
$git_modified_count++
}
#Identify Renamed files
elseIf ($_ -match '^R\s\s') {
$git_index_renamed_count++
}
#Identify Deleted files
elseIf ($_ -match '^D\s\s') {
$git_index_deleted_count++
}
elseIf ($_ -match '^\sD\s') {
$git_deleted_count++
}
}
$branchText+="$marks"
}
if (test-path variable:/PSDebugContext) {
Write-Host '[DBG]: ' -nonewline -foregroundcolor Yellow
}
Write-Host "PS " -nonewline -foregroundcolor White
Write-Host $($executionContext.SessionState.Path.CurrentLocation) -nonewline -foregroundcolor White
if ($symbolicref -ne $NULL) {
Write-Host (" [ ") -nonewline -foregroundcolor Magenta
#Output the branch in prettier colors
If ($branch -eq "master") {
Write-Host ($branchText) -nonewline -foregroundcolor White
}
else {Write-Host $branchText -nonewline -foregroundcolor Red}
#Output commits ahead/behind, in pretty colors
If ($git_ahead_count -gt 0) {
Write-Host (" $SYMBOL_GIT_PUSH") -nonewline -foregroundcolor White
Write-Host ($git_ahead_count) -nonewline -foregroundcolor Green
}
If ($git_behind_count -gt 0) {
Write-Host (" $SYMBOL_GIT_PULL") -nonewline -foregroundcolor White
Write-Host ($git_behind_count) -nonewline -foregroundcolor Yellow
}
#Output staged changes count, if any, in pretty colors
If ($git_index_added_count -gt 0) {
Write-Host (" Ai:") -nonewline -foregroundcolor White
Write-Host ($git_index_added_count) -nonewline -foregroundcolor Green
}
If ($git_index_renamed_count -gt 0) {
Write-Host (" Ri:") -nonewline -foregroundcolor White
Write-Host ($git_index_renamed_count) -nonewline -foregroundcolor DarkGreen
}
If ($git_index_modified_count -gt 0) {
Write-Host (" Mi:") -nonewline -foregroundcolor White
Write-Host ($git_index_modified_count) -nonewline -foregroundcolor Yellow
}
If ($git_index_deleted_count -gt 0) {
Write-Host (" Di:") -nonewline -foregroundcolor White
Write-Host ($git_index_deleted_count) -nonewline -foregroundcolor Red
}
#Output unstaged changes count, if any, in pretty colors
If (($git_index_added_count) -OR ($git_index_modified_count) -OR ($git_index_deleted_count)) {
If (($git_modified_count -gt 0) -OR ($git_deleted_count -gt 0)) {
Write-Host (" |") -nonewline -foregroundcolor White
}
}
If ($git_modified_count -gt 0) {
Write-Host (" M:") -nonewline -foregroundcolor White
Write-Host ($git_modified_count) -nonewline -foregroundcolor Yellow
}
If ($git_deleted_count -gt 0) {
Write-Host (" D:") -nonewline -foregroundcolor White
Write-Host ($git_deleted_count) -nonewline -foregroundcolor Red
}
If (($git_untracked_count -gt 0) -OR ($git_stashes_count -gt 0)) {
Write-Host (" |") -nonewline -foregroundcolor White
}
If ($git_untracked_count -gt 0) {
Write-Host (" untracked:") -nonewline -foregroundcolor White
Write-Host ($git_untracked_count) -nonewline -foregroundcolor Red
}
If ($git_stashes_count -gt 0) {
Write-Host (" stashes:") -nonewline -foregroundcolor White
Write-Host ($git_stashes_count) -nonewline -foregroundcolor Yellow
}
Write-Host (" ]") -nonewline -foregroundcolor Magenta
}
$(Write-Host $('>' * ($nestedPromptLevel + 1)) -nonewline -foregroundcolor White)
return " "}#Powershell requires a return, otherwise defaults to factory prompt
这里是命令从结果来看是什么它看起来像:
mkdir "c:\git\newrepo" | Out-Null
cd "c:\git\newrepo"
git init
"test" >> ".gitignore"
"test" >> ".gitignore2"
git add -A
git commit -m "test commit" | Out-Null
"test" >> ".gitignore1"
git add -A
"test1" >> ".gitignore2"
git rm .gitignore
git add -A
git commit -m "test commit2" | Out-Null
git checkout -b "newfeature1"
"test" >> ".test"
mv .gitignore1 .gitignore3
git add -A
git stash
git checkout "master"
cd c:\git\test #Just a sample repo had that was ahead 1 commit
#Remove-Item "c:\git\newrepo" -Recurse -Force #Cleanup