LoginSignup
5
2

More than 1 year has passed since last update.

Git For Windowsをさわってみる from PowerShell+【oh-my-poshとposh-gitも】

Last updated at Posted at 2021-07-19

Windows環境でGitを使い始める時に自分だったらこういうことを知りたかったかな? ってことのまとめ。

WindowsPowerShellからGitコマンドを実行する時のあれこれについて初級編。

Git For Windowsって?

そもそもGitとはなんぞや?

GitLinuxの生みの親として有名なLinusさんが2005年にLinuxのソース管理のために生み出した分散バージョン管理システム。

Linuxのソース管理でGitが必要になった背景等は Gitの10年間: Gitの生みの親 Linus Torvalds のインタビューに日本語記事があったけどリンク切れ。

InternetArchiveに残ってるのは こちら

また原文はこちら10 Years of Git: An Interview with Git Creator Linus Torvalds

Linuxのための生み出された分散バージョン管理システムと聞くと。

大規模 だったり 複数人が共同で開発を行う場合に利用するのかな? といった印象を受けますが。
Windowsでひとり開発を行う際にも力を発揮する強力なツールになります。

昔はWindowsGitを利用するにあたって色々あったようですが。

現在はGit For Windowsで提供されるインストーラを実行すれば手軽に利用ができるようになります。
Gitの一部はシェルスクリプトで実装されており、Git for WindowsMSYS2を介してシェルスクリプトを実行していたりするのでGit for Windowsをインストールするとそこら編も一緒にインストールされます。

最近はバージョン管理といえばGitな勢いで普及しており、色々な場面でつかわれているようには思います。

余談 WindowsでGit

Windows環境でのGitについて調べているとcygwinやらmsysGitとかも単語として引っかかってきます。

過去、cygwin上でGitを利用するだったり、Git for Windowsの開発環境はmsysGitで現在はGit for Windows SDKになったり。

色々と大きな流れがあった末に現在はGit for Windowsになっています。

アーカイブされているmsysgit - wiki に記載が少しあります。

CUI or GUI

Gitはコマンドラインツールですが、様々なGUIクライアントが存在しておりCUIのみならずGUIからも操作をする事ができます。

本資料ではGitCUI(PowerShell)から実行しています。

なおGUIクライアントについては下記ページにて各種紹介されています。

ドキュメントやらなんやら

Microsoft Learnで提供されているGitの講座はなかなかわかりやすくていいかと思います。

video

Pro Git

Git evangelistであるScott ChaconさんとBen Straubさんが出版したGit解説本。

この書籍は Creative Commons Attribution-NonCommercial-ShareAlike 3.0にてライセンスされておりGit公式サイトでもオンラインで参照でき、また有志によって各言語に翻訳されています。

下記はProGitの日本語翻訳プロジェクトらしい。

本資料で利用している環境

  • Windows 10
  • PowerShell 7
  • Git 2.32.0 64 Bit
  • PowerShell-Module:posh-git
  • PowerShell-Module:oh-my-posh v3

Git For Windowsのインストール

上記ページにWindowsインストールについての記載があるのでこちらを参照してインストールします。

http://git-scm.com/download/win からインストーラを取得してインストール。

32bit版やportal editionもありますが今回はスタンダードに64bit版を選択。

以下は2.32.0のインストール時に選択できるパラメータメモ書き。

なおインストール時のパラメータはインストールしたディレクトリの\etc\install-options.txtに保存されている。
※sample C:\Program Files\Git\etc\install-options.txt

【インストールPARAM】Select Components

インストールするコンポーネントを選択。

Windowsエクスプローラの右クリックにメニュー追加

  • Windows Explorer integration->WindowGit Bash Here
  • Windows Explorer integration->Git GUI Here

Gitの拡張機能 Git LFS をインストール

  • Git LFS(Large File Support)

ファイル関連付け

.gitattributes .gitignore .gitmodules 等の.git*な拡張子で利用するファイル関連付けをデフォルトエディタに設定する。

.shGit Bashで実行できるように関連付けする。

  • Associate .git* configuration files with the default text editor
  • Associate .sh files to be run with Bash

