shuhelohelo’s blog

Xamarin.Forms多めです.

PowerShellでGitを使いやすくする

git-scm.com

Windowsでgitやdotnetawsなどのコマンドラインツールを使いたい。

でもコマンドプロンプトは使いたくない、lsと打って怒られるのはもう嫌だ、というときPowershellだと若干そのあたりの不満を解消できます。

しかしながらgitをインストールしてもデフォルトでは今いるブランチがどこなのか,ひと目でわからないため使いにくかったりします.

そこで,posh-gitです.PowerShell Git.

「.NET Conf 2019」でもプレゼンターが使っていました.

posh-gitはPowershell用のgitクライアントです.

これを導入することで,

導入前: f:id:shuhelohelo:20191022020103p:plain

導入後: f:id:shuhelohelo:20191022020231p:plain

このように今いるブランチがウィンドウのタイトルとプロンプトに表示され,Gitのステータスも表示されるため,現在のブランチの変更状況を把握しやすくなります.

プロンプトに表示される情報の意味は,posh-gitのGitHubリポジトリのReadMeに詳しく書いてあります.

github.com

インストール手順

Git for Windowsはインストール済みとします.

インストール方法は上記のReadMeにも書いてあるとおりいくつかあるのですが,PowerShell Gallaryからコマンド一つでインストールするのが楽です.

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

また,パッケージ管理ツールのchocolateyからもインストールできるので,chocolateyを使っている方にはこちらも便利です.

Posh-gitの有効化

以下のコマンドで有効化します.

Import-Module posh-git

有効化してからPowerShellを再起動してGit管理されたフォルダに移動すると,前述のようにGitの情報が表示されます.

PowerShell起動時にPosh-gitを有効化するには,PowerShellのプロファイルに以下の情報を書きます.

Import-Module posh-git

プロファイルはデフォルトでは以下の場所にあります.

Windows PowerShellの場合:

C:\Users\{UserName}\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

PowerShell 7の場合:

C:\Users\{UserName}\Documents\PowerShell\profile.ps1

プロンプトのカスタマイズ

プロファイルにいろいろ書くことで,プロンプトの表示を変更できます.

例えばこちらとか.

qiita.com

こちらの設定を使用すると,以下のようになります. プロンプトが2行目に表示されるようになりました. 入力位置,ブランチの情報が左端にまとまって見やすくなりました.

f:id:shuhelohelo:20191022023113p:plain

その他にはこちらとか.

opcdiary.net

こちらはプロンプトに表示されるパスが長い場合に短縮してくれます.末尾から16文字という設定とのことです.

そこで,この2つを組み合わせて,

  • Gitの情報とプロンプトを左側に集める
  • パスが長い場合は短縮する

という設定にしてみました.

Import-Module posh-git

function global:prompt {
    $realLASTEXITCODE = $LASTEXITCODE

    # # Reset color, which can be messed up by Enable-GitColors
    # $Host.UI.RawUI.ForegroundColor = $GitPromptSettings.DefaultForegroundColor

    $pro = ''

    Write-VcsStatus

    if ($pwd.ProviderPath.ToString().Length -gt 19) {
        if ((Split-Path($pwd.ProviderPath) -Leaf).ToString().Length -gt 16) {  #C:\分は削除して
            $pro = $pwd.Drive.Name + ':\..' + (Split-Path($pwd.ProviderPath) -Leaf)
        }
        else {
            $start = $pwd.ProviderPath.ToString().Length - 16
            $pro = $pwd.Drive.Name + ':\..' + $pwd.ProviderPath.Substring($start)
        }
        
    }
    else {
        $pro = $pwd.ProviderPath
    }

    Write-Host($pro) -nonewline -ForegroundColor Green

    Write-Host 


    $global:LASTEXITCODE = $realLASTEXITCODE
    return "$('>' * ($nestedPromptLevel + 1)) "
}

$global:GitPromptSettings.BeforeText = '['
$global:GitPromptSettings.AfterText  = '] '

これによって,以下のようにスッキリ見やすくなりました.

f:id:shuhelohelo:20191022025502p:plain

