GitHubチートシート

# はじめに
GitHubを用いて開発を進めていく上で必要なコマンド集です。
これらを使えればGitHubでの開発は問題なく進められると思います。
これほとんどGitHubじゃなくてGitの使い方だよってツッコミはなしでお願いします。

# 最初にしておくべき設定
## ユーザ設定
これをしておくとコミットしたときにcontributorとしてちゃんと表示されます。

```bash:terminal
git config -—global user.name “<GitHub user name>”
git config —-global user.email “<email address>”
```

## エイリアスの設定
頻繁に使用するコマンドはエイリアスを設定しておきましょう。
`st`で`git status`が使えたりして便利になります。

```bash:terminal
git config —-global alias.co checkout
git config —-global alias.st status
git config —-global alias.br branch
git config —-global alias.ci commit
git config --global alias.pu push
```

## コミットログの可視化

コミットログを綺麗に表示できるコマンドを用意しておきましょう。
`gr`というコマンドで綺麗なコミットログが確認できるようになります。

```bash:terminal
git config --global alias.gr "log --graph --date=short --decorate=short --pretty=format:'%Cgreen%h %Creset%cd %Cblue%cn %Cred%d %Creset%s'""
```

## `git push`のデフォルトの挙動

`git push`コマンドを使用したとき、プッシュ先を明示しないとプッシュできないようにしておきましょう。
`nothing`は`simple`(git ver.2.0からデフォルト)でも問題ないですが、僕は好みで`nothing`にしています。

```bash:terminal
git config --global push.default nothing
```

## Gitで使用するエディタを登録
コミットメッセージなどを編集するためのエディタに何を使うかを指定します。`vim`にしておくのが間違いないでしょう。

```bash:terminal
git config —-global core.editor vim
```

## コンソールに表示される文字に色をつける
コミットidや差分などをgitコマンドを用いてコンソールに表示したときに色がついて見やすくなります(初期値ではだいたい色がついているので必要ないかもしれません)。

```bash:terminal
git config --global color.ui true
```

## `.gitignore_global`の設定
ホームディレクトリに`.gitignore_global`というファイルを作成して無視したいファイルを書き込む。
このファイルの記述したファイルはGitが管理しなくなるので、OSが勝手に作成するGitで管理するべきでない`.DS_Store`や環境変数ファイルなどを無視することができます。
何を記述しておけば幸せになれるかは調べてみてください。開発環境によっても変わるので。
次のコマンドで`.gitignore_global`の設定を有効化します。
ちなみに、パスさえしっかり合わせればホームディレクトリに`.gitignore_global`を作成する必要はありません。

```bash:terminal
git config —-global core.excludesfile ~/.gitignore_global
```

この設定をする前に無視したいファイルを`git add`したことがあるなら、

```bash:terminal
git rm --cached <file name>
```

としてキャッシュを削除すればそれ以降無視してくれます。

# GitHub管理の始め方
## すでにGit管理されているプロジェクトに参加する
次のコマンドを実行するだけ。
`git clone`は`git init`と`git remote add`も一緒に実行してくれるコマンドなので、これをしたあとはプッシュもコミットもできるようになっています(やり方は後述)(`git init`や`git remote add`の説明も後述)。

```bash:terminal
git clone <Repository URL>
```

## ローカルにあるプロジェクトを新しくGitで管理する
まずはGit管理したいプロジェクトを置くためのリモートリポジトリをGitHub上に作成してください。
そしてGit管理したいプロジェクトのルートディレクトリで次のコマンド群を実行しましょう。

```bash:terminal
git init    # .gitを作成し、Git管理を開始
git remote add origin <Repository URL>    # 開発内容のプッシュ先を設定
git add .    # すべてのファイルをステージング
git commit -m "Initial commit"    # コミット
git push -u origin master    # プッシュ
```

## 新しくプロジェクトを開始し、Gitで管理する
上と同じようにリモートリポジトリを作成してください。
そしてGit管理したいプロジェクトのルートディレクトリで以下のコマンド群を実行しましょう。
上と同じように最初はmasterにプッシュしていますが、これ以降はブランチを切って開発するべきです。

```bash:terminal
git init
git remote add origin <Repository URL>
echo “# <project name>” > README.md
git add README.md
git commit -m “Initial commit”
git push -u origin master
```

# 開発を進める
## 新しくブランチを切って開発を開始する
`git branch`でmasterにいることを確認して、次のコマンドでブランチを作成、開発を始めます。

```bash:terminal
git checkout -b <new branch name>
```

## 開発内容をリモートのブランチにプッシュする
開発した内容は次のコマンド群でリモートブランチにプッシュします。

```bash:terminal
git add <file name>
git commit -m “<commit message>”
git push origin <branch name>
```

そして最初のプッシュをしたあとで「Compare and Pull Request」を選択してプルリクエストを作成します(これはいろんなやり方がありますが、僕はこれが一番いいと思います)。
プルリクの題名は何を開発するのかわかるように設定するといいでしょう。
概要には開発するべき理由や手法などを書くか、それを書いたissueを参照すると良いでしょう。
これ以降は開発内容についてプルリク上で会話していきます。
そうすれば、どのような実装をすると良いかプロジェクトのメンバーと相談してから実装に取り掛かることができるので、コーディングに無駄がなくなります。

