【GitHub】開発フロー

Githubでチーム開発するための、開発フローになります。
Githubを利用する際の参考にして頂ければと思います。

この記事ではGithubアカウントが作成済みであることを前提としています。
また、ブランチはGithubフローで運用するものとします。

# 開発フロー

## プロジェクト参加直後に必要な作業

1. Gitの設定を行う
2. forkする
3. cloneする
4. upstream（fork元リポジトリ）を設定する

## 開発サイクルの中で繰り返し行う作業

1. Milestoneを作成する
2. Issueを作成する
3. branchを作成する
4. 空のcommitを作成する
5. 空のcommitをpushする
6. タイトルのプレフィックスに[WIP]を付けPull Requestする
7. レビュアーをAssigneesに設定する
8. 作業内容をcommit、pushする
9. localのmasterを最新にする
10. branchをrebaseする
11. branchの更新があった場合は、force pushする
12. Pull Requestのタイトルに付けた[WIP]を外し、レビュアーへmentionを送る
13. レビュー、指摘内容の修正を行う
14. masterへマージする

## Gitの設定を行う
Gitの個人情報を設定します。
この設定を忘れると、commit時のユーザー情報がGithub上で正しく表示されません。

設定を行うためのコマンドは以下になります。

```
$ git config --global user.name "EnoMt"
$ git config --global user.email EnoMt@example.com
```

## forkする