だいぶPowerShellでGitを使いやすくなりました.

20191022追記:

プロンプトのパスの表示をカレントディレクトリ名だけにしました.

こっちのほうがよりスッキリするかなと思って.フルパスが知りたいときはpwdコマンドを使うことにします.

こちらのサイトを参考にしました.

qiita.com

このように表示されます.

f:id:shuhelohelo:20191022113552p:plain

プロファイルの内容は以下のとおりです.

Import-Module posh-git

function global:prompt {
    $realLASTEXITCODE = $LASTEXITCODE

    # # Reset color, which can be messed up by Enable-GitColors
    # $Host.UI.RawUI.ForegroundColor = $GitPromptSettings.DefaultForegroundColor

    # posh-gitの出力
    Write-VcsStatus

    # カレントディレクトリの出力.改行無し
    $idx = $pwd.ProviderPath.LastIndexOf("\")+1
    Write-Host($pwd.ProviderPath.Remove(0, $idx)) -nonewline

    # 改行
    Write-Host 

    $global:LASTEXITCODE = $realLASTEXITCODE
    return "$('>' * ($nestedPromptLevel + 1)) "
}

# Gitの情報を表示する部分を括る文字を変更する.
$global:GitPromptSettings.BeforeText = '['
$global:GitPromptSettings.AfterText  = '] '
# $global:GitPromptSettings.DefaultPromptAbbreviateHomeDirectory=$true

posh-gitの表示情報の見方

posh-gitが有効になるとGit管理下のディレクトリでは以下のようにGitの情報が表示されます.

[master +0 ~0 -1 ~] EggOrHen

この表示内容は以下を表しています.

  • +{n} : 追加されたファイルの数
  • ~{n} : 変更されたファイルの数
  • -{n} : 削除されたファイルの数
  • ~ : ステージング済みだがコミットされていないファイルがある
  • ! : ステージングされていないファイルがある

上記の例でいえば,削除されたファイルが1つあり,コミットされていないファイルがあることがわかります.

[master +0 ~0 -1 ~] EggOrHen
> git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    EggOrHen/MyClass.cs

他の例を見てみます.

[develop ≡ +0 ~5 -0 !] TakeMeThereXamarinForms
  • : ローカルとリモートで同じコミットを指している
  • ↑{num} : ローカルがリモートよりコミットが進んでいる.pushできるよ.
  • ↓{num} : リモートがローカルよりもコミットが進んでいる.pullできるよ.
  • {num a}↕{num b} : ローカルとリモートをあわせるにはpushとpullが必要な状況.rebaseしたほうがいい?

直感的でわかりやすいですね.

上の例では,5つの変更されたファイルがあり,ステージングされていないファイルがある,ということですね.

[develop ≡ +0 ~5 -0 !] TakeMeThereXamarinForms
> git status
On branch develop
Your branch is up to date with 'origin/develop'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   TakeMeThereXamarinForms/TakeMeThereXamarinForms/App.xaml
        modified:   TakeMeThereXamarinForms/TakeMeThereXamarinForms/App.xaml.cs
        modified:   TakeMeThereXamarinForms/TakeMeThereXamarinForms/Models/TargetInformation.cs
        modified:   TakeMeThereXamarinForms/TakeMeThereXamarinForms/Utility.cs
        modified:   TakeMeThereXamarinForms/TakeMeThereXamarinForms/Views/MainPage.xaml

ではこれをすべてステージングすると表示はどのように変わるでしょうか.

[develop ≡ +0 ~5 -0 !] TakeMeThereXamarinForms
> git add .
[develop ≡ +0 ~5 -0 ~] TakeMeThereXamarinForms
>

!~に変わりました.

ではファイルを1つだけステージングに追加してみます.

[develop ≡ +0 ~5 -0 !] TakeMeThereXamarinForms
> git add TakeMeThereXamarinForms/TakeMeThereXamarinForms/App.xaml
[develop ≡ +0 ~1 -0 | +0 ~4 -0 !] TakeMeThereXamarinForms
>

すると,このように|で区切られて,左側がステージングの情報,右がアンステージングの情報というように表示されます.