Gitについてのメモ

# Git memo
### ・Gitの基本コマンド
- `git init`
Git Repositoryを作成してバージョン管理するためのローカル環境（Worktree）を作成する。実際のディレクトリまで移動してから行う。
.gitという隠しファイルが作成され、そのディレクトリ以下にgitの機能が適用されるようになる。

- `git add ファイル名`
`git add .`
指定したファイルの変更内容を worktree から Staged に移動させてチェックポイントを作る。「stage環境に乗せる」という。
. を指定することでカレントディレクトリ指定の全ての変更されたファイルをステージングエリアに追加する。

- `git status`
各ファイルの状態を確認することができる

- `git commit　-m "コメント"`
変更した内容をチェックポイントとしてGitに登録する。
オプション「-m」でコメントをつけてコミットすることができる。
stage環境に上がっている複数のaddを一つのパッケージにまとめてcommitされる。

- `git log`
commitした過去の履歴が確認できる
ハッシュ値で一意のチェックポイントを参照することができる
誰が、いつ　コミットしたか、コメント付きで確認できる

---

### ・ブランチ操作
環境A、環境Bのように作業毎にフォルダ全体を分けること。

- `git branch`
現在のブランチ一覧を表示
- `git branch ブランチ名`
指定した名前で、main(master)とは別の環境を作る。
「ブランチを切る」という。
- `git branch -c ブランチ名`
"-c"は新しくブランチを作りながら移動するオプション

- `git switch ブランチ名`
ブランチ間の移動を行う
HEADは現在いるブランチ先を示している

:::note info
commitする前に、ブランチを移動してしまうとcommit前のaddファイルなどが引き連れてしまうので、移動前にcommitもしくはstashして保存するようにする。
:::

- `git branch -m ブランチ名A ブランチ名B`
A から B へブランチ名の変更

- `git branch -D ブランチ名`
ブランチの削除。Gitでは現在のブランチを削除することはできないので、mainなどに戻ってから削除する。

### ・Merge について
- `git merge ブランチA`
main から分かれたbranchでの作業が完了して main に内容を反映させるときはmainブランチにいる状態で、mergeコマンドを使う。

- マージ方法の種類
    - Fast Forward Merge
    指定したブランチAの最新のコミットをHEADにして main に上書きするように取り込む方法
    - 3-way Merge（三方向マージ）
    main を元にしたbranchAとbranchBがある場合に、
先にブランチAで作業XをFast Forward Mergeして、ブランチBを作業Yをマージする場合は、上書きして作業Xを消さないように、差分のみを自動的に読み取って作業Xを残しつつ、ブランチBの内容をマージする方法。

ただしブランチAとブランチBで同じファイルを変更していた場合は、マージコンフリクトと呼ばれる状態となり、自動でマージできなくなる。この場合、コンフリクトを起こしている箇所を手動で解消してからから再度 add -> commit を行うこと。

実際のコンフリクトが起きたときの表示
```powershell
> git merge aaa
Auto-merging example.md
CONFLICT (content): Merge conflict in example.md
Automatic merge failed; fix conflicts and then commit the result.
```

ファイルの中身を見てみると、
```
<<<<<< HEAD
aaa
=======
bbb
>>>>>> branchB
```

---

### ・Diff
- `git diff`
ブランチやコミット間の差分を表示するコマンド
変更前と後のもので、ソースコードの変更箇所の確認ができる。
オプションとして、--staged や　HEAD などがある

```powershell
diff --git a/piyo.txt b/piyo.txt
index e69de29..f00c024 100644
--- a/piyo.txt
+++ b/piyo.txt
@@ -0,0 +1,4 @@
+piyo
+piyopiyo
+pipi
+pipipipi
```
"-"、ファイル名の前に a がついているものが変更前、
"+"、 b が変更後を表している。

他の記述例：
- `git diff ブランチA..ブランチB`
ブランチAB間の差分を表示させる。
- `git diff コミットハッシュ値..コミットハッシュ値`
指定したコミット内容の差分を表示させる。

