Windows
環境でGit
を使い始める時に自分だったらこういうことを知りたかったかな? ってことのまとめ。
Windows
でPowerShell
からGit
コマンドを実行する時のあれこれについて初級編。
Git For Windowsって?
そもそもGit
とはなんぞや?
Git
はLinux
の生みの親として有名なLinusさんが2005年にLinux
のソース管理のために生み出した分散バージョン管理システム。
Linux
のソース管理でGit
が必要になった背景等は Gitの10年間: Gitの生みの親 Linus Torvalds のインタビューに日本語記事があったけどリンク切れ。
InternetArchiveに残ってるのは こちら
また原文はこちら10 Years of Git: An Interview with Git Creator Linus Torvalds
Linux
のための生み出された分散バージョン管理システムと聞くと。
大規模 だったり 複数人が共同で開発を行う場合に利用するのかな? といった印象を受けますが。
Windows
でひとり開発を行う際にも力を発揮する強力なツールになります。
昔はWindows
でGit
を利用するにあたって色々あったようですが。
現在はGit For Windows
で提供されるインストーラを実行すれば手軽に利用ができるようになります。
※Git
の一部はシェルスクリプトで実装されており、Git for Windows
はMSYS2
を介してシェルスクリプトを実行していたりするので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
からも操作をする事ができます。
本資料ではGit
をCUI(PowerShell)
から実行しています。
なおGUIクライアント
については下記ページにて各種紹介されています。
ドキュメントやらなんやら
- Git
- Git - Documentation
- Git for Windows
- Git for Windows FAQ
- Pro Git
- Microsoft Learn - Git でのバージョン コントロールの概要
Microsoft Learn
で提供されているGit
の講座はなかなかわかりやすくていいかと思います。
video
- LearnWithDrG/WYDLIS_Videos
- Intro To Git: Learn the foundations of Git and version control | Learn with Dr. G
- Introduction to Git Recap | Learn with Dr G
- Collaborate with Git: Keeping your Source Code Error Free| Learn with Dr. G
- Git and Remote Syncing | Learn with Dr G
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*な拡張子で利用するファイル関連付けをデフォルトエディタに設定する。
.sh
をGit 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
について。
Git
はGit
コマンド以外にも色々とUnixTools
をインストールしますが、こちらのインストールオプションを選択すると。
これらのUnixTools
のインストール先もPATHを通します。
インストーラ記載にあるよう、C:\Windows\system32\find.exe
、C:\Windows\system32\sort.exe
等が名前衝突起こすので利用する場合は適宜調整して下さい。
【インストールパラメータ】Choosing HTTPS transport backend
Git
でhttps接続する際に利用するライブラリの選択。
組織で証明証を利用して管理しているような場合はUse the native Windows Secure Channel library
を選び証明証の設定をする。
【インストールパラメータ】Configuring the line ending conversions
改行コードの取り扱いについて。
Linux
とWindows
だと改行コードの取り扱いが違うのでそれをどうするか。
この設定で。
- チェックアウト実行時の変換(
LF
をCRLF
に変換) - コミット実行時の変換(
CRLF
をLF
に変換)
の有効無効を設定できる。
デフォルトパラメータは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
- チェックアウト時
LF
をCRLF
に変換 - コミット時
CRLF
をLF
に変換 - core.autocrlf true
Checkout as-is, commit Unix-style line endings
- チェックアウト時
変換なし
- コミット時
CRLF
をLF
に変換 - 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 config
のpull.rebase
pull.ff
を理解する必要がある。 デフォルトを選択。
git-pull
git config pull.rebase pull.ff
【インストールパラメータ】Choose a credential helper
Git
がGithub
や各種サービスへ認証して接続する際に利用する認証情報ヘルパーを選択する。
GCM CORE
が過去の認証情報GCMヘルパーを置き換えるクラスプラットフォームな認証情報ヘルパーらしい。
【インストールパラメータ】Configuring extra options
Enable file system caching
キャッシュを有効にする。
Enable symbolic links
Windows環境のGit
でもSymbolikLink
を取り扱う場合はチェックを入れる。
【インストールパラメータ】Configuring experimental options
実験的な機能を有効にする場合は利用して下さい。
PowerShellからGitを実行する
Git for Windows
をインストールすると、Git Bash
、Git CMD
、Git 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.name
とuser.email
を設定している。
# グローバルスコープのユーザ名にjohn doeを設定
git config --global user.name "John Doe"
# グローバルスコープのemailアドレスにjohndoe@example.comを設定
git config --global user.email johndoe@example.com
この設定を実施していないと、コミット時にメッセージが表示されてコミットできない。
PowerShellからGitを利用する場合便利なモジュール
PowerShell
でGit
を使う時に便利なモジュールとしてposh-git
とoh-my-posh
があります。
ここではこの2つのモジュールについて説明します。
posh-gitについて
posh-git
のモジュールを利用するとPowerShell
のコンソールにGit
ステータス表示やgit
コマンドに入力補完が使えるようになります。
こんな感じでワークツリーのステータスが表示されたり。
※posh-git
が表示している内容については下記に説明があります。
Git status summary information
git
(git
の後ろにスペー)と入力した状態で
TABキーで入力補完されます。 もしくは
CTRL-SPACE`で下記のような入力提案を利用できます。
インストールについては下記参照。
installationについて要約すると下記が満たせれ入ればOKなはず。
-
Windows PowerShell
かPowerShell Core
がインストールされている事。 -
PowerShell
のセキュリティーポリシーがRemoteSigned
かUnrestricted
になってること。 -
Git For Windows
がインストールされていて、PATH
が通っている事。(git --version
とPowerShellでコマンド叩いてバージョンがでればOK)。
oh-my-poshについて
oh-my-posh
はPowerShell
コンソールをいい感じにカスタマイズできるPowerShellモジュール
。
v2
とv3
でだいぶ違いがあり、今現在はv3
が現行版になります。
oh-my-posh
v3についてはposh-git
のようにPowerShell
プロンプトにgit
ステータスを表示する機能が備わっていたり。
posh-git
と連携して、posh-git
の領域を表示したりできます。
以下はoh-my-posh
とposh-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
については、紹介だけで設定等には本記事では言及しません。
下記を参照して、インストール & カスタマイズして利用して下さい。
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の表示になります)
これは現在はmaster
というブランチで1個のファイルが追加された状態を表しています。
さらにもう1つfoobar.txt
というファイルを追加してみます。
# Set-Contentコマンドでfoobar.txtファイルを追加
Set-Content -Path .\foobar.txt -Value "foo bar"
プロンプト表示が[master +1 ~0 -0 !]
から[master +2 ~0 -0 !]
に表示が変更となり赤文字表示で+2に増えました。
赤色数字についてはUntraked
なファイルを示しており、左から
+ 追加されたファイルの数
~ 変更されたファイルの数
- 削除されたファイルの数
を表しています。
sample-gitの現在のワークツリーの状態を確認する(git status)
git status
コマンドで現在のワークツリーの状態を確認してみます。
# ワークツリーの状態を確認
git status
ワークツリー中のファイルはUntracked
とTracked
と呼ばれる状態が存在し、上記画像では作成したfoobar.txt
とhelloworld.txt
がUntracked files
として表示されています。
ワークツリー内のファイル状態については詳細を知りたい方は下記参照。
2.2 Recording Changes to the Repository
helloworld.txtをステージング(git add)
# helloworld.txtをステージング
git add helloworld.txt
# git statusで状態確認
git status
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
コマンドで変更をリポジトリに記録します。
プロンプト表示が[master +1 ~0 -0 | +1 ~0 -0 !]
から[master +1 ~0 -0 !]
に変化しました。
これはコミットしたことにより、ステージング環境のファイル(helloworld.txt)がリポジトリに記録された事により緑色に表示が消えました。
なおgit commit
に-m
パラメータで1stCommit
というコミットメッセージを渡していますが、-m
パラメータをつけないでgit commit
を実行するとコミットメッセージを入力するために初期設定されているエディターであるVim
が起動します。
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
プロンプト表示が[master +1 ~0 -0 !]
から[master +1 ~1 -0"]
になりました。(赤色文字の数字なので、Untrackedな新規ファイルが1(foobar.txt),Untrackedな変更ファイル~1個という意味)
変更したhelloworld.txt
をgit add
コマンドでステージングします。
# helloworld.txtをステージング
git add helloworld.txt
git add
した段階でPosh-Git
のプロンプト表示が[master +0 ~1 -0 | +1 ~0 -0 !]
に変更され、これはtracked
された変更ファイルが1個。Untracked
な新規ファイルが1個。という表示になります。
変更した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つが表示されます。
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
上記ではreset --hard
に1stCommit
のハッシュを指定して戻しています。
なお、差し戻す手法については色々と方法があり下記のような方法でも差し戻すことはできます。
# 1stCommitのハッシュを確認
git log --oneline
# git resetでHEADを1stCommitに向ける
git reset <<1stCommitのハッシュ>> helloworld.txt
# git checkoutで
git checkout -- helloworld.txt
# ファイル内容の確認
gc .\helloworld.txt
やりたいことはファイルを戻すことだけですが、他にも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
には多種多様のサブコマンドが用意されており。やりたいことがあったとして、それを実現するためには様々なコマンド
を組み合わせて実現できますが。
ちょっと込み入った操作をやりたいときに、なかなかハードルは高いようには思います。
概念からして難しいし、やれることが多すぎるし、用語もよくわらかないし……
それでも基本的な所から少しずつコマンドを実行して利用するだけでもだいぶ便利。