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

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

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

## Git For Windowsって？

そもそも`Git`とはなんぞや？

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

`Linux`のソース管理で`Git`が必要になった背景等は [Gitの10年間: Gitの生みの親 Linus Torvalds のインタビュー](https://jp.linux.com/news/linuxcom-exclusive/428524-lco2015041401)に日本語記事があったけどリンク切れ。

InternetArchiveに残ってるのは　[こちら](https://web.archive.org/web/20190502034447/https://jp.linux.com/news/linuxcom-exclusive/428524-lco2015041401)

また原文はこちら[10 Years of Git: An Interview with Git Creator Linus Torvalds](https://www.linux.com/news/10-years-git-interview-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](https://github.com/msysgit/msysgit/wiki)　に記載が少しあります。

## CUI or GUI

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

本資料では`Git`を`CUI(PowerShell)`から実行しています。

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

- [GUI Clients](https://git-scm.com/downloads/guis)

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

- [Git](https://git-scm.com/)
- [Git - Documentation](https://git-scm.com/doc)
- [Git for Windows](https://gitforwindows.org/)
- [Git for Windows FAQ](https://github.com/git-for-windows/git/wiki/FAQ)
- [Pro Git](https://git-scm.com/book)
- [Microsoft Learn - Git でのバージョン コントロールの概要](https://docs.microsoft.com/ja-jp/learn/paths/intro-to-vc-git/)

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

### video

- [LearnWithDrG/WYDLIS_Videos](http://aka.ms/LearnWithDrG/WYDLIS_Videos)
- [Intro To Git: Learn the foundations of Git and version control | Learn with Dr. G](https://www.youtube.com/watch?v=dnDHVbO7ycM&list=PLjoGSbuzyErh7ffELeKxeCtgIBK1n1q9A&index=3&t=1524s)
- [Introduction to Git Recap | Learn with Dr G](https://www.youtube.com/watch?v=9uGS1ak_FGg)
- [Collaborate with Git: Keeping your Source Code Error Free| Learn with Dr. G](https://www.youtube.com/watch?v=-CDSGioxy6w&list=PLjoGSbuzyErh7ffELeKxeCtgIBK1n1q9A&index=5)
- [Git and Remote Syncing | Learn with Dr G](https://www.youtube.com/watch?v=wuPE__7Yr4k&list=PLjoGSbuzyErh7ffELeKxeCtgIBK1n1q9A&index=6)

### Pro Git

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

この書籍は [Creative Commons Attribution-NonCommercial-ShareAlike 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/)にてライセンスされておりGit公式サイトでもオンラインで参照でき、また有志によって各言語に翻訳されています。

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

- [Pro Git 日本語版電子書籍公開サイト](https://progit-ja.github.io/)
- [progit/progit2-ja](https://github.com/progit/progit2-ja)

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

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

## Git For Windowsのインストール

- [1.5 Getting Started - Installing Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)

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

[http://git-scm.com/download/win](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

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/5e44cde4-a6b8-145b-8834-7d968b720f81.png)

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

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

#### Gitの拡張機能 [Git LFS](https://git-lfs.github.com/) をインストール

- 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が出てくるとハマる気はする。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/2e1a8ee5-3f28-0de0-9a4e-c6c803644175.png)

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/188247e6-2d4b-2f17-68ce-211515b06f58.png)

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

[Regarding Git and Branch Naming](https://sfconservancy.org/news/2020/jun/23/gitbranchname/)

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

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/50854f1f-0299-1b5e-56df-95b50f2fb72f.png)

`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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/1bab8904-b706-3018-631e-b11e1edfff83.png)

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

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

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/827793c7-fd81-aa2d-d771-ce2765034289.png)

改行コードの取り扱いについて。
`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](https://git-scm.com/book/en/v2/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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/71a2d17e-b8f4-1618-9b58-4bc98ab44174.png)

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

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

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/2f55d62c-02de-e7a6-1304-7915aad39b20.png)

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

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

[git-pull](https://git-scm.com/docs/git-pull)
[git config pull.rebase pull.ff](https://git-scm.com/docs/git-config)

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/7f545e8c-7496-20ca-e3d9-a0bcaae60bdf.png)

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

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

[Git-Credential-Manager-Core](https://github.com/microsoft/Git-Credential-Manager-Core/blob/main/docs/faq.md#about-the-project)

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/d275daab-e9d6-7353-d090-46143e0c186c.png)

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

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

[Symbolic Links](https://github.com/git-for-windows/git/wiki/Symbolic-Links)

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/ee046b9e-c534-108a-d172-1941f1ffee68.png)

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

## 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](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup)

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

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

```PowerShell
# グローバルスコープのユーザ名に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`があります。
ここではこの２つのモジュールについて説明します。

### posh-gitについて

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

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

[Git status summary information](https://github.com/dahlbyk/posh-git/blob/master/README.md#git-status-summary-information)


![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/9bba625b-cfcb-918c-cc47-bd8ee494992d.png)

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/ee110404-78bb-c5f3-c005-c06a1aa95298.png)

- [posh-git](https://www.powershellgallery.com/packages/posh-git/)
- [dahlbyk/posh-git](https://github.com/dahlbyk/posh-git)

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

[installation](https://github.com/dahlbyk/posh-git#installation)

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`ステータスを表示する機能が備わっていたり。

[oh-my-posh git](https://ohmyposh.dev/docs/git)

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

[oh-my-posh posh-git](https://ohmyposh.dev/docs/poshgit)

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

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/6c45b3f2-d7e5-fae5-4caf-deafb2ff523d.png)

### Posh-gitのインストール

```PowerShell
# ポリシーの確認
# 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`でインポートします。

```PowerShell
Import-Module posh-git
```

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

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/c9371019-80f5-d635-acf1-be52c6829a30.png)

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

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

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

[oh-my-posh のインストール](https://ohmyposh.dev/docs/pwsh)

## 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](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell)

### sample-gitというリポジトリを作成する（git init）

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

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/3252bb29-52c0-b836-23bb-a68c95c97f2a.png)


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

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

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

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

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/406e61be-eeef-ee2d-6684-1987b5bc04d5.png)

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

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/1842b600-eefe-ef4f-bdf0-c483aca76c54.png)

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

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

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

を表しています。

#### sample-gitの現在のワークツリーの状態を確認する（git status）

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/17c79548-a573-8f5f-3d55-c07c49543e06.png)

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

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

[2.2 Recording Changes to the Repository](https://git-scm.com/book/en/v2/Git-Basics-Recording-Changes-to-the-Repository)

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

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

# git statusで状態確認
git status
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/eed672e6-7475-ec05-a519-69a397b68ade.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](https://github.com/dahlbyk/posh-git/blob/master/README.md#git-status-summary-information)

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

#### リポジトリに記録（git commit）

```PowerShell
git commit -m 1stCommit
```

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/74853907-6b78-b7a1-07ac-487a10c05877.png)

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

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/d3de0b54-c649-8c21-84ee-7c94fd4048b8.png)

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

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

#### コミットのログを確認する（git log）

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

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

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/b208381f-089c-d556-a8c7-57c7054ff511.png)

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

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

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

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

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/719dc4c8-30ec-e45d-d7ac-bdf441ab5c05.png)

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

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

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/2f972e48-b019-c8ef-dd8a-feb1f4775a1a.png)

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

```powerhsell
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/c31dc14c-5493-ce3d-7f47-04e77114e12c.png)

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

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

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/7559a535-35b4-1822-1d0f-3982ec6a8448.png)

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

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1670622/d284822e-b789-bf41-5656-579f9a8edcb6.png)

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

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

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

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

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

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

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

有名な手法の一例としては [A successful Git branching model](https://nvie.com/posts/a-successful-git-branching-model/)などがあります。

## おまけ

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

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

- `c:\temp\remote.helloworld.git`にリモートリポジトリを作成
- 上記リモートリポジトリを`c:\temp\local.helloworld`にclone
- ローカルリポジトリに、ファイル`helloworld.txt`を追加してcommit
- ローカルリポジトリからリモートリポジトリにpush

```PowerShell
# ディレクトリ作成
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`には多種多様のサブコマンドが用意されており。やりたいことがあったとして、それを実現するためには様々な`コマンド`を組み合わせて実現できますが。

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

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

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