lazygitチートシート[ターミナル(TUI)でgitをキーボードで操作して快適なgitライフを送ろう！]

皆さんはgit操作どのように行っていますか？
- GUIアプリ
    - githubdesktop 
    - SourceTree
    - VSCode/JetbrainsIDEの内蔵機能
- CLI(ターミナル等でコマンド直打ち)
    - git add 
    - git commit
    - git push
    - git reflog などなど

本記事はgitをCUI環境でGUIっぽく操作するというTUIアプリケーションに属する**lazygit**の使い方をまとめて説明する．

SourceTree(GUIソフト)を使ってgit操作したい方はこちらから

https://qiita.com/JavaLangRuntimeException/items/9a1eca7c5c84357b06bf#%E5%AE%9F%E9%9A%9B%E3%81%AB%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B

# 他のチートシート
git/gh コマンド(gitコマンド以外にもgitの概念も書いてあります)

https://qiita.com/JavaLangRuntimeException/items/6b46551f56e0def76eba

> 今回は特にgitのことを扱うのでこの記事の内容がわかること前提で話します．add commit pushなど基本的なコマンド以外にもlazygitはreflogなど普段あまり使わないコマンドも出てくるので，一読しておくことをお勧めします．

Docker コマンド

https://qiita.com/JavaLangRuntimeException/items/21f7c7bf3d143f821697

ステータスコード

https://qiita.com/JavaLangRuntimeException/items/ab1bc7b976ed2dfad91c

TypeScript

https://qiita.com/JavaLangRuntimeException/items/5894391c08e0d8e28389

SQL

https://qiita.com/JavaLangRuntimeException/items/f038fbaccdd92fb0308a

Go/Gorm

https://qiita.com/JavaLangRuntimeException/items/d388717fc1436bc3ec9d

testing/gomock

https://qiita.com/JavaLangRuntimeException/items/bf521190f6f4d79e59fb

C#/.NET/Unity

https://qiita.com/JavaLangRuntimeException/items/7849b32bc223d4aa0247

Ruby・Ruby on Rails

https://qiita.com/JavaLangRuntimeException/items/42d935cf92c212f1c7ec

Vim

https://qiita.com/JavaLangRuntimeException/items/0c68ab96ea198e0a7294

プルリクエスト・マークダウン記法チートシート

https://qiita.com/JavaLangRuntimeException/items/329eb92a47a07ff4dde8

ファイル操作コマンドチートシート

https://qiita.com/JavaLangRuntimeException/items/16f244606a73f7d106e4

VSCode Github Copilot拡張機能

https://qiita.com/JavaLangRuntimeException/items/be13dc3a346cf6e5ee44

OpenAI Assistants API

https://qiita.com/JavaLangRuntimeException/items/1a1abc01e8d7d05dce93

Github API

https://qiita.com/JavaLangRuntimeException/items/4f3551c31679233219ac

変数・関数(メソッド)・クラス命名規則

https://qiita.com/JavaLangRuntimeException/items/b93865c448f69bcfca4a

# 他のシリーズ記事
**TypeScriptで学ぶプログラミングの世界**
プログラミング言語を根本的に理解するシリーズです．

https://qiita.com/JavaLangRuntimeException/items/cadf49bb419076819963

**情報処理技術者試験合格への道[IP・SG・FE・AP]**
情報処理技術者試験に出題されるコンピュータサイエンス用語の紹介や単語集

https://qiita.com/JavaLangRuntimeException/items/991be402099542ccb936

**IAM AWS User クラウドサービスをフル活用しよう！**
AWSのサービスを例にしてバックエンドとインフラ開発の手法を説明するシリーズです．

https://qiita.com/JavaLangRuntimeException/items/371a334f5a6e07035db5

**AWS UserのGCP浮気日記**
GCPの様子をAWSと比較して考えてみるシリーズ

https://qiita.com/JavaLangRuntimeException/items/527d99e774165a763180

**Project Gopher: Unlocking Go’s Secrets**
Go言語や標準ライブラリの深掘り調査レポートです．

https://qiita.com/JavaLangRuntimeException/items/dc45b412d3fbd2ccb9e8

**Gopher’s Journey: Exploring TCP Protocol**
Goを用いてTCPプロトコルを探求 & 作成するシリーズです．

https://qiita.com/JavaLangRuntimeException/items/38091220106d86651d2b

# TUIとは？CUI/GUIとはどう違うの？
:::note info
**TUI（Text-based User Interface）とは**
テキストベースのユーザーインターフェースの一種である．CUI（Character User Interface）やCLI（Command Line Interface）の発展形として位置づけられ，テキストモードでありながら，GUI(Graphical User Interface)な要素を取り入れたインターフェースを提供する．
:::