【インストールパラメータ】Choosing the default editor used by Git

Gitでデフォルト利用するテキストエディタを指定する。 デフォルトはVimになっている。
Vim? みたいな人がこのままインストールすると操作する所でVimが出てくるとハマる気はする。

【インストールパラメータ】Adjusting the name of the initial branch in new repositories

Gitではリポジトリやブランチと呼ばれる存在があり。
デフォルトブランチはmasterという名称が利用されていましたが、[BLM]
(http://ja.wikipedia.org/w/index.php?curid=3746941)の流れもあり見直しが行われている。

Regarding Git and Branch Naming

2.32.0現在、将来への変更に向けてインストール時にデフォルトブランチ名を設定できるようなインストールオプションになっています。

【インストールパラメータ】Adjusting your PATH environment

Gitコマンドのインストール先を環境変数PATHに追加するかどうかを設定します。
今回はPowerShellから利用したいのでGit from the command line and also from 3rd-party softwareを選択。

これを選択すると、git.exeへのパスが環境変数PATHへ登録されます。

Use Git and optional Unix tools from the command promptについて。

GitGitコマンド以外にも色々とUnixToolsをインストールしますが、こちらのインストールオプションを選択すると。
これらのUnixToolsのインストール先もPATHを通します。

インストーラ記載にあるよう、C:\Windows\system32\find.exeC:\Windows\system32\sort.exe等が名前衝突起こすので利用する場合は適宜調整して下さい。

【インストールパラメータ】Choosing HTTPS transport backend

Gitでhttps接続する際に利用するライブラリの選択。

組織で証明証を利用して管理しているような場合はUse the native Windows Secure Channel libraryを選び証明証の設定をする。

【インストールパラメータ】Configuring the line ending conversions

改行コードの取り扱いについて。
LinuxWindowsだと改行コードの取り扱いが違うのでそれをどうするか。
この設定で。

  • チェックアウト実行時の変換(LFCRLFに変換)
  • コミット実行時の変換(CRLFLFに変換)

の有効無効を設定できる。

デフォルトパラメータはCheckout Windows-style, commit Unix-style line endingsですが、個人的な好みでここではCheckout as-is, commit as-isを選択。(チェックアウト、コミット時に変換なし)

ここは好みが分かれそうなところ。

下記ページ書式設定と空白文字の項目に記載があります。

8.1 Customizing Git - Git Configuration を参照

Checkout Windows-style,commit Unix-style line endings

  • チェックアウト時 LFCRLF に変換
  • コミット時 CRLFLF に変換
  • core.autocrlf true

Checkout as-is, commit Unix-style line endings

  • チェックアウト時 変換なし
  • コミット時 CRLFLF に変換
  • core.autocrlf input

Checkout as-is, commit as-is

  • チェックアウト時 変換なし
  • コミット時 変換なし
  • core.autocrlf false

【インストールパラメータ】Configuring the terminal emulator to use with Git Bash

Git Bashの端末エミュレータとしてminttyを利用するかcmd.exeを利用するか選択。

Git for Windows をインストールすると mintty も一緒にインストールされるがこれを利用するか、cmd.exeを利用するかの設定。

【インストールパラメータ】Choose the default behavior of git pull

git pull 実行時の動作を選択する。

ここらへんの設定による挙動を理解するには、そもそもgit pull
git configpull.rebase pull.ffを理解する必要がある。 デフォルトを選択。

git-pull
git config pull.rebase pull.ff

【インストールパラメータ】Choose a credential helper

GitGithubや各種サービスへ認証して接続する際に利用する認証情報ヘルパーを選択する。

GCM COREが過去の認証情報GCMヘルパーを置き換えるクラスプラットフォームな認証情報ヘルパーらしい。

Git-Credential-Manager-Core

【インストールパラメータ】Configuring extra options

Enable file system caching キャッシュを有効にする。

Enable symbolic links Windows環境のGitでもSymbolikLinkを取り扱う場合はチェックを入れる。

Symbolic Links

【インストールパラメータ】Configuring experimental options

実験的な機能を有効にする場合は利用して下さい。

PowerShellからGitを実行する

Git for Windowsをインストールすると、Git BashGit CMDGit GUIが追加されます。
これらを使ってGitをさわってみるものいいでのですが。

インストーラで3rd-party softwareから利用できるようにgit.exeにPATHを通す設定でインストールしているのでPowerShellからさわってみます。

インストールが完了したので初期設定を行います。progitの下記参照。

1.6 Getting Started - First-Time Git Setup

Gitにはgit configという環境の設定を編集するツールが付属しており、ここでは最低限設定しないとならない個人情報項目(ユーザー名とEmailアドレス)を設定します。

なおgit configにはsystem , global , local の三種類のスコープが存在します。
下記はglobalスコップにuser.nameuser.emailを設定している。

# グローバルスコープのユーザ名にjohn doeを設定
git config --global user.name "John Doe"
# グローバルスコープのemailアドレスにjohndoe@example.comを設定
git config --global user.email johndoe@example.com

この設定を実施していないと、コミット時にメッセージが表示されてコミットできない。

PowerShellからGitを利用する場合便利なモジュール

PowerShellGitを使う時に便利なモジュールとしてposh-gitoh-my-poshがあります。
ここではこの2つのモジュールについて説明します。

posh-gitについて

posh-gitのモジュールを利用するとPowerShellのコンソールにGitステータス表示やgitコマンドに入力補完が使えるようになります。

こんな感じでワークツリーのステータスが表示されたり。
posh-gitが表示している内容については下記に説明があります。

Git status summary information

git gitの後ろにスペー)と入力した状態でTABキーで入力補完されます。 もしくはCTRL-SPACE`で下記のような入力提案を利用できます。

インストールについては下記参照。

installation

installationについて要約すると下記が満たせれ入ればOKなはず。

  • Windows PowerShellPowerShell Coreがインストールされている事。
  • PowerShellのセキュリティーポリシーがRemoteSignedUnrestrictedになってること。
  • Git For Windowsがインストールされていて、PATHが通っている事。(git --versionとPowerShellでコマンド叩いてバージョンがでればOK)。

oh-my-poshについて

oh-my-poshPowerShellコンソールをいい感じにカスタマイズできるPowerShellモジュール
v2v3でだいぶ違いがあり、今現在はv3が現行版になります。

oh-my-posh v3についてはposh-gitのようにPowerShellプロンプトにgitステータスを表示する機能が備わっていたり。

oh-my-posh git

posh-gitと連携して、posh-gitの領域を表示したりできます。

oh-my-posh posh-git

以下はoh-my-poshposh-gitのgitステータスを両方表示してみた図。

左側のmaster ...部分oh-my-poshの表示
右側の[master +0 ~0 -0 !]posh-gitの表示

Posh-gitのインストール

# ポリシーの確認
# RemoteSigned/Unrestricted 以外だったらSet-ExecutionPolicyで設定する
Get-ExecutionPolicy

# 下記のような感じ
# Set-ExecutionPolicy RemoteSigned

# Install-Moduleコマンドでposh-gitモジュールをインストール
# ScopeをCurrentUserとすることでインストール先をユーザディレクトリ配下にする(管理者権限がいらない)
Install-Module posh-git -Scope CurrentUser

# インストールされたモジュールを確認
Get-Module -ListAvailable posh-git

上記、コマンドでインストール前のポリシー確認からインストール後の確認までできたかと思います。

posh-gitのインポート設定

posh-gitのモジュールが無事にインストールされたので、利用する前にImport-Moduleでインポートします。

Import-Module posh-git

インポートが有効となるのは現在開いているセッションのみとなるため。
PowerShellの起動時に毎度インポートコマンドを打つのも面倒です。

PowerShell起動時に実行されるプロファイルへ上記コマンドを追加すると毎度インポートコマンドを打たなくて良くなります。(その分、起動時間は多少遅くなる)
posh-gitではプロファイルに上記コマンドを追加するコマンドAdd-PoshGitToProfileが用意されています。

Add-PoshGitToProfileコマンドを実行すると、プロファイル中にImport-Module posh-gitの一文が追加されます。
(プロファイの格納場所は変数$profileから確認できる)

oh-my-posh v3のインストール

oh-my-poshについては、紹介だけで設定等には本記事では言及しません。
下記を参照して、インストール & カスタマイズして利用して下さい。

oh-my-posh のインストール

Gitコマンドを実行してみる from PowerShell

ここではPowerShellからGitを操作してみます。

Gitでは独特な用語と概念が出てきます。

用語

説明の中で下記の言葉が出てきますが、Gitではそういう物があるんだなという程度の理解でとりあえず大丈夫。
概念的な所と用語の関係が紐付かない状態でもとりあえずGitコマンドを実行して。
さわりながら、納得していくのが一番の近道になる気は個人的にします。

ブランチとかHEADとかポインタとかハードルがいきなり高いので、本記事ではここらへんさわりません。
(それでもGitは利用はできる)

  • ワーキングツリー
    • 作業しているディレクトリとファイル
  • リポジトリ
    • ワーキングツリーで行われた変更を記録する場所
  • インデックス(ステージング)
    • リポジトリに記録する前に一旦登録される領域。
  • コミット(動詞・名詞)
    • 【動詞】インデックス(ステージング)で管理されている(ワーキングツリー内で行われた変更)をリポジトリに記録する行為
    • 【名詞】リポジトリに変更を記録する際にGitはハッシュの取得、前回のコミットの宛先の取得、作成者の情報、日時等々をコミットオブジェクトとして保存する。
  • ブランチ
    • 変更履歴の流れを途中で枝分かれさせてそれぞれ個別に管理できる機能。
    • インストール時のAdjusting the name of the initial branch in new repositoriesで設定変更していなければデフォルトmasterという名前でブランチは作成される。
    • ブランチはコミットを指し示すポインタとして実装することにより、変更履歴の枝分かれを軽量に実装できていてGitのすごい部分らしい。
  • HEAD
    • HEADは現在作業しているブランチを指し示す特殊なポインタ。

コミット、ブランチ、HEADとかを説明しようとすると。
Gitのファイル管理方法にぶちあたってしまうので気になる人は下記参照。

3.1 Git Branching - Branches in a Nutshell

sample-gitというリポジトリを作成する(git init)

まずはc:\sample-git\というディレクトリを作成して、この作業ディレクトリをgit initコマンドを使いリポジトリとして設定します。

# ディレクトリの作成
mkdir c:\sample-git\
# sample-gitへ移動
cd C:\sample-git\
# git initコマンドでgitリポジトリの作成
git init
# ディレクトリの確認(.gitが隠しファイルなので-forceをつける)
ls -force

git initコマンドは、リポジトリの初期化を実行し、git管理を行うためのサブディレクトリ.gitが作成されます。

またPowerShellのプロンプト表示に[master] 表示されるようになりました。

これは先ほどインストールしたposh-gitの機能でワークツリーのステータスを表示してくれています。

ここでGitリポジトリとして構成されたsample-gitにファイルを追加してみます。

# Set-Contentコマンドレットでファイルを追加
Set-Content -Path .\helloworld.txt -Value "hello world"

ファイルを追加してみました、先ほどまで[master]と表示されていた部分が[master +1 ~0 -0 !]に変わるのを確認できたかと思います。(画像だとoh-my-poshのgit表示も有効になってるので紛らわしいですが赤枠の部分がposh-gitの表示になります)

image.png

これは現在はmasterというブランチで1個のファイルが追加された状態を表しています。

さらにもう1つfoobar.txtというファイルを追加してみます。

# Set-Contentコマンドでfoobar.txtファイルを追加
Set-Content -Path .\foobar.txt -Value "foo bar"

image.png

プロンプト表示が[master +1 ~0 -0 !]から[master +2 ~0 -0 !]に表示が変更となり赤文字表示で+2に増えました。

赤色数字についてはUntrakedなファイルを示しており、左から

  • + 追加されたファイルの数
  • ~ 変更されたファイルの数
  • - 削除されたファイルの数

を表しています。

sample-gitの現在のワークツリーの状態を確認する(git status)

git statusコマンドで現在のワークツリーの状態を確認してみます。

# ワークツリーの状態を確認
git status

image.png

ワークツリー中のファイルはUntrackedTrackedと呼ばれる状態が存在し、上記画像では作成したfoobar.txthelloworld.txtUntracked filesとして表示されています。

ワークツリー内のファイル状態については詳細を知りたい方は下記参照。

2.2 Recording Changes to the Repository

helloworld.txtをステージング(git add)

# helloworld.txtをステージング
git add helloworld.txt

# git statusで状態確認
git status

image.png

git addコマンドはファイルをステージングするコマンドとなり。
今回は2つ作成したファイルの内、helloworld.txtだけをステージングします。

ステージングされたファイルはChanges to be committed:にファイルが表示されるようになります。
またステージングする事により、Untrackedの状態からTrackedの状態に変化します。

プロンプト表示が[master +2 ~0 -0 !]から[master +1 ~0 -0 | +1 ~0 -0 !]に変更されました。

Git status summary information

posh-gitの説明を読むと、左側緑色で表示されているファイルはステージングされているファイルに関する情報を表示しており。
緑色で+1 ~0 -0はステージングされた新規作成ファイルが1つある事を表しており。
赤色で+1 ~0 -0はステージングされていないuntrackedが1つある事を表しています。

リポジトリに記録(git commit)

git commit -m 1stCommit

git commitコマンドで変更をリポジトリに記録します。

image.png

プロンプト表示が[master +1 ~0 -0 | +1 ~0 -0 !]から[master +1 ~0 -0 !]に変化しました。

これはコミットしたことにより、ステージング環境のファイル(helloworld.txt)がリポジトリに記録された事により緑色に表示が消えました。

なおgit commit-mパラメータで1stCommitというコミットメッセージを渡していますが、-mパラメータをつけないでgit commitを実行するとコミットメッセージを入力するために初期設定されているエディターであるVimが起動します。

image.png

Vimが起動して慌てる人は、まずVimの画面から抜けることが困難なので。

その場合は、ESCキーを押した後に、:q!と入力してENTERを押すとVimから抜けることができます。

コミットのログを確認する(git log)

# git logでコミットのログを表示する
git log --oneline

git logでコミットのログを表示できます。 onelineオプションを利用すると一行の簡潔な表示になります。

HEADがmasterブランチを指し示していて、今回のコミット1stCommitの短いハッシュが1c1a1b6になっていることがわかります。

helloworld.txtに行を追加して、再度コミットしてみる

Add-Contentコマンドレットでコミットしたhelloworld.txtに行を追加します。

# Add-Contentで変更
Add-Content -Path .\helloworld.txt -Value "add-helloworld"
# git statusでワーキングツリーの状態を確認
git status
# git diffで前回のコミットとワーキングツリーの差分を表示
git diff helloworld.txt

image.png

プロンプト表示が[master +1 ~0 -0 !]から[master +1 ~1 -0"]になりました。(赤色文字の数字なので、Untrackedな新規ファイルが1(foobar.txt),Untrackedな変更ファイル~1個という意味)

変更したhelloworld.txtgit addコマンドでステージングします。

# helloworld.txtをステージング
git add helloworld.txt

git addした段階でPosh-Gitのプロンプト表示が[master +0 ~1 -0 | +1 ~0 -0 !]に変更され、これはtrackedされた変更ファイルが1個。Untrackedな新規ファイルが1個。という表示になります。

image.png

変更したhelloworld.txtがステージングに登録されたので、2度目のコミットを実施してみます。

git commit -m 2ndCommit
# git logでコミットのログを表示
git log --oneline

プロンプトの表示が[master +0 ~1 -0 | +1 ~0 -0 !]から[master +1 ~0 -0 !]に変化しました。
これは前回と同じくコミットしたことにより、ステージング環境のファイル(helloworld.txt)がリポジトリに記録された緑色に表示が消えました。

git logでコミット履歴を表示すると1stCommtと2ndCommitの2つが表示されます。

image.png

1stCommit時のファイルの状態に戻す

Gitではコミットをスナップショットとして記録しており、そのスナップショットからファイルを戻すことができます。

2ndCommit現在ではhelloworld.txtが2行の状態となっていますが、これを1stCommitに差し戻してみます。

# 1stCommitのハッシュを確認
git log --oneline
# git reset --hardで作業ツリーを1stCommitの状態に戻す
git reset --hard <<1stCommitのハッシュ>>
# コミットの状態を確認
git log --oneline
# ファイル内容の確認
gc .\helloworld.txt

image.png

上記ではreset --hard1stCommitのハッシュを指定して戻しています。
なお、差し戻す手法については色々と方法があり下記のような方法でも差し戻すことはできます。

# 1stCommitのハッシュを確認
git log --oneline
# git resetでHEADを1stCommitに向ける
git reset <<1stCommitのハッシュ>> helloworld.txt
# git checkoutで
git checkout -- helloworld.txt
# ファイル内容の確認
gc .\helloworld.txt

image.png

やりたいことはファイルを戻すことだけですが、他にもgit revertを利用したり、他の書き方があったり様々な方法で過去の状態に立ち戻ったりできます。

Git操作全般に言えることですが、やりたいことを実現する手法は多種多様あってよく混乱する気がします。

とりあえずGitを操作してみたが何がよいのか?

ここまで操作してみて、なんのためにこんなことをしているの? といった感じかと思います。

Gitは様々なコミットが発生したとしても、うまいこと調整して管理できる仕組みになっていて。
開発時に起こる煩雑なバージョン管理の問題を解決します。

コミットの粒度だったり、ブランチの切り方だったり、マージの仕方だったり。

Gitによる開発の管理手法はいろいろな流儀、考え方があるのでそれぞれGitの操作とは別に学んでいく必要はありますが。

有名な手法の一例としては A successful Git branching modelなどがあります。

おまけ

git pushコマンドを実行するサンプルはおまけとして紹介しておきます。

githubサービス等にリモートリポジトリを作り、そこからcloneしてpushするまでをやってもいいのですが。
ローカルの端末だけでやりたかったので、下記を実施しています。

  • c:\temp\remote.helloworld.gitにリモートリポジトリを作成
  • 上記リモートリポジトリをc:\temp\local.helloworldにclone
  • ローカルリポジトリに、ファイルhelloworld.txtを追加してcommit
  • ローカルリポジトリからリモートリポジトリにpush
# ディレクトリ作成
mkdir c:\temp\remote.helloworld.git
# bareオプションをつけてベアリポジトリを作成
git init --bare c:\temp\remote.helloworld.git
# リモートリポジトリ(remote.helloworld.git)をローカルリポジトリ(local.helloworld)にコピー
git clone c:\temp\remote.helloworld.git c:\temp\local.helloworld
# 新規ファイル作成(hellworld.txt)
Set-Content -Path c:\temp\local.helloworld\helloworld.txt -Value "hello world"
# カレントディレクトリをlocal.helloworldに移動
cd c:\temp\local.helloworld\
# helloworld.txtをローカルリポジトリでステージング
git add helloworld.txt
# ステージングされたファイルをコミット
git commit -m add:hellworld.txt
# リモートリポジトリにpush(git cloneで作成したのでリモートリポジトリの情報は登録済み)
git push
# カレントディレクトリをリモートリポジトリに移動(ベアリポジトリなのでファイルはなし)
cd c:\temp\remote.helloworld.git
# git logでコミットが反映されているのを確認
git log --oneline

総評

コマンドの動き方や概念がなかなか難しいものがあります。(そもそもバージョン管理が煩雑で難しい)

Gitには多種多様のサブコマンドが用意されており。やりたいことがあったとして、それを実現するためには様々なコマンドを組み合わせて実現できますが。

ちょっと込み入った操作をやりたいときに、なかなかハードルは高いようには思います。

概念からして難しいし、やれることが多すぎるし、用語もよくわらかないし……

それでも基本的な所から少しずつコマンドを実行して利用するだけでもだいぶ便利。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2