最低限のGit・Github

# はじめに
大学のグループ課題などで、Gitを使ったほうが楽だけど、他の人があまりGitを知らないということが周りでよくありました。
そこで、必要最低限の知識を短時間で身につけることを目的に記事を書こうと思いました。

急にGitを使うことになった方や、Gitを全く触ったことがない人を対象としています。


## Git とは
バージョン管理システムのひとつ。

このように更新するごとにファイルが増えていくとする。
- ドキュメント.txt
- ドキュメント_20240218更新.txt
- ドキュメント_20240219更新.txt
- ドキュメント_20240220更新.txt

Gitを用いるとファイル名を変えること無く差分や、更新履歴を保存していくので、いつ更新したかを指定してその時の状態に戻すことも可能である。

- ドキュメント.txt
更新履歴
20240218更新 by aさん ← 20240220の状態から、いつでもここに戻すことが出来る
20240219更新 by bさん
20240219更新 by aさん
20240220更新 by aさん

また、複数人で作業領域を分けて作業し、後でそれらを合体することが出来るためチーム開発でもよく用いられる。


## ワークツリー - インデックス - ローカルリポジトリ - リモートリポジトリ
- ワークツリー
現在作業しているPCのローカルのディレクトリ
- インデックス
addしたらインデックスに登録されて、commitの準備が出来る
- ローカルリポジトリ
commitをすると、インデックスに登録されたファイルの変更がローカルリポジトリ内で保存される
- リモートリポジトリ
GithubやGitLabなどオンライン上のリポジトリ
pushをすることで、これらのオンライン上にコード等を保存できる

pushしたコードは別のPCでcloneすると同じコードを利用することが出来る。

図のイメージは以下のサイトが参考になります。知らない単語は無視しても大丈夫です。

https://biz.hpg.co.jp/biz2020/column/1338/



## clone
githubからリポジトリを自分のPCに複製するために使用します。
cloneすることでgithub上に保存されている自分のコードや他人のコードを別のPCでも利用することが出来ます。

- 主に自分が参加しているリポジトリをcloneするときは**ssh**形式でclone
```shell:clone
git clone git@github.com:〇〇/〇〇.git

```

- 他人のリポジトリをcloneするときは**https**形式でclone
```shell:clone
git clone https://github.com/〇〇/〇〇.git
```


## add→commit→push
基本的な流れはaddcommit→pushです
## add
- カレントディレクトリ内の変更があるファイルを全てadd
```shell:add
git add .
```

- 変更があるファイルを全てadd
```shell:add
git add -A
```

- ファイル名を指定して、ファイルごとにadd
```shell:add
git add file_name
```


## commit
- メッセージをつけてcommit
```shell:commit
git commit -m "message"
```
基本的にメッセージをつけてcommitをします。メッセージには何を行ったか書くことが一般的です。

例
- `[Add] 〇〇機能`
- `[Fix] 〇〇の構造`
- `[Delete] 〇〇`

## push
- ローカルのPCでcommitした変更をgithubに保存する。
```shell:push
git push origin branch_name
```

## pull
- 指定したbranch名の変更をgithub上から現在のbranchに取り込む。

```shell:pull
git pull origin branch_name
```


## branch
- branchの一覧表示と現在のbranch表示
```shell:branch
git branch
```

- 今いるbranchの名前を変更
```shell:branch
git branch -M branch_name
```

## checkout
- 別のbranchに移動
```shell:checkout
git checkout branch_name
```

- 新しくbranchの作成とともに、そのbranchに移動
```shell:checkout
git checkout -b branch_name
```

## status
- 現在の変更があるファイルの状況を調べる。
何も変更がない、変更があるがcommitされていない、まだcommitされていない未追跡の新規ファイルがある...などの情報を得ることが出来ます。

```shell:status
git status
```

##  log
- commitの履歴を一覧表示
大量に履歴がある場合は矢印キーで動かしながら見ることが出来ます。`q`を押すと終了します。
```shell:log
git log
```

## .gitignore
.gitignoreに書かれているファイルはaddやcommitがされません。
主に、個人情報を含むファイルや、キャッシュなど共有する必要がないファイルを.gitignoreに記述することで不要な共有を防止します。

- **.env**ファイル
`API_KEY`や`PASSWORD`など環境変数などを記載したファイル
- **\_\_pycache\_\_**　
pythonで自動生成されるキャッシュ
- **\*.o** 
C言語などでコンパイル時に生成されるオブジェクトファイルなど

## conflict
git pullなどをするとconflictが起きることがあります。
Gitは基本的に同じファイルを編集している場合でも、自動的に差分を検出して、上手く合体してくれます。
しかし、同じファイルの同じ行などを編集した場合、pullやmergeで合体をする際に、どちらの変更が優先されるべきか解決することが出来ません。このような場合を**conflict(コンフリクト)** と言います。
このような場合は人間が手動で**conflictを解決**する必要があります。


# 応用編
このような機能もあるという紹介です。詳細は自分で調べてみてください

- **switch**
checkoutとほぼ同じ
- **stash**
現在の変更を一旦退避する
- **cherry-pick**
一部の変更をbranchに取り込む
- **fetch**
branchの履歴のみを取得。mergeはしない(fetch + merge = pull)
- **merge**
branchを統合する
- **reset**
commit履歴などを戻す
- **プルリクエスト**
Github上で作成するリクエスト、マージ前やレビュー時に作成する


# 最後に
今回紹介した項目は本当に最低限のものです。Gitでわからないことがあったらチームの有識者にすぐに確認しましょう。
積極的にGitを使用して、慣れていくことが一番だと思います。
最後まで読んでいただきありがとうございました。
以下のサイトが様々な項目が丁寧にわかりやすく解説されています。

https://backlog.com/ja/git-tutorial/intro/01/