Git CLI チートシート

この記事では, コマンドラインでの Git 操作についてまとめています.  
自分用のメモ的な要素が大きいですが, 基本操作を網羅し辞書のように使えることを目的にまとめました.

# 1. はじめに
## 1.1 記事作成のモチベーション
記事作成時点で恥ずかしながら GUI 形式の Source Tree を Git 操作のメインで使っています. サーバーで Git 操作をすることが多くなり, 都度調べたりしていたのですが面倒になってきたので記事にまとめておこうと思いました.

## 1.2 対象読者
- Git の基本的な概念や用語を理解できている方.
- Source Tree での git 操作がメインの方.
- CLI での git 操作が苦手な方.
- CL での git 操作をこれから習得しようとされている方.

# 2. 本編
お決まりの図です.
![AbstractFigure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245318/3d56b0bf-e1de-d281-48de-a4a9683cf9e7.png)


## 2.1 Repository の新規作成/基本設定
### 1) Remote Repository を作成する (init)
Gtithub や Bitbucket の web 上で作成します.   
作成方法に関してはググってください.  

共用サーバーに Remote Repository を作成する場合は, bare オプション(working tree を持たない設定)をつけて以下のコマンドを実行します.

```bash
$ git init --bare /path/for/repo
```

### 2) Local Repository を作成する (init)
Git 管理したいディレクトリに移動して以下のコマンドを実行します.

```bash
$ git init

# Output Message:
# >> Initialized empty Git repository in {YOUR_REPOSITORY_PATH}/.git/
```

### 3) Remote Repository を追加する (add)
```bash
$ git remote add {REPOSITORY_NAME_IN_LOCAL} {URL_OR_PATH_FOR_REMOTE_REPOSITORY}

# e.g.
# git remote add origin {URL_OR_PATH_FOR_REMOTE_REPOSITORY}
# git remote add upstream {URL_OR_PATH_FOR_REMOTE_REPOSITORY}
```
{REPOSITORY_NAME} は Local Repository 内での Remote Repository の名称です

### 4) Remote repository を取得する (clone)
```bash
$ git clone {URL_OR_PATH_FOR_REMOTE_REPOSITORY}
```

リモートのディレクトリ名と別名で取得したい場合

```bash
$ git clone {URL_OR_PATH_FOR_REMOTE_REPOSITORY} {LOCAL_NAME}
```

### 5) Remote Tracking Branch を設定する
```bash
$ git branch -u {REMOTE_NAME}/{REMOTE_BRANCH_NAME} {LOCAL_BRANCH_NAME}
```

## 2.2 Repository / Working Tree / Staging Area の履歴・状態確認
### 1) Commit 履歴を確認する (log)
- Local Branch のコミット履歴を表示する

```bash
$ git log
```
- Remote Branch の履歴を表示する

```bash
$ git log {REPOSITORY_NAME}/{BRANCH_NAME}
```
- よく使うオプション
  - グラフィカルにコミット履歴を表示する
  
  ```bash
  $ git log --graph
  ```
  - 簡易表示(コミット情報をコミットIDとメッセージのみの 1 行にする)
  
  ```bash
  $ git log --oneline
  ```
  - 表示するコミット数を制限する
  
  ```bash
  $ git log -{NUM_COMMITS}
  ```
  - 各コミットで反映された変更点を直近 NUM_COMMITS 個だけ表示する
  
  ```bash
  $ git log -p -{NUM_COMMITS}
  ```

### 2) Branch の状態を確認する (branch)
- ローカルブランチのみ

```bash
$ git branch
```
- リモートブランチも含めて確認する

```bash
$ git branch -a
```

### 3) Local の変更状態を確認する (status)
- 基本

```bash
$ git status
```
- 出力例

```
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   file_2.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   file_1.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        file_3.txt
```
- 説明
  - On branch {BRANCH_NAME}
      - 現在の Branch 名
  - Changes to be committed
      - Staging Area に追加されたファイル一覧
  - Changes not staged for commit
      - git 管理されているファイルで, Staging Area に追加されていないファイル一覧
  - Untracked files
      - git 未管理(新規追加など)で Staging Area に追加されていないファイル一覧

- よく使うオプション
  - 簡易表示
  
  ```bash
  $ git status -s
  ```
  - ブランチ名を含めて簡易表示
  
  ```bash
  $ git status -sb  
  ```

## 2.3 Local Repository に関する操作
### 1) Working Area から Staging Area に追加する (add)
- 全てのファイルを Index に追加（__新規作成されたファイル, 削除されたファイルも含めて追加される.__）

  ```bash
  $ git add -A
  $ git add --all
  ```
- 選択したファイルを Index に追加

  ```bash
  $ git add {FILE_NAE}
  ```
- よく使うオプション
  - Working Tree 内のバージョン管理されているファイル (modified) をすべて Index に追加する. __新規作成されたファイル, 削除されたファイルは追加対象外.__
  
    ```bash
    $ git add -u
    $ git add --update
    ```
  - カレントディレクトリ以下の全ての変更されたファイルを Index に追加する
  
    ```bash
    $ git add .
    ```
  - 作業ツリーの変更の一部 (partial) を Index にステージする
  
    ```bash
    $ git add -p {FILE_NAE}
    ```
    - hunk 毎に stage するか聞かれるので, 対話式で回答していく.  
    - 以下の記事が参考になった.
      - https://qiita.com/cotton_desu/items/bf08ac57d59b37dd5188

### 2) Staging Area から Working Tree に戻す (reset)
- 全てのファイルを Working Tree に戻す

  ```bash
  $ git reset
  ```