:::note info
Windows用の比較・マージ用のビジュアルツールとして、WinMergeも使える。
[公式サイト](https://winmerge.org/?lang=ja)
[参考サイト](https://qiita.com/frozencatpisces/items/8f998720de8f2aaa7e37#1-%E5%9F%BA%E6%9C%AC)
:::

---

### ・stash
作業内容を一旦、退避させるコマンド
変更途中のものを一度addしてから
- `git stash`
その作業場所に作業内容を留めることができる
- `git stash list`
stashされているファイルが一覧表示されるので、

```powershell
stash@{0}: WIP on aaa: d4e4b5a aaa
stash@{1}: WIP on aaa: d4e4b5a aaa
```

- `git stash apply 'stash@{0}'`
listの記号 @{0} を指定するとそのstashが復元される
- `git stash pop`
上のリストから復元しながらリスト一覧から削除する。applyは復元してリストには残す。
- `git stash drop 'stash@{0}'`
指定したものをリストから削除することができる
※作業箇所が同じファイルが複数スタッシュされていてapplyで復元する場合コンフリクトすることがある
- `git stash save xxx`
xxx と名前を付けてstashもできる。この場合、名前を指定して apply や pop 、drop できる

---

### ・履歴操作する Time Traveling
過去のコミットにさかのぼっていくこと。

- `git log --oneline (--graph)`
実行するとコミット履歴をコミットハッシュ値の先頭7桁とコミットメッセージを一行で表示する。(グラフオプションで履歴をグラフ表示できる)
```powershell
0a281da (HEAD -> testA) add a.md
b74e598 (master) add memo.md
```

- `git checkout b74e598`
指定したハッシュ値のコミット（チャックポイント）まで遡ることができる。バグの調査などに使える方法
- `git checkout HEAD~1`
チルダの後ろで指定した数字分ヘッドを戻す。
- `git checkout ブランチ名`
最新のコミットに戻ることができる
- `git restore ファイル名`
unstagedなadd前の変更内容を編集前まで戻す
- `git restore --staged ファイル名`
add済みでcommit前のファイルをadd前の状態（unstaged）に移動する（編集内容自体はそのまま）

- `git reset`
編集内容のそのままにaddをリセットする
- `git reset ハッシュ値/head`
指定したハッシュ値のコミット（チェックポイント）まで履歴を削除して移動することができる。
- `git reset --hard ハッシュ値/head`
ファイルごと指定したコミットまで削除するコマンド

- `git reflog`
reset --hardで間違ってコミットログを消してしまった場合はreflogで全logを取得して、削除前のポイントを指定してあげることで戻すことができる

コミットログの確認
```powershell
> git log --oneline
b92957c (HEAD -> master) Merge branch 'fix-bugs'
eb11ca1 (testA) c.md
0a281da add a.md
0dc321e (fix-bugs) fix-bugs
b74e598 add memo.md
```

最初のコミットログまでリセット
```powershell
> git reset --hard b74e598
HEAD is now at b74e598 add memo.md
```

コミットログの確認
```powershell
> git log --oneline
b74e598 (HEAD -> master) add memo.md
```

リフログの確認
```powershell
> git reflog
b74e598 (HEAD -> master) HEAD@{0}: reset: moving to b74e598
b92957c HEAD@{1}: merge fix-bugs: Merge made by the 'ort' strategy.
eb11ca1 (testA) HEAD@{2}: merge testA: Fast-forward
b74e598 (HEAD -> master) HEAD@{3}: checkout: moving from testA to master
eb11ca1 (testA) HEAD@{4}: checkout: moving from 0a281da30465c9a30517ca0c8d6376d6154e4d1d to testA
0a281da HEAD@{5}: checkout: moving from testA to HEAD~1
eb11ca1 (testA) HEAD@{6}: commit: c.md
0a281da HEAD@{7}: commit: add a.md
b74e598 (HEAD -> master) HEAD@{8}: checkout: moving from fix-bugs to testA
0dc321e (fix-bugs) HEAD@{9}: commit: fix-bugs
b74e598 (HEAD -> master) HEAD@{10}: checkout: moving from master to fix-bugs
b74e598 (HEAD -> master) HEAD@{11}: checkout: moving from testA to master
b74e598 (HEAD -> master) HEAD@{12}: reset: moving to HEAD
b74e598 (HEAD -> master) HEAD@{13}: checkout: moving from master to testA
b74e598 (HEAD -> master) HEAD@{14}: checkout: moving from master to master
b74e598 (HEAD -> master) HEAD@{15}: commit (initial): add memo.md
```

リセット前のコミットログまで戻す。
```powershell
> git reset --hard "HEAD@{1}"
HEAD is now at b92957c Merge branch 'fix-bugs'
```

削除前の状態まで戻っていることの確認。
```powershell
> git log --oneline
b92957c (HEAD -> master) Merge branch 'fix-bugs'
eb11ca1 (testA) c.md
0a281da add a.md
0dc321e (fix-bugs) fix-bugs
b74e598 add memo.md
```

- `git revert #commit-hash`
コミットを削除するのではなく打ち消すようなコミットを出して、指定したコミットログまで戻るコマンド。

**リセットとリバートの使い分け**
自分しか触っていないブランチで手元のみの操作の場合（他の人への影響がない場合）は reset 、他の人も触っているブランチ場合は revert を用いる。

---

### ・Github
RepositoryをWeb上で共有するためのアプリケーション
[参考サイト](https://www.sejuku.net/blog/73468)

- `git clone https:xxxxxxxxxx`
指定したリポジトリがローカルにダウンロードされる
- `git push`
ローカルのコミット後の内容をウェブ上のリポジトリに反映させる
- `git pull`
ウェブ上のリポジトリ（他の人がpushした内容）をローカルに反映させる
- `git remote -v`
登録済みの push先と fetch先（pull）を確認するコマンド
- `git remote add https:xxxxxxxxxx`
該当のinit済みのディレクトリからウェブ上のリポジトリ先を登録する。このコマンドで push と fetch が同時に登録される

`git fetch origin xxxxx`
github上で作成したブランチをローカルにダウンロード
`git checkout xxxxx`
ダウンロードした作業用ブランチに変更

※Githubの公式サイトからリポジトリを作ると、そのページ内にCLIから連携するためのGitコマンドが紹介されています。

・ **Pull Request**
リモートのブランチにプッシュした内容をメインへの反映を依頼すること（メインの管理者がブランチの内容をレビューして良ければ認められる）
リポジトリにプッシュするには、`git push origin ブランチ名`として、ウェブ上のGithubからタイトルなどを編集して「Create pull request」をクリックして作成する。
管理側が「Merge pull request」クリックすると、musterに反映される。