From dcca4e35117c58ff741ffe82b166b9f401e16d06 Mon Sep 17 00:00:00 2001
From: Takeno-hito <18237819+Takeno-hito@users.noreply.github.com>
Date: Fri, 31 May 2024 19:07:18 +0900
Subject: [PATCH] =?UTF-8?q?=E5=8E=BB=E5=B9=B4=E3=81=AE=20md=20=E3=81=AE?=
=?UTF-8?q?=E5=86=85=E5=AE=B9=E3=82=92=E7=A7=BB=E6=A4=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docs/.vitepress/config.mts | 16 +
docs/advanced/0-intro.md | 23 ++
docs/advanced/1-git-n-github.md | 42 +++
docs/advanced/2-project/index.md | 93 +++++
docs/advanced/3-commit/index.md | 60 ++++
docs/advanced/4-cli/index.md | 570 +++++++++++++++++++++++++++++++
docs/advanced/4-cli/system.md | 48 +++
docs/advanced/index.md | 7 +
docs/index.md | 1 +
9 files changed, 860 insertions(+)
create mode 100644 docs/advanced/0-intro.md
create mode 100644 docs/advanced/1-git-n-github.md
create mode 100644 docs/advanced/2-project/index.md
create mode 100644 docs/advanced/3-commit/index.md
create mode 100644 docs/advanced/4-cli/index.md
create mode 100644 docs/advanced/4-cli/system.md
create mode 100644 docs/advanced/index.md
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
index e43c3fd..4f6fccf 100644
--- a/docs/.vitepress/config.mts
+++ b/docs/.vitepress/config.mts
@@ -38,6 +38,22 @@ export default defineConfig({
{ text: 'おまけ13: VSCode以外のGUI操作', link: '/basic/github-desktop' }
]
}
+ ],
+ 'advanced': [
+ {
+ text: '発展編',
+ items: [
+ { text: '目次', link: '/advanced/'},
+ { text: '0. 導入', link: '/advanced/0-intro'},
+ { text: '1. Git と GitHub', link: '/advanced/1-git-n-github'},
+ { text: '2. プロジェクト', link: '/advanced/2-project/'},
+ { text: '3. コミットの作法', link: '/advanced/3-commit/'},
+ { text: '4. Git CLI', link: '/advanced/4-cli/', items: [
+ { text: 'Git の仕組み', link: '/advanced/4-cli/system'},
+ ]},
+ { text: '終わりに (まだ)', link: '/advanced/conclusion'},
+ ]
+ }
]
},
diff --git a/docs/advanced/0-intro.md b/docs/advanced/0-intro.md
new file mode 100644
index 0000000..bfb0d58
--- /dev/null
+++ b/docs/advanced/0-intro.md
@@ -0,0 +1,23 @@
+# 0. Introduction
+
+## 自己紹介
+
+- たけ :@Takeno_hito: @Takeno_hito
+- 22B プログラマー? SysAd班員
+- Logical Room のプランナー
+
+## 講習会の目的
+
+前期に実施された Git 講習会を受講している事を前提にして、主にプログラマー向けにより実践的な使い方を学ぶ。
+
+::: warning
+本講習会は主にプログラマー(=コードを書いている)向けのものです。
+そうでない場合は、前期にlogicaさんが実施したGit講習会の内容を理解していれば十二分だと思います。(もちろん受講は大歓迎です)
+:::
+
+## 講習会概要
+
+1. Git と GitHub/Gitea が別物であるという事を理解する
+2. Git CLI を使って、Git がどのように動いているかを理解すると同時に、Git CLI で操作できるようにする
+3. rebase, cherry-pick など Git に関する新たなサブコマンドを理解する
+4. Git の実用的な使い方を理解する
diff --git a/docs/advanced/1-git-n-github.md b/docs/advanced/1-git-n-github.md
new file mode 100644
index 0000000..be6b93c
--- /dev/null
+++ b/docs/advanced/1-git-n-github.md
@@ -0,0 +1,42 @@
+# 1. Git と GitHub と Gitea...?
+
+Git, GitHub, Gitea を混同する者がたまに居るので、これらの違いを以下に解説する。
+
+- Git
+ - コードのバージョン管理(ソースコードの編集履歴の記録)をするソフト
+ - サーバー上に保管されている「リモートリポジトリ」
+ - 各自のPCに保管されている「ローカルリポジトリ」
+ - ローカルリポジトリを編集して、リモートリポジトリと同期をとる形で作業する
+- GitHub
+ - Git を使用した **Web サービス**
+ - リモートリポジトリを保管する以外にも、チーム開発に便利な機能を提供してくれている
+- Gitea
+ - Git を使用した、セルフホスト型(自分でサーバーを持つ)の **ウェブサービス**
+ - リモートリポジトリを保管する以外にも、チーム開発に便利な機能が実装されている
+ - traP の場合は、traP のサーバーに Gitea を置いて運用している
+
+### Git/GitHub の違いクイズ
+
+1. `commit` は Git の機能か、GitHub の機能か?
+2. `merge` は Git の機能か、GitHub の機能か?
+3. `pull` は Git の機能か、GitHub の機能か?
+4. `issue` は Git の機能か、GitHub の機能か?
+
+:::spoiler Answer (クリックで展開)
+
+1. commit は Git の機能。
+2. merge は Git の機能。GitHub の機能とも言えなくもないが、本質的には GitHub が Git のマージをする機能だという事を忘れないように。
+3. pull は Git の機能。Pull Request が GitHub の機能。もともとは、大本のリポジトリを持つ側に対して「自分のリポジトリ内のブランチをpull して統合してください」とrequest を出す、という所から Pull Request という名前がついている。
+4. issue は GitHub の機能。Git に issue 機能はない。
+:::
+
+:::info
+**おまけ:Gitea と GitHub の使い分け**
+
+Gitea と GitHub 、これらはどちらも Git のホスティングをしているが、大きく違うのは GitHub は **GitHub** のサーバー上にコードを保管していることに対して、Gitea は**自分が所有する**サーバー上にコードを保管していること。
+そのため、GitHub には OSS(オープンソースソフトウェア)が置かれて、Gitea にはセキュリティ上の問題から非公開のファイルを置いている、という事が多い。
+(GitHub の会社向けプランみたいなものも存在していてそれを使う企業・団体も存在するし、またはGitea/GitHub 以外のソフト・サービスを使っている企業・団体も存在する。)
+
+traP の場合は traQ のような traP が作った webサービスそのものは GitHub 上で公開され、サーバーの設定ファイル(プロビジョニングコード)や、Gitea と連携している Showcase で動かすコードは Gitea 上に置かれている、という事が多いらしい。
+また、2022年に新規に立ち上げられたプロジェクトはすべて Gitea 上に置かれている。
+:::
diff --git a/docs/advanced/2-project/index.md b/docs/advanced/2-project/index.md
new file mode 100644
index 0000000..11f53a0
--- /dev/null
+++ b/docs/advanced/2-project/index.md
@@ -0,0 +1,93 @@
+## 2. Git 運用のすすめ
+
+### merge conflict
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp1kdtKxDAQhl9lGCi5qYi3uRB6kG11BU8XuvQm26RtsElKTMWl9N1Nu8qWPQQCmZkv_z_JDFgaLpBiEAxSS0dhANKaei2-RUsoEC62fU1CIK4RSuwzFetbR2CEMQgKDfOqpVtZ1jX_MUBplJIOJKcF5l66wENta5kuG6jkz_XN4kYjyk_TO1BM6vNCURTB1S0kSbKUWxJxHE_E-8emQHC7TtAsX2Vrv9_OOB13cGqVpuklK9_FRDw9v1wifGki8vuHk2bAsdoT2V3k9TFEJax_NvejGCatAucPL5D649-XTy6jR1nvzOtOl0id7UWIfceZE6lktWUKacXaL5_tmN4Yc4gFl87Yx_2456mPvybcljY)
+
+merge を行う際、たまにコンフリクトが発生する。例えば、上図のようなコミット図で fix/1 -> main にマージを行う際に、 `AAA` を `CCC` に変更するコミットと、同じ `AAA` を `DDD` に変更するコミットが違うブランチで存在したときに、 Git は自分ではマージせずに一回中断する。
+
+GitHub などで PR をマージする時にコンフリクトが発生すると、一度作業ブランチにマージする必要がある。これは、コンフリクトを正しく解消できているかレビュワーが確認したいからである。
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp1kt9rgzAQx_-VIyC-OMZe8zCwCq1bB1u3h634kuqpYZpIGrsV8X_fqSu1vwKBXO5z3y-XS8sSnSLjzHFaqaTl0IJb6nyJOyxdDm6KmyZ3PXBtgRWON5loSutCB53jxAqGlUs7N6IuDjFAoqtKWpApj1lE0jE75jZGqKSATP7eP0wqCky-dWOhElJdF_J9H-4eIQiCqdyUmM1mPfH5tT4hDtLnlpfaYRje0ibbnnh9W90iKNUT0dPzlKjQ5Dh0BXZfI19E88WS9sdYZHCryx2SkMpKmdBLgRU5JVa4k_hztY_TJxoNht7OHJjHKEl0SkNu-4qYDaOMGafj_zB7i45Q0Vj9vlcJ49Y06LGmToXFUIrciIrxTJRbuq2FWmt9jDGVVpuX8SMN_6n7A4UqslA)
+
+(作業者が `main` ブランチを `fix/1` ブランチにマージして、 `review` タグがついたコミットをレビュワーが確認し、その後 main にマージされる。という流れを表したのが上図)
+
+コンフリクト解消は意外と面倒くさいので、演習用のリポジトリを使いながら実際に解消して学ぶと良いだろう。
+
+:::success
+**演習**
+前提:`ex_rebase` ブランチがマージされてる状態にする(`ex_rebase`、`ex_conflict` ブランチ間でコンフリクトが発生している。)
+
+1. `ex_conflict` を master にマージしたいので、PR を立てる。この時に、コンフリクトが発生していると Gitea に怒られるので手元で修正する。
+2. `ex_conflict` ブランチにチェックアウトし、`master` ブランチをマージする。
+3. コンフリクト通知が出るので、エディターを使って編集する (vim じゃなくて良い)。
+4. 以下のように `<<<<<<
>>>>>> master` で囲まれている部分がコンフリクトしている場所なので、2つを見比べながら適用していく。
+ この時、「**どちらがどんな変更をしたのか**」を確認しながら、どちらも適用できるように編集を進めていくこと。
+```
+<<<<<<< HEAD
+本サークルは、名称を **『東京医科歯科工業大学デジタル創作同好会traP ..... とする。
+=======
+本サークルは、名称を **『東京工業大学デジタル創作同好会traP』... とする
+>>>>>>> master
+```
+
+5. キャンパス名の修正で困ったかもしれない。どちらも違うものに編集しようとしている。ここでは、「すずかけ台」への移行を採用する。
+6. 修正が完了したら、マージコミットを作成する。
+
+:::
+
+### .gitignore
+
+gitignore は git の管理下に新たに置きたくないファイルを指定するファイル。
+注意して欲しいのは、既に git の管理下に置かれたファイルは、gitignore に追加しても変更は追跡されるという事(1敗)。具体的な記述方法は割愛するので各自調べること。(`*` によるワイルドカード指定などができる。)
+主にビルド時・実行時に生成されるファイル・キャッシュ・バイナリファイルや、ライブラリ、また個人情報や認証情報が含まれるファイルが gitignore に置かれる事が多い。
+
+[gitignore.io](https://www.toptal.com/developers/gitignore) を使うと、リポジトリを制作する時に必要なファイルを自動で生成してくれるので便利。
+
+### branch protection
+
+文字通りブランチの保護に関する設定。例えば、間違えて master にコミットしても push する際に拒否されるので他の作業者に影響を及ぼさなくなる事ができる。
+
+GitHub でできるプロテクションはこんな感じ。Gitea にも同様の設定が存在する。
+
+
+
+自分が普段つけている設定は、大体
+- マージ前に main への PR を必須にする
+- main へのレビュワーの Approve を必須にする
+- main への直接の commit を禁止する
+
+の3つ。
+
+### issue/PR の作り方
+
+GitHub、Gitea 共に issue, PR の機能が搭載されているが、運用の仕方は様々あるし、あまり提示されていない事も多い。ここでは自分が今までやってきて、他のところでも traP でも大体そうっぽそうという話をする。
+
+#### issue を建てるとき
+
+1. まずはじめに、その issue は大きくならないかをよく考える。小さく分割できるなら分割した方がよい。
+ - **非常に重要**。これをしないと、大きい PR が完成してレビュワーが泣く。
+ - 過大な issue を切り分けるのはプロジェクトリーダーの仕事に関わる部分だと思っているので、ちょっと気をつけるくらいでも良いと思う。
+3. issue タイトルは簡潔に、明確にする。
+4. タイトルに書いてない話を本文に書く。(具体的な仕様・要件とか、バグ内容とか。)
+ - タスクが複数ある場合は、チェックボックス `- [ ]` を使うのがおすすめ。
+ 進行状況が issue 一覧からも分かるようになりかなり便利。(GitHub, Gitea 共通)
+ 
+ 
+6. タグ・ラベルをつける(enhancement, bug とか。説明文が下に書いてあるので読んでそれっぽそうな物を選ぶ。)
+
+#### issue に取り掛かるとき
+
+**必ず** issue の Assingees に自分を設定する。これを設定しないと、作業が重複して悲しい事になる。
+
+参考: https://docs.github.com/ja/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue
+
+#### PR を建てるとき
+
+1. 何をしたかを簡潔に書く。issue と対応した名前でなくても良い。
+2. 本文には何をしたかを書く。PR の diff やコミット一覧を見ながら書くこと。
+ - たくさんあれば箇条書きを使うと良い。
+3. 対応する issue の番号を書く。例えば130番ならば `resolve: #130` と書くだけで良い。
+ - これを書くと、PR がマージされた時に自動的に issue がクローズされて、作業が楽になる。
+ - issue がクローズされたくないなら、単に `#130` と書けば十分。
+4. issue と同様にしてラベルをつける。
diff --git a/docs/advanced/3-commit/index.md b/docs/advanced/3-commit/index.md
new file mode 100644
index 0000000..1df4ced
--- /dev/null
+++ b/docs/advanced/3-commit/index.md
@@ -0,0 +1,60 @@
+### Git Flow
+
+Git Flow は Git を利用した開発方針の一つ。`master` `develop` `hotfix` `feature` `release` のブランチを作って、各ブランチに以下のような役割をもたせて運用する。マージする前の PR はあまりなく、master にマージする前にバグがないかチェックする。
+具体的な運用の仕方についてはここでは扱わない。
+
+- `master` はリリースされているもの
+- `develop` はリリース前のもの
+- `feature` は個々が作業するブランチ
+- `hotfix` は緊急修正を行う作業ブランチ
+- `release` はリリース作業を行うブランチ。(develop -> master)
+
+
+
+
+### GitHub Flow
+
+`master` と作業ブランチのみが存在し、`master` にマージする前に PR を立ててレビューを行ってからマージする形式。`master` にマージされるたびに、即時リリースされる。
+
+実際に運用する際には、どちらも運用しやすいように形を変えることが多い。例えば traQ の場合は GitHub Flow のような形だが、リリースはマージされる度には行わずに、リリースコミットを打ったタイミングでリリースをする。
+
+### コミットの付け方・ブランチの付け方
+
+作業する時のコミットやブランチの切り方、メッセージの書き方について。
+
+まず前提として、リーダーの人がルールを決めていたらそのルールに従うべきである。
+
+#### ブランチ
+
+ブランチは、1 issue に対して 1つのブランチを意識する事。issue が終わる度に PR を出したい。ブランチの名前は、issue の名前を英語にすれば良い。全員東工大生なのできれいな英語を無理に意識する必要はない。
+
+#### コミット
+
+コミットはできるだけこまめにしよう。push する前に先述の rebase 等を使用すれば良いだけ。変更したい所がうまく変更できて、ビルドも成功すればすぐにコミットする事。
+コミットメッセージの付け方については、コミットの頻度が非常に細かくなればそこまで困ることはなくなると思う。(Todo)〇〇した、という形で書けば割とよくなる。日本語でも英語でも良いと思うが、ルールが存在すればそれに従うこと。
+
+また、コミットにプレフィックスをつける事を個人的にはおすすめする。
+
+[Angular](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type) を見ながら、コミットにプレフィックスをつけるとコミット一覧を見た時にどのような変更なのか非常に分かりやすくなる。
+
+具体的にはこんな感じ。([リポジトリのURL](https://github.com/afes-website/cappuccino-app/commits/develop))
+
+
+もうひとつの選択肢として、コミットメッセージの先頭に絵文字をつける方法もある。
+
+[gitmoji](https://gitmoji.dev/) を見ながら、コミットに絵文字をつけると見た目は良くなる(ただ、これを知らない人が見ると全くわからない気がする…)。
+
+こっちはこんな感じ。カラフルでちょっと見栄えは良い。([リポジトリ](https://github.com/traPtitech/traPortfolio/commits/main))
+
+
+
+### やってはいけないこと
+
+- 巨大なバイナリファイルのコミット
+ - 特に zip ファイル。そのままコミットすると、他のgit操作に支障が出る。Git LFS を用いるなりそもそも巨大なzipファイルを扱わないなり回避するべき。
+ - GitHub は特に制限があって、超えると利用停止とかが発生するので要注意(これで後輩が利用を停止させられていた。)
+- コードのコメントアウト
+ - 特段の理由がなければ避けるべき。過去のコミットを漁れば見れる。
+- force-push
+ - バージョン管理のデータそのものを一部吹き飛ばす訳なので、無闇にやって良いものではない。
+ - 特に、masterブランチなどではしない方が良い(他の人の作業進捗にまで影響が出る為)。
diff --git a/docs/advanced/4-cli/index.md b/docs/advanced/4-cli/index.md
new file mode 100644
index 0000000..fea2433
--- /dev/null
+++ b/docs/advanced/4-cli/index.md
@@ -0,0 +1,570 @@
+# 5. Git CLI
+
+プログラミングをする際に Git は必要不可欠で、Git についてより理解して発展的な使い方を学ぶには GitHub Desktop では不十分。そこで、Git CLI(コマンドラインインターフェース)を使う。
+
+:::warning
+wiki にも書いた通り、Git CLI を導入した前提で講習会を進めます。
+また、前期の講習会を受講している前提で進めますので、この章で説明するコマンドについての詳細は割愛します。
+
+:::info
+
+**前期 Git 講習会リンク**
+- 座学編: https://md.trap.jp/p/zyzKKzZls#/
+- 実習編: https://md.trap.jp/s/eS_tHGpGj
+
+:::warning
+traP のアカウントが必要です
+:::
+
+本講習会では、講習会用のリポジトリを用いてコマンドを実際に使用しながら解説する。
+
+### clone
+
+リモートリポジトリを、クローンしてローカルに作る。
+
+```bash==
+git clone
+```
+
+### log
+
+コミットの一覧を表示する。
+
+```bash==
+git log
+```
+
+このままではなかなか見づらい。logコマンドには様々なオプションを設定する事ができるので、試しに `--oneline` を設定してみる。
+
+```bash==
+git log --oneline
+```
+
+コミットを一行で見れるようになったが、複数のブランチのコミットが混ざっていて分からない。
+
+```bash==
+git log --oneline --graph
+```
+
+これである程度見やすくはなった。
+
+### vim ツール
+
+実際にこれからコミットしたいが、せっかくの機会なのでファイル変更もCLIで行おう。今回は vim を使う。
+
+#### vim の使い方
+
+```bash==
+vim
+```
+
+で起動する。 `:q` と入力すると終了する。
+
+```bash==
+vim
+```
+
+で特定のファイルを開くことができる。 `I` キーで編集モードに入り、`Escape` キーで編集モードが終わる。編集モード外で、`:w` と入力すると変更を保存する。 `:wq` で変更を保存して終了する。
+
+これを使って、kiyaku.md を編集しよう。
+
+:::success
+
+### 演習 1 ファイルの編集
+
+#### Step 1. フォーク
+
+まずはリポジトリのフォークを行う。フォークについての詳細は省くが、簡単に言えば他の人のリポジトリをコピーして自分のリポジトリとして作業できるようにする機能。
+
+https://git.trap.jp/Takeno_hito/git-lecture-advanced を開き、「フォーク」ボタンを押す。すると、自分のリポジトリが作成できる。
+
+※ git-lecture.trap.jp は、講習会期間中のみ開いているサーバーで現在は開いていません。
+
+**traPのアカウントを持ってない方は、以下のリポジトリを活用してください!テキストの説明と同じ方法で演習を進めることができます。**
+
+**https://github.com/Takeno-hito/git-lecture-advanced**
+
+#### Step 2. クローン
+
+
+
+クローン先のリポジトリで、画像のボタンからURLをコピーする。
+
+リポジトリコンソールを開き、テキストに従いクローンする。
+
+#### Step 3. 編集
+
+vim で kiyaku.md を開き、「第3条(目的)」の、`ゲーム、イラスト、...` に「映像」を追記して、保存。vim を閉じて元の画面まで戻れればOK。
+
+:::
+
+
+### add
+
+変更したファイルをステージングする。(ステージング:コミットするファイルを選択する操作)
+この時、ステージングするファイルを選択する必要がある。
+
+```bash==
+git add
+```
+
+また、
+
+```bash==
+git add .
+```
+
+で全ファイルをステージングできる。
+
+`-p` オプションを使うと、ファイルのステージングを、インタラクティブに行える。
+
+```bash==
+git add -p
+```
+
+実行すると、差分をある程度のブロックに分けて、「この差分をどうしますか?」と聞かれる。これに対して、指示された通りにステージングするかしないかを選び、これを複数回行ってステージングを行う事ができる。ここで、差分に対して `edit` の選択肢を選ぶと具体的にどの行をステージングするかを選択できるようになる。
+
+### status
+
+HEAD コミットとの差分があるファイルの一覧を表示する。(HEAD については第三章で解説します。この節内では最新のコミットと同義)
+
+```bash==
+git status
+```
+
+### commit
+
+ステージングされたものをコミットする。
+
+```bash==
+git commit
+```
+
+で、コミット画面に移動する。コミット画面は vim で起動しているので、画面の指示通りにコミットメッセージを入力し、セーブして終了。
+コミット後に log を確認すればコミットが追加されていることが確認できる。
+
+### diff
+
+コミット・ブランチ間のファイルを比較する。
+
+```bash==
+git diff ..
+```
+
+1コミットだけを入力すると、HEAD との差分を取得できる。
+
+```bash==
+git diff
+```
+
+### pull
+
+リモートのブランチのコミットを、ローカルのブランチに反映させる
+
+```bash==
+git pull
+```
+
+### push
+
+ローカルのブランチのコミットを、リモートのブランチに反映させる
+
+```bash==
+git push
+```
+
+初回のpush時はリモートリポジトリ側にブランチがなくて push 先が分からないと怒られてしまうので push 時にリモートにブランチを作ることを明記すること。
+
+```bash==
+git push --set-upstream origin
+```
+
+:::success
+**演習 2 CLI での push**
+
+1. 演習1 で編集したファイルをコミットする。
+2. 実際にコミット出来ているか、CLI だけで確認する。
+3. push して、gitea 上でも問題なく反映されている事を確認する。
+:::
+
+
+### tig ツール (任意)
+
+log コマンドだけではやはり少しコミットログを一覧しづらい。このログを見やすくするためのツールの一つとして tig がある。本来 tig は他にも便利な機能が存在するが、ここではログを一覧するために使う。
+
+tig を入れるか入れないかは自由。GitHub Desktop などを見てもいいが、個人的にはコマンドを叩きながら他のアプリを開くのは少し大変だと思う。
+
+#### インストール方法
+
+##### Windows の Git Bash
+
+デフォルトで入ってます
+
+##### WSL
+
+```bash==
+git clone https://github.com/jonas/tig.git
+cd tig/
+sudo apt install make
+sudo apt install make-guile
+make prefix=/usr/local
+sudo make install prefix=/usr/local
+cd ..
+rm -rf tig
+```
+
+##### Mac
+
+```bash==
+brew install tig
+```
+
+#### 使い方(一部)
+
+```bash==
+tig
+```
+
+- 上下キーで移動。
+- `Enter`でコミットの詳細が開ける。
+- `Q`で今開いているタブを閉じる。
+- `S` でコミット画面に移動できる。
+ - `U` でコミットしたいファイル・行を選択できる。
+ - `Shift + C`でコミットメッセージ入力画面に移動する。
+
+## 4. Git のサブコマンド
+
+3章を踏まえて、サブコマンドについて解説していく。
+
+### branch
+
+ブランチを新しく作る。
+
+```bash==
+git branch
+```
+
+`-d` を指定すると逆に削除できる。
+
+```bash==
+git branch -d
+```
+
+ただし、このコマンドではリモートにプッシュされてないコミットが残ってるブランチは削除できない。削除したい場合は `-D` を使う。(多用しないように…)
+
+```bash==
+git branch -D
+```
+
+### merge
+
+対象のブランチの差分を自分のブランチに取り込む。この時マージコミットが生成される。
+相手のブランチにマージするのではなく、相手のブランチを自分のブランチにマージするという事に注意。
+
+```bash==
+git merge
+```
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNqVUE1rwzAM_StCEHwJbN3XwbdBRzPobTsNX9xEcUxjO2TyWAn573O6hmZlDCYQ-Onp6ckasAwVocQsG6y3LGEA0QazpQ9qhQRR0S4akYPghhx9V2odWxYwwphlysMxjOVNr7tmxgBlcM4y2EoqvJ5ipfDM7nrtywZq-3m1WmgaKvchMjht_R-jbpajTiwfOpLF86bYpnxdNN8qBNYmweLpcf1DOdtdrnHpd_eL35m9_882DwoxR0d9-mKVDj9MUoXH8yqU6Xk68DR0TK06cng5-BIl95FyjF2lmdZWm147lLVu31O10_4thBmPX4aYiRI)
+
+↓ **main**ブランチにいる状態で `git merge fix/1`
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNqFkU1rwzAMhv-KEARfAlv3Cb4NOppBb9tp-OLGimMW2yGzx0rIf5_TLrTLIBUYLL1-H8mox9IrQo5Z1htnAoceWOP1lr6oYRyYol3ULAcWarJ0rFQyNoHBAEOWCQeH0CZsOtnWUw5QemtNAKO4wOsxVgJP6q6TrqyhMt9XqzNPTeWHjwGsNG4BdXOO-qfe_lEn5LzV3HW3yLxfVB8EQti3xIuXTbFN5-3inyx1mo5DzawQpE7g4vlpnbCnJo8CMcfkSyCVVtaPMIGHxQjk6fq7mnHUIT2VMfjXvSuRhy5SjrFVMtDaSN1Ji7ySzWeqttK9ez_lww9EY5ji)
+
+GitHub/Gitea 上のマージボタンで起きている操作は大体これ。マージ後はマージしたブランチを(fix/1)を消すとよい。(マージ後に「ブランチを削除」のボタンが出現するのでそれを押せばOK。リポジトリ側で自動消去の設定もできる。)
+
+マージする際、同じ行に対して2つのブランチで異なる変更を加えている時など、たまにコンフリクトが発生する事がある。コンフリクトについては、5章で扱う。
+
+### restore
+
+作業中の変更をもとに戻す動作を担う。
+
+作業中のファイルを staged と同じ状態に戻すときは以下のように入力すればよい。
+
+```bash==
+git restore
+```
+
+add と同様に、`.` を指定すれば全ファイルが staged と同じ状態に戻る。
+
+:::danger
+この操作は不可逆なので作業中のファイルを誤って消し飛ばさないように要注意。
+:::
+
+また、`-S` (`--staged`) を指定すると、ステージエリアにある対象のファイルがステージエリアから削除される。
+
+```bash==
+git restore --staged
+```
+
+`-W` (`--work-tree`) を指定すると、作業中のファイル(work-tree)がもとに戻る(何も指定していない状態と同じ)。よって、staged と作業中のファイル両方を HEAD コミットと同じ状態に戻したい場合は次のコマンドを実行すればよい。
+
+```bash==
+git restore -S -W
+```
+
+### switch
+
+ブランチを切り替える。(HEAD に紐づくブランチを変更して、ファイルも更新する。)
+
+```bash==
+git switch
+```
+
+`-c` (`--create`) オプションで新しくブランチを作成できる。
+
+```bash==
+git switch -c
+```
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNqFUE1rwzAM_StCEHwJbN3XwbdBSzPobTsNX9TYcUxjO3j2WAn573O6hWZlbAKDpPf0nqUBay8VciyKwTgTOQzAOq936l11jAOTap80K4HFVln11WkodZHBCGNRCAen0CZuA_XtXAPU3loTwUgu8HqKlcAzug_k6hYa83G1Wsy0qj74FMGScX9I3SylvtF47BWvnrbVLr-XBfn2B3l2uHS-tLj7xeKM3v__gUg6s6vN41rgYvJBIJZoVcgrynz4YdIReDqvQJ5TSeEwyY-ZRyn656OrkceQVImplxTV2pAOZJE31L3lbk_u1fu5Hj8B0tCHzw)
+
+↓ `switch main`
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNqVUctqwzAQ_JVlwehiaNPXQbdCSlzIrT0VXTaWLItYklGl0mD875XTmrghFLog2MfMzkgasPZSIceiGIwzkcMArPN6qz5UxzgwqXZJsxJYbJVV352GUhcZjDAWhXBwDG3iJlDfzjVA7a01EYzkAq-nWAk8TXeBXN1CYz6vVgtOq-q9TxEsGffHqpvlqp9pPPSKV8-bapvP6wJ8KxAi6VxWT4_rX8xZ7tzGud7dBb3T9P4_bh4uGpjuiyVaFXIm838ME0jg8dUF8pxKCvuJO2YcpehfDq5GHkNSJaZeUlRrQzqQRd5Q9567Pbk37-d6_AIGL460)
+
+↓ `git switch -c feat/2` & `git commit`
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNqVUU1rwzAM_StGEHwJdO2-wLdBRzPobTsNX9REScziOGTyWAn573O6hqahFCowWHrSe89WB6nLCBREUWdqw0p0Qlau2NIPVVIJmdHOFzIWkkuy9F_J0VcsRS_6KNK1OERheNNiU465EKmz1rAwmdJwN8RSwwndtVinpcjN72I5mSkp_XKehUVTX6FaTamOKO8bUsnbJtmG8zFpvj9rHhXmynOJhwsSJ_TxFgNPFw2cP3H8D0JerK4IP2uYCzEWAU1eX9YaIAZLbaDOwk67gUfDYXMaVLgedzf46UMrenbv-zoFxa2nGHyTIdPaYNGiBZVj9R2qDdafzo15_wecbaKh)
+
+:::info
+**おまけ:checkout はどこへ?**
+checkout を使っている者もいるかもしれないが、ここでは紹介しない。
+最近(といっても2年前) `checkout` の機能を分割した新たなサブコマンド `switch` / `restore` がリリースされたのだ。つまり、`checkout` は上記2サブコマンドの機能を両方持ったサブコマンドである。経験者(自分も含む)は割と `checkout` を使っているので、先輩に質問すると少し困惑するかもしれないが、その時は各自で調べて頑張ってほしい。
+:::
+
+### reset
+
+HEADとブランチの指すコミットを指定されたコミットに動かす。
+
+```bash==
+git reset
+```
+
+`` に `HEAD` と指定すると HEAD コミットまで戻せる。 `HEAD~` と指定すると HEAD の1つ前に戻せる。`HEAD~~` と指定して2つ前に戻すこともできる。
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNqFUU1rwzAM_StCEHwJbN3XwbdBRzPobTsNX9TYcUxjO3j2WAn573O6hWalbAKDpPeenmwPWHupkGNRDMaZyGEA1nm9VR-qYxyYVLukWQkstsqq705DqYsMRhiLQjg4hjZxE6hv5xqg9taaCEZygddTrASe0F0gV7fQmM-r1ULTqnrvUwRLxv0x6mY56geNh17x6nlTbfN5XZBvf5Fnh3Pnc4u7CxYn9P7_BSLpzK6eHtcCF8qHi9tM98USrQo5k_k_hokk8PjqAnlOJYX9pB0zj1L0LwdXI48hqRJTLymqtSEdyCJvqHvP3Z7cm_dzPX4B-DuOtA)
+
+↓ `git reset HEAD~` or `git reset 00005`
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp9UU1rwzAM_StCEHwJrN3XwbdCRzPobTsNX9TYSUxjO3j2WAn573O6hWahVGCQ9N7Tk-0eSycVcsyyXlsdOPTAWlfv1ZdqGQcm1SHWLAcWGmXUb6ei2AYGAwxZJiyco9Zh56lrphqgdMboAFpygasx1gIv6MGTLRuo9PfdeqZpVHl0MYAhbW-Mup-P-kPDqVO8eN0V-3TeZ-SHf-TJYem8tHi8YnFBnwQuDQPVCS1eNtubyuer24z3xRyN8imT6T_6kSTw_OoCeUol-eOoHRKPYnBvJ1siDz6qHGMnKaitptqTQV5R-5m6HdkP56Z6-AEEto60)
+
+コミットが削除されている訳ではないので、頑張ればもとに戻すことはできる。(ref: `reflog`)
+
+また、`--hard` オプションを用いると、作業中のファイルも`HEAD`の状態に戻すことができる。
+
+```bash==
+git reset --hard HEAD
+```
+
+:::danger
+既にプッシュしたコミットを reset で戻すことは極力避けること。リモートリポジトリのブランチと整合性が取れなくなってしまう。戻したい場合は基本的に次に紹介する `revert` を使うとよい。
+:::
+
+### revert
+
+
+指定されたコミットの変更を戻すコミットをする。HEADが戻っている訳ではないので、`revert`を使うと既にプッシュしたコミットでも安全に取り消すことができる。
+
+```bash==
+git revert
+```
+
+また、revert したいコミットを範囲指定で選択する事もできる。
+
+```bash==
+git revert ..
+```
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp9UcFqwzAM_RUhCL4Etq7bDr4NOppBb9tp-OImSmIW2yGVx0rIv8_pGpqFUoFA0nvSk-Uec18QSkyS3jjDEnoQja929E2NkCAK2odKpCC4Jkt_lVKHhgUMMCSJcnCyyvC202095QC5t9YwmEIqvB9tpfCC7jvt8hpK83O3mvXUlH_5wGC1cTdGPcxHnVE-tiSzt222i_4xI6__kSeFpfJS4vGKxAV9uok-K1yuw7qKaPb6srm6zfheTNFSF6Mi_kc_khSerq5QxvB897F9iFQd2L8fXY6Su0AphrbQTBujq05blKVuDrHaavfp_ZQPv5n5j_c)
+
+↓ `git revert 000005` or `git revert HEAD~`
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp9UU1rwzAM_StCEHwJbN0n-FZoaAY9tWOH4YubKIlZbIfMHish_31O29CslAgMkt7Te8LqMLM5Icco6pRRjkMHrLblhn6oZhxYTntfshiYq0jTqVNIXzsGPfRRJAwco1Ru3cqmGmuAzGqtHKicC7wfYiHwgu5babIKCvV7t5jMVJR9We9AS2VmpB6mUmfUHRri6ds63YT3PiE__iOPDtfO1xZPNywu6LPAk-E2-Ui2u2SG-jIr9DoKXTZ3sgxomixXNxcfvgZj1NSGLA-n6waSwOOBBPKQnk80jPeBKr2zu4PJkLvWU4y-yaWjlZJlKzXyQtbfodtI82ntWPd_q66bzA)
+
+:::warning
+コミット"000005" 自体は残っていることに注意。コミット 000007 で打ち消す変更を行っているだけ。
+:::
+
+### rebase
+
+:::info
+この講習会で一番覚えてほしい要素です
+:::
+
+あるコミットを別コミットの先につなぐ。もう少し細かく説明すると、HEADから指定されたコミットの直近の共通祖先までのコミット群を「枝」として、指定されたコミットの先に「枝」を追加する。図で解説した方がおそらく早いので図で解説する。
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp9Us1qwzAMfhUhCL4Etu7v4NugpRl0p-00fHETJzFL7ODZYyUEdinsCXbYfQ-whypjbzEnaUlaSgUG_XzSJ1mqMdaJQIpBUEslLYUaSKGzhXgVBaFAErF0GQmB2FyUovek3BWWQANNEDAFnWTSzg2v8p0NEOuylBZkQhmetzJhCJZn3tysf_7ev36_PzfrD4ZDytJwFeeQyrezyahQLuJn7SyUXKoT9S_GpbZRu6oEje7m0cK_xxH4cg-8YzhkPqS4OkIxRK9PRm_a8ffb6X8jmt1Oj3bTzoshlsJ4LfFLqlsQw24VDKlXt8to0xsP5c7qh5WKkVrjRIiuSrgVU8kzw0ukKS9evLfi6knrwRaJtNrc94fQ3UPzDzJ5oVA)
+
+↓ `git rebase main`
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNqNUs1KxDAQfpVhoPRS0PVnD7kJW7bCetkVD5JL2mTbYNuUmopLKXhZ8Ak8ePcBfKhFfAvTbku7shYDgczMl2--TL4SA8UFErSsUqZSEyjBjlW4EE8itgnYXPhFaDtg60gkYp9ZsyLWNlRQWRZNoVmh1POcZVEXAwQqSaQGyQnF03pNKIJmoQl328_vl_evj7fd9pVif8XPWRpEoGI-oIlE8KAKDQmT6Qj72ZCorepNJoh3PfcWZt8OwOcH4K7DYd_fDS5q-TXh0r1zlyt3BHr5f-j0b-jxh7czWsvnk8mYWv_IPAYKx8tTv5PVT2__dZ57NaOIDiYiN8K4sU5ZE1FsDEKRmGNrkbpFZaCs0Gq1SQMkOi-Eg0XGmRYzycKcJUjWLH402Yyl90r1seBSq_xmb8_GpdUPzcfLHg)
+
+(わかりやすくする為に `old` というブランチを図に載せているが、実際には `old` というブランチは生成されない。ブランチに紐付かないコミットがそこに残るだけ。)
+
+コミット `000004` ~ `000006` が、 `000004b` ~ `000006b` にコピーされている。
+
+HEAD の場所が前とは違うところについているため、既に push したものを rebase すると push できなくなる(force-pushが必要になる)ので注意。
+
+#### 使うタイミング
+
+現在開発中の traQ の運用の中で使用しているらしい。
+traQ は master ブランチで開発を行っているのだが、ここで開発されている traQ は OSS 用(≒一般公開されてるもの)。そこから traP 内で使用する traQ に対応するための変更(例えば traPortal を経由してログインするようにする変更) は 別のブランチ(ここでは `for-traP` ブランチとする)で行っている。ので、この `for-traP` を更新する為に、リベースを行っているらしい。
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp1UkFqwzAQ_IpYMLq4H9CtaSEppKXQHtrgy8Ze26KWZZR1IRhDL4G-oIfe-4A-KpT-orKdEAdcCcHu7OwMWqmB2CYECoKg0aVmJRohC5st6ZUKqYRMaF1nMhSSczI0ICnWBXdYpnnusMo93EiDupw5LOP8DgemwQ2Tk6LtdhBEpejXseuYCxFbYzQLnagILiMQjJmP9rvv37fPn6-P_e49ghN73ZuI1LoLdng_kskpfrE1i8F4Wn82ljoUeFuRWtzMF0t_Hgfe1RnvqDxhOtJ-mtDuC8__FVbdbc_cIQRDzg8z8a_SdF0R9LOPQPnwMP1Or_VUrNk-bMsYFLuaQqirBJmuNWYODagUi41HKyxX1p5ySjRbdzu8fP8B2j8XwKOq)
+
+↓ traP 内 traQ 用のリリース作業
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp1UcFKxDAQ_ZUwUHKpP5Cbq7ArrCLoQZdeZttpG2ySkp0KSyl4WfALPHj3A_yoRfwL09bFXagJgZk3b16SNy2kLiNQEEWttpqVaIWsXLGkZ6qkEjKjdVPIWEguydCI5NhU3GOF5rnHugxwKw1qO_No0_IGR6bBDZOXout3FCVWDOvQdciFSJ0xmoXOVALnCQjGIkT73ef3y_vXx9t-95rAEbuk9Mk1LEb9aZnZScdY4G1NanE1XyzDuR95F8e89fB8kTt_xh5vp5Uf5IT0UHn8t7KS_a9OrocYDPlgWhbcb_u2BAaPE1Ah_HW5F-wCFRt2d1ubgmLfUAxNnSHTpcbCowGVY7UJaI125dxfTplm56_HCQ-D7n4A3_2b1A)
+
+他にも、PR を建てる前に rebase を行ってブランチをキレイにする人もいる。その場合は、よく次に紹介する `-i` コマンドを使っている事が多い。
+
+
+### rebase -i
+
+基本は同じだが、`-i` オプションをつけると「枝」のコミットに対して編集・入れ替えなどの操作をすることができるようになる。
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp9Us1qwzAMfhUhCL4Etu7v4NugpRl0p-00fHETJzFL7ODZYyUEdinsCXbYfQ-whypjbzEnaUlaSgUG_XzSJ1mqMdaJQIpBUEslLYUaSKGzhXgVBaFAErF0GQmB2FyUovek3BWWQANNEDAFnWTSzg2v8p0NEOuylBZkQhmetzJhCJZn3tysf_7ev36_PzfrD4ZDytJwFeeQyrezyahQLuJn7SyUXKoT9S_GpbZRu6oEje7m0cK_xxH4cg-8YzhkPqS4OkIxRK9PRm_a8ffb6X8jmt1Oj3bTzoshlsJ4LfFLqlsQw24VDKlXt8to0xsP5c7qh5WKkVrjRIiuSrgVU8kzw0ukKS9evLfi6knrwRaJtNrc94fQ3UPzDzJ5oVA)
+
+例えば、上図の状況で `git rebase -i 000001` と入力すると、コミット `000004` ~ `000006` について操作することができる。
+
+rebase を実行すると、エディターが起動してどのコミットをどのように操作したいかを選ぶことができる。画面の指示に従って編集して、セーブして終了するとコミットが操作される。操作は、編集後に並んでいるコミットを一番上から適用していく形で進む。
+
+画面を見ればどのように操作できるか分かると思うが、以下に各操作の解説をする。
+
+- `pick` コミットをそのまま配置する。デフォルトはこれ。
+- `reword` コミットメッセージを編集する。
+- `edit` コミットを編集する。このコミットを適用する段階で一旦 rebase がストップするので、編集して git の指示に従い `git commit --amend` を実行。その後、`git rebase --continue` を実行すると適用が完了する。
+- `squash` 一つ前のコミットと合体する。コミットメッセージの入力画面ではコミットメッセージが2つ並ぶので、片方をコメントアウト(`#` を行の先頭に入れる)して削除しよう。
+- `fixup` squash と同じだが、コミットメッセージは1つ前のコミットが採用される。
+- `drop` コミット削除。`#` を行の先頭に入力すれば削除される事を頭に入れておけば、これを使うことはない。
+- そのほか:使う機会はほぼない(少なくとも私は使ったことがない)。必要になった時に説明文を読んでください。
+
+:::success
+**演習**
+
+リポジトリに `ex_rebase` ブランチが用意されているので、このブランチで rebase -i を試してみる。
+まず、log でコミットの一覧を確認する。このブランチを master にマージするための PR を出すために、作業内容を整理したい。具体的には、以下の事を変更してほしい。
+
+1. 「英語名称に Titech を追加」と「Titech を Tokyo Tech に修正」のコミットは1つにまとめられそうなので、まとめて更にコミットメッセージを「英語名称に Tokyo Tech を追加」と書き換えたい。
+3. Tokyo Tech traP の略称は不要という事になったので消したい。
+4. 「卒業生でも在籍できるように」のコミット内で、「または」という文言を使っているが「もしくは」に書き換えたい。
+
+すべて変更したら、PR を建て traQ のチャンネルに貼って、レビューを待つ。
+
+Approve が出たら、そのままマージする。
+:::
+
+### cherry-pick
+
+特定のコミットだけを自分のブランチに取り込む。`cherry pick` はいいとこ取りという意味らしい。
+
+```bash==
+git cherry-pick
+```
+
+また、範囲指定でコミットを取り込むこともできる。
+
+```bash==
+git cherry-pick ..
+```
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp9UU1LxDAQ_SvDQMmloOvXITdhZSusJz1JLtlmmgabpMREXEr_u2lX2YrSgUDevJn34M2AtVeEHItiMM5EDgOwzus9fVDHODBFh6RZCSy2ZOnUaWTqIoMRxqIQDubSJu6C7NsfDFB7a00Eo7jAy6k2As_sIUhXt9CYz4vNys7NcucPe7vK3gmEeOyJV4-7ap_fy2K4pfrNpwhWGreicfWPw2_NxfD1ZCh1htXD_VYglmgpZAeVAx4mHYFzjAJ5_n4HOTmMeVSm6J-PrkYeQ6ISU69kpK2ROkiLvJHde-720r16f8akTPTh6XTE-ZbjFxTDiMA)
+
+↓ `git cherry-pick 000004`
+
+[](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp9UU1rwzAM_StCEHzJ2Lqvg8-FdtCettPwxbWVxDS2g2uPhZD_PifdaMsgAoGkpyehpwGV14Qci2IwzkQOA7DW1zv6opZxYJoOqWYlsNiQpXOlkqmNDEYYi0I4mK02cRNk1_zlAMpbayIYzQU-TLYSeEEPQTrVQGW-71cLnOdrzj_0ZRF9FQix74hv3zbbXfaPq-aG1NGnCFYatzDjcXHD0w3aUAj9XWfU8fYALNFSyIt01nmYCAJnNQXyHP7qOY0ac6tM0b_3TiGPIVGJqdMy0trIOkiLvJLtKVc76T69v-SkTfRhf_7l_NLxBxszido)
+
+(見切れちゃった…。自動生成なのでこのあたりは少し許して)
+
+### bisect
+
+バグ・問題が発生したときに、どのコミットで問題が起きてしまったかを見つけるために便利な機能。ただ、私は使ったことがない。(このテキストを作成している最中に知った。)
+
+```bash==
+git bisect start
+```
+
+で bisect を開始する。その後、様々なコミットを選択して実行して、問題が発生するかを確認していく。
+
+問題が発生しなければ
+
+```bash==
+git bisect good
+```
+発生したときは
+```bash==
+git bisect bad
+```
+を実行する。
+
+good commit と bad commit が1つずつ見つかると、git は _†伝家の宝刀†_ 二分探索を行ってくれる。
+あとは、git が自動的に commit を checkout してくれるので、それに対して `git bisect good`, `git bisect bad` を入力し続ける事で問題のコミットを特定できる。
+`git bisect run