初心者がGitについて調べたことをまとめる

## 本記事の目的
現在情報系の大学3年の私がGitについて学んだことをまとめていく記事になります。前提知識としては、GitHubは少しだけ触れたことがあり、
```
git init
git remote add ...
git add
git commit
git push
git pull
git clone
```
などをその都度調べて呪文のようになにも理解せず叩いています。今回はこのような前提知識の上で学んだことをまとめていきます。最終的には自分が困ったときに見返せたり、友人に何か聞かれた際にこれを見せれば完結するような内容をまとめられたらいいなと思っています。
(Qiitaへの投稿が初めてなので構成などで読みづらい部分があるかもしれませんが、ご容赦ください...)

## バージョン管理とは
Gitは現在主流のバージョン管理システムと呼ばれるもの。一言でいうと、履歴管理ツール。Gitを使うことで各ファイルに関して"誰が、いつ、どの部分を編集したのか"という情報を管理することができる。また、その際に各変更前のバージョンが残っていくので、各ファイルに問題が発生した際に、どの編集によってその問題が引き起こされたのかを簡単に発見することができるらしい。

## チーム開発においてGitをつかうメリット
チームで開発を行う際にはファイルの共有が必要。簡単なツールでいうと、GoogleDriveなどのクラウドサービスがあるが、これらはファイルの変更を自動的に同期してしまい、同じファイルを複数人で編集したりすると、どのファイルが最新なのかわからなくなってしまったり、誤って変更を上書きしてしまったりするなどの問題がある。一方でGitを使うと、ファイルの変更の同期はcommit/push/pullなどの段階を踏み、コンフリクトが起きたらそれらが解消するまで編集内容を統合することはないため、このような問題をなくす事ができる。

## Gitの基本的な仕組み
### リポジトリ化
最初に紹介したこの呪文コマンド
```
git init
```
フォルダをリポジトリ化するためのコマンドらしい...
このコマンドを叩くとワーキングディレクトリ内に.gitというフォルダが生成される。その.gitがリポジトリの本体であり、そこに変更点を記録していく。リポジトリ(.gitのフォルダ)に編集内容を記録するときに使うのが
```
git　add
git commit
```
というコマンド。`git add`はコミット対象のファイルを置いておく「ステージングエリア」という仮想上の空間にファイルをあげる(ステージング)ためのコマンド。そして実際に記録内容をリポジトリに記録するためのコマンドが`git commit`。記録の操作自体だけでなく、記録した変更データのかたまりもコミットと呼ぶらしい。ここのコミットには直前のコミットからの差分だけが記録されている。

### リモートリポジトリ
ローカルのリポジトリと同期したリモートリポジトリを用意するのがGitHubの用途。これにより、ネット上に自分のファイルを置くことができたり、チーム開発の際にみんなのファイルの同期をミスなく行うことができる。ローカルリポジトリの内容をリモートリポジトリに反映するのが
```
git push
```
というコマンド。逆に、リモートの内容をローカルに反映するのが
```
git pull
```
というコマンド。ここまでで注意したいのは、Gitが同期しているのはリポジトリ同士であること。つまり、何かを変更してもコミットしなければプッシュしても反映されない。またおそらく、細かな変更の際の元のファイルを復元可能にするために、こまめにコミットする方がよいのではと考えられる。

### ブランチ
コミットの履歴を枝分かれさせる機能。これを使うと、たとえば複数人でアプリの新機能を実施する際に実装する機能ごとにブランチを作ることで、複数の機能のコミットが混合しないようにすることができ、開発時に履歴の参照がしやすくなる。最終的にそれぞれが分岐先で作った内容をmainにマージする。そのため、マージの際にコンフリクトが起きづらいようなブランチ分けが大事。

## GitとGitHubの境界
ここまでの自分の理解としては、ローカルに対する操作(commit, branch, merge等)はGit、リモートに関係する操作(clone, push, pull)はGitHubというように考えていたが、実際はどの機能もGitに備わっているらしい。そのため、自力でサーバーを立てれれば、そこにリモートリポジトリを置くことも可能だとか...
### GitHubの機能(まだ理解が浅いので実際に使ってみて更新したいです)
* プルリクエスト
ブランチのマージの際に他のチームメンバーと相談や確認を行うための機能。プルリクエストの使い方として、GitHubフローという以下のルールが提唱されている。
-作業開始時は必ずmainブランチからブランチを分岐させて進める
-ブランチをマージする際には、必ずプルリクエストを利用してチームメンバーからのレビューを受けてからマージする
* 公開設定(Public or Private)
リポジトリの公開範囲を設定できる。
* イシュー
バグの報告や作業上の懸念点の相談に使われる機能。

## 主要Gitコマンドまとめ
```
git init //ワーキングディレクトリをリポジトリ化
git remote add origin @git... //リモートリポジトリをoriginという名前で追加
git remote remove origin //リモートリポジトリの指定を解除
git add //ステージング(-Aをつけるとステージング可能なすべてのファイルを対象とする)
git rm //ステージングを外す
git diff --cached //(--cachedをつけるとステージングエリアとの)差分を比較
git commit -m "(コミットメッセージ)"// (-mをつけるとコミットメッセージ付き)コミット
git push origin ブランチ名 //コミット内容をリモートにプッシュ(初回で以下を実行するとgit pushのみで実行可となる)
git push -u origin main //--set-upstreamと-uは同じ
git reset --soft HEAD^ //直前のコミットを取り消してすぐに再コミットできる状態にする
git revert コミットID(先頭4文字程度) //それまでのコミット内容を打ち消すようにしたファイルをコミット(コミットとしてログに残る)
git status //リポジトリの状態を確認
git log //コミット履歴を参照(revert用のコミットIDもここから見れる)
git pull //リモートリポジトリの内容をローカルに同期(fetchとmergeを同時にやってる)
git fetch //リモートリポジトリの状態を確認
git merge //ブランチの内容をマージ
git branch ブランチ名 //ブランチを作成(ブランチ名なしで実行するとブランチ一覧表示、-dをつけると削除)
git checkout ブランチ名 //ブランチを切り替え
```

## 見たことはあるけど正体不明だった者たち
### README.md
READMEとは一般的に、そのリポジトリ内で管理しているプロジェクトの紹介や、共同開発者への注意文などを載せるためのファイル。
### .gitignore
名前の通り無視したいファイルを指定するためのファイル。要するに自分のリポジトリに残したくないファイルやそのようなファイルに共通する拡張子などを記述しておくことで、コミット時に自動的に無視してくれる。ちなみにGitHub上に[.gitignoreのサンプル](https://github.com/github/gitignore/tree/main)のリポジトリがあった。

## 最後に
とりあえず1日で学べた内容を取り急ぎまとめてみました。これからガンガン使っていって気づいたことがあればその都度追加していこうと思います。