TUIの主な特徴は，テキスト文字を使用して画面上に疑似的なグラフィカル要素を表現することにある．例えば，ボックス，枠線，メニュー，ボタンなどをASCII文字や拡張文字セットを用いて描画する．これにより，純粋なテキストベースのインターフェースよりも視覚的に構造化された情報表示が可能となる．また，キーボード操作を主体としつつ、カーソルやハイライトなどを用いて，インタラクティブな操作感を提供する．ユーザーは矢印キーやタブキーでメニュー項目間を移動したり，エンターキーで選択を確定したりすることができる．今回のlazygitとlazydockerはVimのキー操作ができるので，Vimをよく使う人も使いやすい仕様になっている．([Vimの使い方はこちらから(Vimチートシート)](https://qiita.com/JavaLangRuntimeException/items/0c68ab96ea198e0a7294))

TUIの利点としては，GUIに比べて軽量であり，リソースの少ない環境や，リモートサーバーへのSSH接続時などでも快適に動作する点が挙げられる．また，キーボード操作が主体であるため，熟練ユーザーにとっては非常に効率的な操作が可能となる．

:::note info
**代表的なTUIアプリケーション**
テキストエディタのVimやEmacs，ファイルマネージャーのMidnight Commander，そして先述のlazygitなどがある．
:::

# lazygitインストール方法
## lazygit
**Windows**
- Scoop を使ったインストール
```powershell
scoop install lazygit
```
- Chocolatey を使ったインストール
```powershell
choco install lazygit
```
**macOS**
Homebrew を使ったインストール
```bash 
brew install lazygit
```
:::note info
**コマンドでインストールできない場合**
- **手動インストール**
GitHubのリリースページから最新のそれぞれのOS用のバイナリをダウンロードし，PATHの通ったディレクトリに配置する
- **Go言語がインストールされている環境**
```bash
go install github.com/jesseduffield/lazygit@latest
```
:::

インストール後は、ターミナルまたはコマンドプロンプトで**対象のディレクトリ**で以下のコマンドをと入力して実行すれば良い．
**lazygitの場合**
```bash
lazygit
```

# 前提状態
本記事で使用するgitリポジトリの構成は以下のファイル構成で説明する．
```
.
└── README.md
```
masterブランチでREADME.mdを作成し，そこからdevelopブランチを作成し，developブランチからfeature/001ブランチと，feature/002ブランチを作成した状態で説明する．

# lazygit開始方法
対象のディレクトリで以下のコマンドを実行するとlazygitを始めることができる．
```bash
lazygit
```
終了するには，
`q`キー

開始したら以下の画面になっている．

![スクリーンショット 2024-09-29 23.40.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/feba06d6-6b8a-07f9-bcea-1c409752d7c7.png)

上下左右の移動はvim操作でも矢印キーでもOK
1つ戻る際は`esc`キー
決定は`return`キー
実行は`space`キーが基本操作

# モード切り替え
`1`, `2`, `3`, `4`, `5`を押してモードを切り替える．マウスクリックでも切り替えができる．
また，各モードにおいてコマンドのヘルプを出すには`?`を押すと確認できる．
![スクリーンショット 2024-10-01 11.38.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/5c0673f5-b174-6994-2129-1980828c8e1f.png)

> ヘルプのコマンドを選択して`return`を押すと


## gitリポジトリ・作業ブランチの確認・操作履歴とコミット履歴の確認
`1`を押すと現在のgitリポジトリと現在のブランチを確認できる．

![スクリーンショット 2024-09-29 23.40.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/feba06d6-6b8a-07f9-bcea-1c409752d7c7.png)

このモードで`a`を押すと操作履歴とコミット履歴を確認できる．(**git log --oneline --graph --all**)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/b9c1ff40-2701-7c9c-21d1-a38364252c9d.png)


## 変更差分(git status)・ワークツリー・サブモジュールの表示
`2`を押すと現在の変更差分を表示する(**git status**)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/499ce62e-31dc-4818-661e-868c929e35bf.png)

差分を作ると以下のようになる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/90cbc99e-f698-bd22-d0f2-8bd72367e948.png)

もう一度`2`を押すとワークツリーの情報が出てくる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/29177646-ca50-d34f-6282-28f3efd4e67a.png)

さらにもう一度`2`を押すとサブモジュールの情報が出てくる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/9d62e241-3cd0-62e6-7749-4c912b77b8b0.png)

:::note info
**`2`を押した時の挙動**
変更差分→ワークツリー→サブモジュール
:::