## ブランチでの開発内容をmasterにマージする
PR上でmasterとのコンフリクトがなければこの作業はしなくても問題ありません(してもいいです)。
上の方法で開発内容をプッシュした後、

```bash:terminal
git fetch origin
```

としてローカルのmasterをリモートのmasterと同じ最新の状態に更新して、

```bash:terminal
git rebase -i origin/master
```

としてmasterへrebaseし、fast-forwardマージができるようにする。自動で起動するエディタは何も編集せずに保存して閉じます。
rebaseしたときにコンフリクトが発生したら、そのファイルのコンフリクトを修正し、以下の手順でそのファイルを`git add`してrebaseを続けます。

```bash:terminal
git add <file name>
git rebase --continue
```

そしてブランチ作成時に作成したプルリクエスト上でのプロジェクトメンバーによるコードレビューが終了したら、GitHubのプルリクエスト上の「Merge pull request」ボタンを押してmasterにマージします。

マージが成功し、マージコミットが作成されたら、

```bash:terminal
git push origin -d <branch name>
git branch -d <branch name>
```

としてリモートとローカルの開発ブランチを削除しましょう。
このあとは、また異なる開発内容でブランチを切って開発を継続していきましょう。

## リモートブランチをローカルにpullする
開発を進めていたブランチを別のマシンのローカルにpullして、その別のマシンで開発を再開したいときは`git pull origin master`してローカルのmasterを最新の状態にしたあとに、次のコマンドを実行すれば良い。

```bash:terminal
git branch <remote branch name> origin/<remote branch name>
```

## ローカルの追跡ブランチを最新状態にする

`git branch -a`とすると、追跡ブランチを含めたすべてのブランチが表示されます。
しかし、この中にはGitHub上では削除されている昔のブランチが混ざっていることがあると思います。
このリストを最新の状態に更新するには次のコマンドを実行します。

```bash:terminal
git fetch --prune
git branch -a    # 追跡ブランチを含めたすべてのブランチが最新状態に
```

## コミット履歴を修正する
### stagingを破棄し、直前のコミットの状態に戻す
テスト用に変更していた値などを、開発内容をプッシュしたあとに一括で戻すときなどに使うと便利です。
stagingしていた開発内容は直前のコミットの状態へ戻るので破棄されます。

```bash:terminal
git reset —-hard
```

ちなみに、`--hard`オプションをつけずに`git reset`すると、ワーキングエリアの内容は変更は直前のコミットの状態に戻りません。
これは間違ってファイルを`git add`してしまったときなどに便利です。

### コミットを削除する

```bash:terminal
git rebase -i <commit id>
```

とするとエディタが立ち上がり、入力した```<commit id>```より後のコミット一覧が表示されます。
その中で削除したいコミットの```pick```を削除し、保存してエディタを終了します。
コンフリクトが発生した場合は上述のmasterへrebaseしたときと同様に解決してください。
その後自分の開発ブランチにプッシュすると思いますが、そのときは以下のように```-f```オプションをつけてください。そうしないと```fast-forward```じゃないよと怒られてしまいます。
**このforce pushはmasterにはしないようにしましょう。**

```bash:terminal
git push -f origin <branch name>
```

### 直前のコミットを編集する

```bash:terminal
git add <file name>    # 直前のコミットに含めたいファイルがある場合に実行
git commit —-amend
```
とすると起動するエディタ上でコミットメッセージを編集できます。
この場合も上記の例と同じように```-f```オプションをつけて強制プッシュしてください。

## 編集内容を退避させる

「間違ってmasterブランチで作業してしまったが、その変更を元に戻して違うブランチでもう一度同じ作業をするのは嫌だ」、「あるブランチで作業していたが、違うブランチにcheckoutして今すぐ取り掛からないといけないタスクができてしまった」などの状況に遭遇した場合、```git stash```コマンドを利用すると便利です。

```bash:terminal
git stash
```
とすると、作業しているブランチでのコミットしていない変更内容を退避させることができます。
`git status`として確認してみると、変更内容がなくなっているのがわかります。

```bash:terminal
git stash list
```
とすると、今まで退避させた作業内容の一覧が表示されます。
退避させた変更内容を適用したいブランチへ```git checkout```したら、

```bash:terminal
git stash pop
```
として、最後に`git stash`した作業内容を現在のブランチへ適用します(いわゆる`LIFO: Last In, First Out`です)。
stashの退避内容を指定して適用したい場合は、

```bash:terminal
git stash apply <stash name like "stash@{0}">
```
とします。
ちなみに、

```bash:terminal
git stash drop <stash name>
```
とすると退避させた作業内容を削除できます。


# さいごに
これであなたもGitHubマスターだ！
ちなみに、`.gitignore_global`などの`.`から始まるファイルはドットファイル(`dotfile`)と呼ばれ、ターミナルの設定など様々な設定などに使用されます。
このように[GitHub](https://github.com/snowman-mh/dotfiles)で`dotfiles`というリポジトリを作って管理すると、新しいマシンの環境設定を行う際に便利です。