如何在 PowerShell 提示符中显示当前的 git 分支名称?

发布于 2024-08-02 06:15:32 字数 208 浏览 8 评论 0原文

基本上我在这个之后,但对于PowerShell而不是bash。

我通过 PowerShell 在 Windows 上使用 git。如果可能,我希望将当前的分支名称显示为命令提示符的一部分。

Basically I'm after this but for PowerShell instead of bash.

I use git on windows through PowerShell. If possible, I'd like my current branch name to displayed as part of the command prompt.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

雅心素梦 2024-08-09 06:15:32

一种更简单的方法是安装 Powershell 模块 posh-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("https://raw.githubusercontent.com/psget/psget/master/GetPsGet.ps1") | iex

要安装 posh-git,请使用以下命令:
Install-Module posh-git

要确保为每个 shell 加载 posh-git,请使用 Add-PoshGitToProfile 命令

An easier way would be just installing the Powershell module posh-git. It comes out of the box with the desired prompt:

The Prompt

PowerShell generates its prompt by executing a prompt function, if one exists. posh-git defines such a function in profile.example.ps1 that outputs the current working directory followed by an abbreviated git status:

C:\Users\Keith [master]>

By default, the status summary has the following format:

[{HEAD-name} +A ~B -C !D | +E ~F -G !H]

(For installing posh-git I suggest using psget)

If you don't have psget use the following command:

(new-object Net.WebClient).DownloadString("https://raw.githubusercontent.com/psget/psget/master/GetPsGet.ps1") | iex

To install posh-git use the command:
Install-Module posh-git

To ensure posh-git loads for every shell, use the Add-PoshGitToProfile command.

一场春暖 2024-08-09 06:15:32

这是我的看法。我对颜色进行了一些编辑,以使其更具可读性。

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:

在此处输入图像描述

Here's my take on it. I've edited the colours a bit to make it more readable.

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
}

Example 1:

enter image description here

Example 2:

enter image description here

掩于岁月 2024-08-09 06:15:32

@Paul-

我的 Git PowerShell 配置文件基于我在这里找到的脚本:

http://techblogging.wordpress.com/2008/10/12/displaying-git-branch-on-your-powershell-prompt/

我已将其修改为位显示目录路径和一些格式。由于我使用 PortableGit,它还设置了我的 Git bin 位置的路径。

# 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 [master] c:0 u:1 d:0 | J:\ Projects \ forks \ Fluent-nhibernate>

*注:根据 Jakub Narębski 的建议进行了更新。

  • 删除了 git 分支/git 状态调用。
  • 解决了由于未设置 $HOME 而导致“git config --global”失败的问题。
  • 解决了浏览到没有 .git 目录的目录会导致格式恢复为 PS 提示符的问题。

@Paul-

My PowerShell profile for Git is based off of a script I found here:

http://techblogging.wordpress.com/2008/10/12/displaying-git-branch-on-your-powershell-prompt/

I've modified it a bit to display the directory path and a bit of formatting. It also sets the path to my Git bin location since I use 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 " "
 }

So far, this has worked really well. While in a repo, the prompt happily looks like:

GIT [master] c:0 u:1 d:0 | J:\Projects\forks\fluent-nhibernate>

*NOTE: Updated with suggestions from Jakub Narębski.

  • Removed git branch/git status calls.
  • Addressed an issue where 'git config --global' would - fail because $HOME was not set.
  • Addressed an issue where browsing to a directory that didn't have the .git directory would cause the formatting to revert to the PS prompt.
初见你 2024-08-09 06:15:32

posh-git 很慢,有更好的方法 https://ohmyposh.dev/

输入图像描述这里

  1. 从 powershell 运行此命令来安装 ohmyposh 模块:
Install-Module oh-my-posh -Scope CurrentUser -AllowPrerelease
  1. 安装支持来自 https://www.nerdfonts.com/
    我喜欢 Meslo LGM NF

  2. 在 powershell 默认设置中设置该字体:

在此处输入图像描述

  1. C:\Program Files\PowerShell\7 打开/创建文件 Microsoft.PowerShell_profile.ps1 并写入下面设置主题(与屏幕截图相同):
Set-PoshPrompt -Theme aliens

您也可以选择其他主题。通过运行 Get-PoshThemes 查看预览

现在在包含 git repo 的位置打开 powershell,您将看到状态。


查看更多信息:启动您的 PowerShell

posh-git is slow, there's a better way with https://ohmyposh.dev/.

enter image description here

  1. Run this command from powershell to install ohmyposh module:
Install-Module oh-my-posh -Scope CurrentUser -AllowPrerelease
  1. install font that supports glyphs (icons) from https://www.nerdfonts.com/.
    I like Meslo LGM NF.

  2. set that font in powershell defaults settings:

enter image description here

  1. Open/create file Microsoft.PowerShell_profile.ps1 at C:\Program Files\PowerShell\7 and write below to set theme (same as screenshot):
Set-PoshPrompt -Theme aliens

You can choose other theme also. see preview by running Get-PoshThemes