## ローカル・リモートブランチ(git branch (-a))・変更履歴(git log)・リモートリポジトリのURL(git remote -v)・タグ(git tag)の表示
`3`を押すとローカルブランチを表示する(**git branch**)
選択中のブランチにおける変更履歴も表示する(**git log**)
![スクリーンショット 2024-09-30 9.23.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/1ed28b2b-8308-1bc9-78fa-78d311b1decd.png)

もう一度`3`を押すとリモートブランチを表示する(**git branch -a**)
リモートリポジトリのURLも表示する(**git remote -v**)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/4d49c132-8712-1976-f67b-9a125d3f8cbf.png)

対象のリモートブランチ名(origin)を選択し，`return`を押すとリモートブランチが表示される．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/e62dcf08-0aea-9ffd-c8d4-7e9598f2e4cb.png)

> 緑色になっているブランチがローカルにないブランチ

`3`を押し，tagsのページまで行くと，とタグが表示される(git tag)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/e18e60e8-1136-ac86-1e0b-54c9e3247a87.png)

:::note info
**`3`を押した時の挙動**
ローカルブランチ・変更履歴→リモートブランチ・リモートリポジトリのURL→タグ
:::

## コミット履歴・詳細差分(git show)・操作履歴(git reflog)の表示
`4`を押すとコミット履歴を表示する．(**git log --pretty=format:"%h %s" --graph**)
選択中のコミットにおける詳細差分も表示する(**git show**)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/52253cb1-0a70-8bce-9cc6-9e7e98f0b5c4.png)

もう一度`4`を押すとローカルリポジトリにおける操作履歴を表示できる(**git reflog**)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/1b240c88-c534-22c2-93de-ceef68e0d925.png)

:::note info
**`4`を押した時の挙動**
コミット履歴・詳細差分→操作履歴
:::

## 変更差分の待避(git stash list)の表示
`5`を押すと変更差分を一時退避したものを一覧表示する(**git stash list**)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/ce7cd39c-145a-274a-255f-4077b95e9089.png)


# ファイルをステージング(git add)・ファイルのステージングを解除(git restore --staged)
`2`を押してFilesのページに移動．ステージングしたいファイルを選択し，`space`を押す(**git add**)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/fa0b12d2-89c2-4e64-2b9a-6686760e2b1b.png)


ファイル名が緑色になったらステージングしている証拠

![スクリーンショット 2024-09-30 11.38.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/629302a2-0973-4ce0-67a9-361bce62361b.png)


ステージングしているファイルを選択し，`space`を押すとステージング解除

![スクリーンショット 2024-09-30 11.39.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/9b9435a0-20d9-baa5-47ac-723338fb7349.png)

**その他 add restore --staged操作**
- 全てのファイルをステージングしたい場合は`a`を押す．(**git add .**)

- 全てのファイルのステージングを取り消したい場合は全てのファイルをステージングした状態で`a`を押す．(**git restore --staged .**)


# コミットする(git commit)
addした後に`c`を押したら，コミットメッセージを入力できる．入力後`return`を押したらステージングしたファイルをコミットする．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/7b13d4f5-c02c-d367-a95e-2483ceaca98b.png)

4のcommitsにコミット履歴が追加される．pushしていないコミットは赤色になっている．また1のstatusに↑1がつき，リモートリポジトリと比較して1コミット先行していることがわかる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/aa66b012-d033-1a42-d32f-245812a0bdd9.png)

## 1つ前のコミットを編集する(git commit --amend)
addした後に`A(大文字)`を押すと1つ前のコミットにファイルを追加できる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/6811c88f-e79e-6788-579d-f8a1c97ebc4c.png)



# ローカルブランチでのリセット(git reset)
2のfilesで`g`を押すとローカルブランチを上流ブランチ（通常はリモートブランチ）の状態にリセットする(**git reset @{upstream}**)

> --soft --mixed --hardのオプションも選択できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/16a79853-0c2f-1660-6b47-6c8061dc5da4.png)

3のLocal branches(またはremote branches)で`g`を押すと現在のブランチを選択したブランチの状態にリセットする．(**git reset [branchname]**)
![スクリーンショット 2024-09-30 12.28.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/0cf68cd9-fadd-408d-1290-d8ab7640f52b.png)

4のcommitsで`g`を押すと選択したコミットまでリセットする．(**git reset [commithash]**)
![スクリーンショット 2024-09-30 12.32.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/1cca5cea-9c2b-980a-4413-eb3c9b1c00f3.png)

# ローカルブランチを作成し，切り替える(git checkout -b)
3のLocal branchesで`n`を押し，ブランチ名を入力し`return`を押すとローカルブランチを作成し，切り替える操作ができる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/6b6acb59-ee27-1bfd-9947-e297c2cb2362.png)