- 特定のファイル or ディレクトリを Working Tree に戻す

  ```bash
  $ git reset {FILE_PATH1} {FILE_PATH2} ...
  $ git reset /{DIR_NAME}/
  ```

### 3) 変更を破棄する (checkout / reset)
- 特定のファイルの変更を破棄する

  ```bash
  $ git checkout {FILE_PATH1} {FILE_PATH2} ...
  ```

- 変更された全ての変更を破棄する

  ```bash
  $ git checkout .
  ```

- 最新の commit まで戻る (Working Tree / Staging Area を破棄)

  ```bash
  $ git reset --hard
  ```

### 4) 編集済みファイルの差分を確認する (diff)
- Staging Area と Working Tree の diff を確認する

  ```bash
  $ git diff
  ```
- 最新の Commit と Staging Area の diff を確認する

  ```bash
  $ git diff --staged
  ```

- git diff は奥が深すぎるので詳細は以下の Qiita の記事を参考にしてください. 本記事でも参考にさせて頂きました.
  - https://qiita.com/shibukk/items/8c9362a5bd399b9c56be

### 5) コミットする (commit)
```bash
$ git commit -m "add your comment here"
```

### 6) 別の Commit を Cherry Pick する (cherry pick)
- 特定の commit をチェリーピックする
-
  ```bash
  $ git cherry-pick {COMMIT_HASH}
  ```

- 複数のコミットをまとめてチェリーピックする
  - COMMIT_HASH_A+1 ~ COMMIT_HASH_B までのコミットがチェリーピックされる
  
    ```bash
    $ git cherry-pick {COMMIT_HASH_A}..{COMMIT_HASH_B}
    ```

### 7) 現在のブランチを指定の Commit まで戻す (reset)
つまりコミットの取り消し.

- commit のみ戻す (working tree, stagint area は維持)

  ```bash
  $ git reset --soft {COMMIT_HASH}
  ```

- commit と add のみ戻す (変更は working tree で維持される)

  ```bash
  $ git reset --mixed {COMMIT_HASH}
  ```

- 全てを戻す

  ```bash
  $ git reset --hard {COMMIT_HASH}
  ```
  - COMMIT_HASH の代わりに以下を指定しても良い
    - HEAD^：　直前のコミット
    - HEAD~{n}：　n個前のコミット

### 8) 指定したコミット時点のファイル状態を復元する
```bash
$ git checkout {commit id} {filename}
```

### 9) コミットの打消し (revert)
```bash
$ git revert {COMMIT_HASH}
```

### 10) コミットメッセージの修正
```bash
$ git commit --amend -m "new comment"
```

## 2.4 Stash 操作
### 1) Stash に追加する
```bash
$ git stash {STASH_NAME}
```

### 2) Stash に保存していた変更を現在の作業ツリーに取り込む
- stash 一覧を見る

```bash
$ git stash list
```

- stash から戻す

```bash
$ git stash apply stash@{STASH_INDEX}
```

- stash から Index に追加した変更は Index として戻す

```bash
$ git stash apply stash@{STASH_INDEX} --index
```

### 3) Stash を削除する
```bash
$ git stash drop stash@{STASH_INDEX}
```

## 2.5 ブランチ操作
### 1) 既存のブランチを指定してチェックアウトする
```bash
$ git checkout {BRANCH_NAME}
```

### 2) 新規ブランチを作成してチェックアウトする
- 現在の HEAD からチェックアウト

```bash
$ git checkout -b {NEW_BRANCH}
```
- コミットを指定してチェックアウト

```bash
$ git checkout -b {NEW_BRANCH} {COMMIT_HASH}
```

### 3) リモートブランチをローカルにチェックアウトする
```bash
$ git checkout -b {LOCAL_BRANCH_NAME} {REMOTE_NAME}/{REMOTE_BRANCH_NAME}
```

### 4) ブランチをマージする(merge)
現在の HEAD が属するブランチにマージされる

```bash
$ git merge {BRANCH_NAME}
```

### 5) Remote に Push する (Push)
- 指定したブランチを push

  ```bash
  $ git push  {REMOTE_NAME} {LOCAL_BRANCH_NAME}
  ```

- 指定したブランチを Push (REMOTEに別名ブランチを作る場合)

  ```bash
  $ git push  {REMOTE_NAME} {LOCAL_BRANCH_NAME}:{REMOTE_BRANCH_NAME}
  ```

- 全てのブランチを Push

  ```bash
  $ git push --all {REMOTE_NAME}
  ```

### 6) Remote から Fetch する (Fetch)
```bash
$ git fetch {REMOTE_NAME}
$ git fetch {REMOTE_NAME} {BRANCH_NAME}
$ git fetch --all
```
### 7) Remote から Pull する (Pull)
- 現在のローカルブランチに特定のリモートブランチを pull する

```bash
$ git pull {REMOTE_NAME} {REMOTE_BRANCH_NAME}
```

- 特定のリモートブランチを特定のブランチに pull する

```bash
$ git pull {REMOTE_NAME} {REMOTE_BRANCH_NAME}:{LOCAL_BRANCH_NAME}
```

- 現在のローカルブランチに Remote Tracking ブランチを pull する

```bash
git pull
```

### 8) ブランチを削除する
delete オプションを使う

- ローカルブランチを削除

  ```bash
  $ git branch --delete {BRANCH_NAME}
  ```

- リモートブランチを削除

  ```bash
  $ git push {REMOTE_NAME} --delete {REMOETE_BRANCH_NAME}
  ```

## 参考文献
本編内で引用させて頂いた記事の一覧です.

- git diff
  - https://qiita.com/shibukk/items/8c9362a5bd399b9c56be
- git add -p
  - https://qiita.com/cotton_desu/items/bf08ac57d59b37dd5188