Now open powershell at location containing git repo and you'll see the status.


See more: Power up your PowerShell

若相惜即相离 2024-08-09 06:15:32

使用 Git 2.22(2019 年第 2 季度),任何脚本(无论是否为 Powershell)都可以使用新的 --show-current 选项

$branch = git branch --show-current

如果为空,则表示“分离的 HEAD”。

With Git 2.22 (Q2 2019), any script (Powershell or not) could use the new --show-current option.

$branch = git branch --show-current

If empty, it means "detached HEAD".

偏爱你一生 2024-08-09 06:15:32

我调整了提示代码(来自@david-longnecker 的回答),使其更加丰富多彩。

编辑: 2019 年 6 月 - 更新以显示未跟踪、隐藏、重命名。调整视觉效果以显示索引。

为什么使用这个(通过 posh-git 等):

  • 学习:在调整时学习有关 git/SCM 概念的内容
    • 最终解决了 posh-git 解决的问题,但我通过这个学到了更多
  • 跨平台了解了更多信息:在 POSIX shell 中具有相同的提示,代码几乎相同。
  • 灵活:我调整了提示以显示未跟踪/隐藏/索引/重命名。
  • 轻量级便携:无需获取外部模块(这是一个小好处,但很好)

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

结果(VSCode,使用 Powershell 终端):
Powershell Git操作提示

以下是来自结果的命令,用于查看结果:

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

I tweaked the prompt code (from @david-longnecker answer) to be a bit more colorful.

Edit: June 2019 - Updated to show untracked, stashes, renames. Tweaked visual to show index.

Why I use this (over posh-git etc):

  • Learning: Learn stuff about git/SCM concepts when as I tweak
    • End up fixing problems solved by posh-git, but I learn more through this
  • Cross Platform: Have same prompt in POSIX shells, code is almost identical.
  • Flexible: I've tweaked my Prompt to show untracked/stashes/index/renames.
  • Lightweight & Portable: No fetching external modules (this is minor benefit, but nice)

The powershell code:

NOTE: Some commands used are porcelain (not recommended for scripting/parsing, e.g. git status). Will eventually migrate to plumbing commands, but this works for now.

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

The result (VSCode, Using Powershell terminal):
Powershell Git Prompt in action

Here are commands from result to view what it would look like:

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
沫尐诺 2024-08-09 06:15:32

我改编了 @tamj0rd2 答案,以进一步在存储库的子文件夹中显示分支名称。

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 (! (git -C . rev-parse) ) {
        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
}

查看差异:

