How can I display my current git branch name in my

2019-01-21 05:33发布

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.

4条回答
Ridiculous、
2楼-- · 2019-01-21 06:03

@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.
查看更多
唯我独甜
3楼-- · 2019-01-21 06:13

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

Edit: Oct 2018 - Reworked with additional comments, some cleanup, a less noisy output than before.

The powershell code:

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

  $differences = $(git diff-index --name-status HEAD)

  If ($differences -ne $NULL) {
    $git_create_count = [regex]::matches($differences, "A`t").count
    $git_update_count = [regex]::matches($differences, "M`t").count
    $git_delete_count = [regex]::matches($differences, "D`t").count
  }
  else {
    $git_create_count = 0
    $git_update_count = 0
    $git_delete_count = 0
  }

  #Identify how many commits ahead and behind we are
  #by reading first two lines of `git status`
  $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]}
      }
  }
  $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 unstaged changes count, if any, in pretty colors   
  If ($git_create_count -gt 0) {
      Write-Host (" c:") -nonewline -foregroundcolor White
      Write-Host ($git_create_count) -nonewline -foregroundcolor Green
  }

  If ($git_update_count -gt 0) {
    Write-Host (" u:") -nonewline -foregroundcolor White
    Write-Host ($git_update_count) -nonewline -foregroundcolor Yellow
  }

  If ($git_delete_count -gt 0) {
    Write-Host (" d:") -nonewline -foregroundcolor White
    Write-Host ($git_delete_count) -nonewline -foregroundcolor Red
  }

  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): enter image description here

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"
git checkout "master"
cd c:\git\test #Just a sample repo had that was ahead 1 commit
查看更多
姐就是有狂的资本
4楼-- · 2019-01-21 06:20

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("http://psget.net/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-PoshGitToPrompt command.

查看更多
祖国的老花朵
5楼-- · 2019-01-21 06:25

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

查看更多
登录 后发表回答