【Git】とりあえずこれだけやっておけばGitで悩まない

![Git-Logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696254/3e14f772-cd70-8203-f86b-ea6fc1e194e4.png)

# はじめに
筆者は、未経験からWeb系エンジニアになって2ヶ月目の人間だ。Gitの理解に非常に苦しんだので、自分自身のため、またこれから同じ思いをするかもしれない方々のために、これを読めばGit操作に困らない記事を作成した。

# 対象レベル
- これからエンジニア転職を考えている方
- 駆け出しエンジニアの方
- もう一度、基礎的なところを学びたい方
- 何となく読んでみたいという方
※PCはMac推奨

## 記事内容
- Gitの基本的な操作(add, commit, push, pull, merge, clone等)
- Gitの応用的な操作(rebase, diff, stash)

## Gitとは?
バージョン管理システムの一つで「誰が、いつ、何を」変更したのかを管理する

## バージョン管理が必要な理由
・変更履歴を辿れる
・差分確認ができる
・最新のファイルがわかる
・前のバージョンに戻せる
・他人の作業箇所がわかる
・他人の作業を結合できる

## 用語解説
- リポジトリ
    - リモートリポジトリ：GitHubで例えるなら、GitHub上に存在する[プロジェクト](https://wa3.i-3-i.info/word11485.html)の全てのファイルのこと(画像の上の方)
    - ローカルリポジトリ：自分のパソコン・マシンに存在するプロジェクトの全てのファイルのこと(画像の下の方)
- コミット
    - ファイルをセーブすること
![localRepoRemortRepo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696254/273d03fb-f701-64ca-d71e-8406c9233d2d.png)

- Working directory(Working tree等といくつかの呼び方がある)
    - 自分が作業している[ディレクトリ](https://wa3.i-3-i.info/word199.html)
- Staging area(Indexと呼び方がある)
    - コミットする前のWorking derectoryから追加する場所

## コミットの流れ
- Working directoryで変更→Staging areaに追加→コミットとこれを繰り返す

    - ほとんどはチーム開発なので、複数の機能を平行で開発する場合、状態を分けることができる
    - その状態を分けることを「[ブランチ](https://www.sejuku.net/blog/71071)切る」を言ったりする
![GItHubFlowimg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696254/380ceb45-0e3a-9046-8d3b-7cc5c674e8d1.png)
    - ブランチを切ると上記の画像のように、メインのブランチ(青)から枝分かれ(緑・赤)して、それぞれが変更でき、メインのブランチへ変更を結合するイメージ

## 基本のワークフロー手順
1. リモートリポジトリをコピー(既存のリポジトリをローカル環境に複製すること)
※[privateリポジトリ](https://zenn.dev/longbridge/articles/06938bee8f41d6)を保存したい場合or別名で保存したい場合or[カレントディレクトリ](https://wa3.i-3-i.info/word1537.html)以外に保存したい場合は、コマンドが変わる
    ```
    git clone <リポジトリパス>
    ```
    <br>
1. featureブランチを作成と同時にそのブランチに切り替える
    ```
    git checkout -b '<ブランチ名>'
    ```
    <br>
1. ファイルを更新しコミット
例えばREADME.mdを編集済の場合
    ```
    git add README.md  //作業内容がWorking directoryからStaging areaに追加
    ```
    ※```git add .```: 実際の業務では、カレントディレクトリ配下の全てのファイル、フォルダをStaging areaに追加される上記コマンドを使われることが多い
    ```
    git commit -m '<XXXXXXXXXX>'
    ```
    - 'xx'の部分には、なるべく簡潔にどういう変更したかわかるようメッセージを入れる
    - コミット後には、コミットポイントが作成される
    <br>
1. コミットの履歴を確認
    ```
    git log
    ```
    - 下の画像がコミット履歴
    - 新しいコミットが上に表示される
    - 矢印の部分が、コミットID

    ![gitlog.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696254/e7229695-7228-ca23-a0ac-dcc419f25c3b.png)
    <br>
1. ローカルリポジトリをリモートリポジトリにpushして反映する
    - pushする前に、自分が作業している間にリモートリポジトリの内容が更新されている場合があるため、pullする
    ```
    git pull origin master
    ```
    - pullができたらリモートリポジトリの最新の内容が反映されるので、次はpushする
    ```
    git push origin master
    ```
    <br>
1. featureブランチをmasterブランチ(mainブランチの場合もある)にmergeする
    - masterブランチへのmergeは、コマンドでも出来るが、実際の業務では、Githubを例に出すとプルリクエストを作成して他人に確認してもらった上で、他人がmergeすることがほとんど
    ![プルリク.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696254/0c0653e9-9618-9f20-c175-0aac90d85b9d.jpeg)
    - 下の画像がmergeボタン
    ![マージボタン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696254/dcb711c6-bbdc-4ab2-77f5-41de8856bd00.png)
    <br>
1. リモートリポジトリをローカルリポジトリにpullして反映する
    - featureブランチからmasterブランチに切り替える
    ```
    git pull origin master
    ```
    - これで、無事に変更した内容がリモートリポジトリのmasterブランチとローカルリポジトリのmasterブランチにも反映した
    <br>
1. 最後はfeatureブランチを削除する
    - 上記の一連の流れを完了すると、featureブランチは不要になるため、リモートとローカルのfeatureブランチを削除する
    - ブランチを確認
    ```
    git branch
    ```
    - featureブランチがあることを確認し、削除する
    ```
    git branch -d <ブランチ名>
    ```
    ※リモートリポジトリのブランチは、GithubのWebサイトから削除する

## 基本操作
- forkする：リモートリポジトリを自分のリモートリポジトリにコピーする
    - 大元のリポジトリに何も影響を与えずに作業ができる
    - 大元のリポジトリへプルリクエストを出せる
![github-fork-button.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696254/c5a77ff6-cdb5-e9ec-8f75-ca2b1691dcf9.png)

- trackファイルとuntrackファイルを理解する
    -  trackファイルは一度でもgitコマンドを使用している(untrackファイルはその逆)
        -  trackファイルは一覧表示ができる
        ```
        git ls-files
        ```
        <br>
- unstagedのやり方(例えば、Staging areaの内容をWorking directoryに戻す)
    ```
    git restore --staged <ファイル名>
    ```
    ※このコマンドは```git status```をすると確認ができるので、覚える必要はない
    <br>
- Working directoryの作業内容を破棄する
    ```
    git checkout --<ファイル名>
    ```
    ※このコマンドは```git status```をすると確認ができるので、覚える必要はない
    <br>
- ファイル名変更をgitで管理する
    ```
    git mv <旧ファイル名> <新ファイル名>
    ```
    <br>
- ファイル削除をgitで管理する
    ```
    git rm <ファイル名>
    ```
    ※Staging areaの作業内容のあるファイル削除は不可
    ※trackされていないファイルの削除は不可
    <br>
- コミット履歴を表示する
    ```
    git log
    ```
    - オプション
        - --oneline：各コミットを一行で表示する
        - --graph：各コミットを線で結ぶ
        - --<ファイル名>：ファイルの情報を表示する
        <br>
- 特定のコミット情報を表示する
    ```
    git show <コミットID>
    ```
    <br>
- ブランチのマージ
    - マージ：ブランチでの作業は最終的には、メインのmasterブランチや、枝分かれしたブランチに結合させるのがほとんど
    - ローカルリポジトリでマージする
    ※上記で説明したが、基本的にはマージはローカルリポジトリでは行わず、リモートリポジトリでマージする
    ```
    git merge <ブランチ名>
    ```
## diffの使い方
- Working directoryとStaging areaの差分の見方
    ```
    git diff
    ```
    <br>
- Working directoryとローカルリポジトリの差分の見方
    ```
    git diff HEAD
    ```
    <br>
- Staging areaとローカルリポジトリの差分の見方
※コミット前の差分を見たいときに使うことが多い
    ```
    git diff --staged HEAD
    ```
    <br>
- 指定したファイルの差分の見方
    ```
    git diff -- <ファイル名>
    ```
    <br>
- 指定したコミット同士の差分の見方
※使い方は大体、左が古いIDで、右が新しいIDを指定する
※最新のコミットポイントにはHEADを指定すれば良い
    ```
    git diff <コミットID> <コミットID>
    ```
    - HEAD^：HEADの親コミット
    - HEAD^^：HEADの親の親のコミット
    <br>
- ブランチ同士の差分の見方
※使い方は大体、左が古いブランチ名で、右が新しいブランチ名を指定する
    ```
    git diff <ブランチ名> <ブランチ名>
    ```
    <br>
- rebaseの使い方
※不要なマージコミットを作らないため、コミット履歴がスッキリする
※既存のコミットを削除して、新たなコミットを作るので注意が必要
    ```
    git rebase
    ```
    <br>
- pull時にmergeではなく、rebaseをする
    ```
    git pull --rebase origin master
    ```
    - rabaseを理解するためにはこの説明では足りないので、他人の力を借りることにします※参考になった記事が以下
    [git rebaseの具体的なメリット](https://zenn.dev/tana0102/articles/475d8952933af6)
<br>

- stashの使い方
※Wording directoryとStaging areaの作業内容を一時避難させる
※実際の業務では、緊急で作業が必要になった時、今の作業をstashするして、別の作業したりする

    - stashする
        ```
        git stash
        ```
    - stashした内容を一覧表示する
        ```
        git stash list
        ```
    - stashした内容をWorking directoryに戻す
        ```
        git stash apply
        ```
        ※作業内容がWorking directoryに戻るが、stashにも残る
        ```
        git stash pop
        ```
        ※作業内容がWorking directoryに戻り、stashにも残らない
        <br>
    - 作業内容をstashから消す
    ※popを使用すると、下記の作業は不要
        ```
        git stash drop
        ```
    - untrackファイルの作業内容も含めてstashする
        ```
        git stash -u
        ```
        ※これで、trackファイルとuntrackファイルのどちらもstashされる
        <br>
    - 特定のstashファイルの内容を確認する
        ```
        git stash show stash@<X>
        ```
        ※<>の中は```git stash list```した際の数字を入れる
    - gitignoreされているファイルの作業内容も含めてstashする
        ```
        git stash -a
        ```
    - メッセージをつけてstashする
        ```
        git stash save "<メッセージ>"
        ```
    ※stashされた件数が多い場合、数字だけではわかりにくいため、メッセージをつけてstashができる

# まとめ
見るだけでは、理解できないことも多いため、是非、ここで紹介したコマンドを実際に自分のPCで試して欲しい。また、何か要望や指摘があれば、修正するのでコメントしていただければと思う。
この記事を読んで、gitの理解が深まってくれたら嬉しく思います♡最後まで読んでいただきましてありがとうございました。

以上