# ローカルブランチの切り替え(git checkout)
3のLocal branchesで切り替え先のブランチを選択し，`space`でブランチを切り替える．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/df8a0862-cf01-4411-e67c-d269cac03ecd.png)

# ローカルブランチの削除(git branch -d)
3のLocal branchesで削除したいブランチを選択し，`d`を押し，一番上のDelete local branchを選択し，`return`を押すと削除できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/0594de14-8978-727a-ff27-6482cd7bd85a.png)

:::note warn
現在の作業ブランチそのものは削除できないので他のブランチに移動してから削除すること
:::

# ローカルブランチのマージ(git merge)
3のLocal branchesでマージ先のブランチに切り替える，その後，マージ元のブランチを選択して`M`を押してマージする．マージするオプションはいつもの3種類から選べる．詳しくは[こちら](https://qiita.com/JavaLangRuntimeException/items/6b46551f56e0def76eba#git-merge%E4%BB%96%E3%81%AE%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E3%81%AE%E5%86%85%E5%AE%B9%E3%82%92%E3%83%9E%E3%83%BC%E3%82%B8%E3%81%99%E3%82%8B)から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/0a57d324-ce72-d9e0-9769-988433d3b39b.png)

# 作業中の変更を一時保存(待避)(git stash)
## 一時退避する(git stash push)
2のfilesで`s`を押すと，現状の変更を一時退避できる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/afdeddea-ea64-3d00-da32-eb902a9f9f26.png)
すると，5のstashのところに保存され，変更差分がなくなる．
![スクリーンショット 2024-10-05 14.36.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/aefabef0-1901-a3eb-cb71-08845b987d05.png)

## 退避した変更を適用する(git stash apply)
5のstashで対象のstashを選択し，`space`を押すと選択しているstashを適用する．
![IMG_3358.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/940b01fa-3e5e-475d-b3b8-8f7d1bb19321.jpeg)

2のfilesに変更差分が戻り，5のstashから適用したstash(「stashしたよ〜」)が消えてなく，listに残っていることがわかる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/72c4e4a3-e88a-ea91-5a9d-0b0cee2af3e8.png)


## 退避した変更を適用してstashリストから削除(git stash pop)
5のstashで対象のstashを選択し，`g`を押すと選択しているstashをpop(stashを適用してリストから削除)する．
![IMG_3360.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/086e46ea-5370-a692-842e-35e69804a7db.jpeg)

2のfilesに変更差分が戻り，5のstashから適用したstash(「stashしたよ〜」)が消えていることがわかる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/26c272ad-585e-15ba-99c2-fc11e3312da4.png)

## stashを削除(git stash drop)
5のstashで削除したい対象のstashを選択し，`d`を押すとstashを削除できる．
![IMG_3358.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/2170d197-352f-d566-3b71-64175a6df403.jpeg)


# リモートブランチをチェックアウト(git checkout)
3のRemoteに移動する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/4d49c132-8712-1976-f67b-9a125d3f8cbf.png)

対象のリモートブランチ名(origin)を選択し，`return`を押すとリモートブランチが表示される．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/e62dcf08-0aea-9ffd-c8d4-7e9598f2e4cb.png)

:::note info
リモートブランチを選択して`return`を押すとリモートブランチのコミット履歴(log)が出る．リモートブランチ一覧に戻るには`esc`を押す．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/30f038d5-2500-b3b2-a0e0-383c0307af24.png)
:::

チェックアウトしたいリモートブランチを選択して`space`を押して，`new local branch`を押し，`return`を押すとチェックアウトできる
![スクリーンショット 2024-10-05 16.36.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/68648902-5401-7d9c-e874-9d198a15b0c3.png)

# ローカルからリモートへの同期(git push)
任意のモード(どこでもいい)で`SHIFT`+`P`を押すと現在の作業ブランチでpushできる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/a73aa3b4-6726-48d8-e729-fc7063f6b30d.png)

> このとき3のlocal branches の作業ブランチの右側がPushingになる

# リモートからローカルへの同期(git pull)
任意のモード(どこでもいい)で`p`を押すと現在の作業ブランチでpullできる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3757442/6e7b8529-3aef-c80e-13a1-1bab27fbc30e.png)

> このとき3のlocal branches の作業ブランチの右側がPullingになる

とりあえずここまでの動作がわかれば普段の開発で行うgit操作はできる．これ以外の操作をしたい場合は[git/ghコマンドチートシート](https://qiita.com/JavaLangRuntimeException/items/6b46551f56e0def76eba)で記載しているコマンドを実行した方が良いと思う．ただし，普段から多用するadd commit はlazygitを使うと快適なgitライフが送れるようになると思う．