![スクリーンショット 2016-08-02 18.05.44.png](https://qiita-image-store.s3.amazonaws.com/0/133918/76dfb177-325c-61e4-c3f4-fb4a0a367b24.png "スクリーンショット 2016-08-02 18.05.44.png")

Webブラウザにて、forkするプロジェクトのGithubページを表示し、右上「fork」
ボタンを押下します。
fork後、自分のGithubアカウント内にプロジェクトのリポジトリが追加されます。

## cloneする

![スクリーンショット 2016-08-02 18.24.32.png](https://qiita-image-store.s3.amazonaws.com/0/133918/a5529448-0c72-b86a-b65d-adef3c4b33a3.png "スクリーンショット 2016-08-02 18.24.32.png")

自分のアカウント内のリポジトリにて、Clone or download -> Copy to clipboardでURLをコピーし、任意のディレクトリで以下のコマンドを実行します。

```
$ git clone https://github.com/~
```

## upstream（fork元リポジトリ）を設定する
localのmasterがfork元リポジトリのmasterを追跡できるようにする必要があります。（自動では追跡してくれません）
自分のリポジトリにデフォルトのoriginという名前が使用されているため、慣習的にupstreamという名前を付けることが多いです。

```
$ git remote add upstream https://github.com/~
```

## Milestoneを作成する

Milestoneは一つの開発サイクル毎に作成します。IssueにMilestoneを紐付けることで、進捗率の管理やIssueの漏れを防ぐことができます。

また、Milestoneは基本的に変更不可になるので、Milestoneに紐付いたIssueが期限に遅れた場合、積み残しタスクとして別のMilestoneに紐付けし直す運用がいいかと思います。

## Issueを作成する

追加機能やバグは全てIssueで管理します。
Issueには必ず、Milestone、Assigneesを設定します。Assigneesに設定された担当者が実装を行います。
また、Labelには追加機能の場合「enhancement」、バグの場合「bug」を設定します。

## branchを作成する

branchはIssue毎に作成します。
branchを作成する前に、masterを最新の状態にする必要があります。

```
# branchをmasterに切り替える
$ git checkout master

# upstreamから最新の状態を取得する
$ git pull upstream master
```

masterからbranchを作成します。

```
$ git checkout -b EnoMt/entry_dialog
```

ブランチ名は、\<Githubのユーザー名>/<機能名( _ 区切り)> で作成します。

## 空のcommitを作成する

コミットメッセージを「[WIP] + 機能名 + (Issue番号)」とし、commitとします。

```
$ git commit --allow-empty -m "[WIP] entry dialog (#1)"
```

## 空のcommitをpushする

```
$ git push origin EnoMt/entry_dialog
```

## タイトルのプレフィックスに[WIP]を付けPull Requestする

自分のGithubアカウント内のレポジトリを表示し、branchを切り替えます。

![スクリーンショット 2016-08-02 19.43.39.png](https://qiita-image-store.s3.amazonaws.com/0/133918/9af53699-be64-aac6-fbe3-b74136434f25.png "スクリーンショット 2016-08-02 19.43.39.png")

New pull requestを押下します。

Pull Requestのタイトルに空のコミットで設定したメッセージが記載されていることを確認し、Create pull requestを押下します。


## レビュアーをAssigneesに設定する

Pull RequestのAssigneesにレビュアー担当者を設定します。

作業開始前にレビュアーをAssigneesに設定することで、実装担当者が作業開始したことをレビュアーが知ることができます。
また、レビュアーが作業内容を追いやすくなるため、相談が必要な作業の場合にも円滑に作業をすすめることができます。

※Pull RequestにIssueと同様のMilestoneとLabelを設定しておくとフィルタリングが楽になります。

![スクリーンショット 2016-08-03 16.43.47.png](https://qiita-image-store.s3.amazonaws.com/0/133918/857cdc39-6820-d876-fa4a-b40fe6f3b615.png)

## 作業内容をcommit、pushする

commitは出来る限り小さい単位で行います。
commitの単位を小さくすることで、不具合の発生原因が追いやすくなったり、レビューがしやすくなります。

レビュー者の混乱をさけるため、実装担当者の試行錯誤の過程はcommitに含めないようにします。
※作業中の時点で試行錯誤の過程が含まれていても問題ありませんが、レビュー依頼する時には、試行錯誤の過程はcommitから除いた方がいいです。

また、コミットメッセージは全て英語で記述するようにします。英語の文章を考える練習にもなります。
※文末のピリオドは不要です。

### コミットメッセージ

コミットメッセージは以下の規則に従って記載します。

・バグ修正

```
# Fix + [修正内容] + (Issue番号)
ex) Fix entry dialog (#1)
```

・機能追加

```
# Add + [追加内容] + (Issue番号)
ex) Add entry dialog (#1)
```

・機能変更

```
# Update + [変更内容] + (Issue番号)
ex) Update entry dialog (#1)
```

・ファイル削除

```
# Remove + [削除ファイル] + (Issue番号)
ex) Remove EntryDialog.kt (#1)
```


・リネーム

```
# Rename + [以前の名前] to [現在の名前] + (Issue番号)
ex) Rename a to b (#1)
```

### コミットメッセージ文字数

コミックメッセージが72文字を超える場合には、2行目を空行にし3行目以降にコミットメッセージを記載します。
※3行目以降も72文字を超えないようにする必要があります。
→3行目も72文字を超える場合、一度コミットメッセージを見直した方がいいかもしれません。

## localのmasterを最新にする

```
# branchをmasterに切り替える
$ git checkout master

# upstreamから最新の状態を取得する
$ git pull upstream master
```

## branchをrebaseする

```
# branchを作業branchに切り替える
$ git checkout EnoMt/entry_dialog

# rebaseする
$ git rebase master
```

## branchの更新があった場合は、force pushする

branchの更新があった場合、rebase後、commitが編集されてしまうため、通常のpushが使用できないため、force pushする必要があります。

```
$ git push -f origin EnoMt/entry_dialog
```

## Pull Requestのタイトルに付けた[WIP]を外し、レビュアーへmentionを送る

以下のようにレビュアーへmentionを送ります。mentionが届いた後は、レビュアーは実装レビューを行います。

## レビュー、指摘内容の修正を行う

指摘があった場合はその内容をコメントに記載します。

## masterへマージする

レビュー完了後、レビュアーがmasterへマージします。
この時、Pull Requestのコメントに以下を記載するようにします。

```
// close + [Issue番号]
close #1
```

こうすることで、masterへのマージと同時にIssueを閉じることができます。

また、masterへのマージが完了した後はbranchを削除します。
※マージ完了画面にて「Delete branch」ボタンを押下すると、branchが削除されます。