- if (Test-Path .git) {
+ if (! (git -C . rev-parse) ) {

I adapted @tamj0rd2 answer to further display the branch name in sub folders of the repository as well.

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 (! (git -C . rev-parse) ) {
        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
}

See the diff:

- if (Test-Path .git) {
+ if (! (git -C . rev-parse) ) {
忆沫 2024-08-09 06:15:32

我喜欢已接受的答案,因此我将详细说明设置它的步骤。
您可以使用 Chocolatey 或使用可用于新 Core PowerShell 的 PowerShellGet 命令来安装 PoshGit。

对于 Chocolatey,您需要先安装它才能继续。
在管理员/提升的 shell 中执行命令:

choco install poshgit

对于 Core PowerShell,还需要安装。要安装 Core PowerShell,请执行以下命令:

dotnet tool install --global PowerShell

注意:您需要安装 .NET Core SDK(最好是最新版本)

安装 Core PowerShell 后,执行以下命令安装 PoshGit:

PowerShellGet\Install-Module posh-git -Scope CurrentUser -AllowPrerelease -Force

使用 PoshGit 需要您使用以下命令将其导入到当前运行的 shell 环境中:命令导入模块 posh-git。这意味着每次打开新 shell 时都必须运行此命令。

如果您希望 PoshGit 始终可用,您应该执行以下命令:

Add-PoshGitToProfile

请注意,PowerShell 和 Core PowerShell 不同,因此它们在不同的配置文件上运行。这意味着,如果您希望 PoshGit 适用于任一 shell,您需要在各自的 shell 环境中执行这些命令。

I like the accepted answer so I will elaborate on the steps to set it up.
You can install PoshGit using Chocolatey or using the PowerShellGet command which is available for the new Core PowerShell.

For Chocolatey, you need to have it already installed before proceeding.
In an administrator/elevated shell execute the command:

choco install poshgit

For Core PowerShell, installation is also required. To install Core PowerShell, execute the following command:

dotnet tool install --global PowerShell

NB: You need to have .NET Core SDK installed (latest version preferably)

After installing Core PowerShell, execute the command below to install PoshGit:

PowerShellGet\Install-Module posh-git -Scope CurrentUser -AllowPrerelease -Force

Using PoshGit requires you import it to the currently running shell environment using the command Import-Module posh-git. This means you have to run this command every time you open a new shell.

If you want PoshGit to be always available you should execute this command instead:

Add-PoshGitToProfile

Please note that PowerShell and Core PowerShell are different and as a result they run on different profiles. What this means is that if you want PoshGit to work for either of the shells you need to execute those commands in their respective shell environment.

梦里的微风 2024-08-09 06:15:32

从 @tamj0rd2 的回答中,我们可以将分支名称获取到这样的字符串变量中。

$branch = git rev-parse --abbrev-ref HEAD
echo $branch

From @tamj0rd2's answer we can get the branch name to a string variable like this.

$branch = git rev-parse --abbrev-ref HEAD
echo $branch
不乱于心 2024-08-09 06:15:32

这是我的 PowerShell Core 配置。只需复制下面的函数并将其放入您的 $PROFILE

function prompt {
  try {
    $GitBranch = git rev-parse --abbrev-ref HEAD
    # we're probably in detached HEAD state, so print the SHA
    if ($GitBranch -eq "HEAD") { $GitBranch = git rev-parse --short HEAD }
  } catch {}

  if ($GitBranch) { $GitBranch = " `e[33;93m[`e[33;96m$GitBranch`e[33;93m]`e[0m" }

  "PS $pwd$GitBranch> "
}

Here is my configuration for PowerShell Core. just copy the function below and put it in your $PROFILE

function prompt {
  try {
    $GitBranch = git rev-parse --abbrev-ref HEAD
    # we're probably in detached HEAD state, so print the SHA
    if ($GitBranch -eq "HEAD") { $GitBranch = git rev-parse --short HEAD }
  } catch {}

  if ($GitBranch) { $GitBranch = " `e[33;93m[`e[33;96m$GitBranch`e[33;93m]`e[0m" }

  "PS $pwd$GitBranch> "
}
つ低調成傷 2024-08-09 06:15:32

对于我来说,这是在 Windows 11 上使用终端应用程序的最简单方法。它在主题 PowerShell 上运行,不应用样式,并在子目录中显示分支。

  1. 在 powershell 中运行 echo %profile
  2. 导航到该文件,或者创建目录和文件(如果不存在)。我的位置是:C:\Users\YourName\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
  3. 粘贴以下代码:
function prompt {
    $gitBranch = & git rev-parse --abbrev-ref HEAD 2>$null
    $promptString = "$PWD"
    
    if ($gitBranch) {
        $promptString += " ($gitBranch)"
    }
    
    "$promptString> "
}

我使用日光深色 PowerShell 主题的最终结果:
输入图片此处描述

This was the simplest method for me on Windows 11 using the Terminal app. It works on a themed PowerShell, applies no styling, and displays the branch when in sub directories.

  1. Run echo %profile in powershell
  2. Navigate to the file or create the directory and file if it doesn't exist. Mine is located here: C:\Users\YourName\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
  3. Paste the following code:
function prompt {
    $gitBranch = & git rev-parse --abbrev-ref HEAD 2>$null
    $promptString = "$PWD"
    
    if ($gitBranch) {
        $promptString += " ($gitBranch)"
    }
    
    "$promptString> "
}

My final result with the solarized dark PowerShell theme:
enter image description here

归属感 2024-08-09 06:15:32

我使用了与上面 @tamj0rd2 类似的方法,但不太复杂。

打开:Microsoft.PowerShell_profile.ps1

添加第一个:

function Get-GitBranch {
    if (Test-Path .git) {
        $branch = git rev-parse --abbrev-ref HEAD
        " [$branch]"
    }
}

添加第二个:

function prompt {
    $p = Split-Path -leaf -path (Get-Location)
    Write-Host "$p" -NoNewline
    Write-Host (Get-GitBranch) -NoNewline -ForegroundColor Yellow
    Write-Host "> " -NoNewline
    return " "
}

结果如下:
输入图片这里的描述

我是如何通过使用 split-path 来实现减少的字符串或目录路径的,所以总共的提示是:

function prompt {
    $p = Split-Path -leaf -path (Get-Location)
    Write-Host "$p" -NoNewline
    Write-Host (Get-GitBranch) -NoNewline -ForegroundColor Yellow
    Write-Host "> " -NoNewline
    return " "
}

I used a similar method to the one above from @tamj0rd2, but less complex.

Open: Microsoft.PowerShell_profile.ps1

Add First:

function Get-GitBranch {
    if (Test-Path .git) {
        $branch = git rev-parse --abbrev-ref HEAD
        " [$branch]"
    }
}

Add Second:

function prompt {
    $p = Split-Path -leaf -path (Get-Location)
    Write-Host "$p" -NoNewline
    Write-Host (Get-GitBranch) -NoNewline -ForegroundColor Yellow
    Write-Host "> " -NoNewline
    return " "
}

The result is as below:
enter image description here

How I achieved the reduced string or directory path is by using the split-path, so in total the prompt is:

function prompt {
    $p = Split-Path -leaf -path (Get-Location)
    Write-Host "$p" -NoNewline
    Write-Host (Get-GitBranch) -NoNewline -ForegroundColor Yellow
    Write-Host "> " -NoNewline
    return " "
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文