【Git】ブランチ作成&ファイル編集後にリモートのmasterが変更されたとき

ローカルリポジトリで新規ブランチ作成後、リモートリポジトリのmasterが変更された時の流れをメモしました。

ローカルリポジトリであらかじめコンフリクトを解消してから、プルリクエストを作成します。新規ブランチは``develop``とします。

# ブランチの変更を保存する
ブランチでcommitを行っておきます。ブランチが複数ある場合は、それぞれのブランチでcommitします。

ローカルリポジトリの``HEAD(最新コミット)``と差分があるファイルを確認します。

```
$ git status
```

該当ファイルをステージングします。

```
$ git add .
```

パス指定・オプションについてはこちらの記事が参考になります。
>[Gitコマンドについて調べる【git add】](http://kimromi.hatenablog.jp/entry/2015/08/04/082357)

追跡対象外のいらないファイルがあれば、以下のコマンドで削除します。
削除前に``nオプション``で対象のディレクトリ、ファイルを確認した方が良いそうです。

>[git cleanでUntracked files(未追跡ファイル)をまとめて削除)](https://easyramble.com/how-to-use-git-clean.html)

```
$ git clean -df -n 
```

commitします。

```
$ git commit　-m　'コミットメッセージ'
```

# masterブランチを最新にする
masterブランチへ切り替えます。

```
$ git checkout master
```

commitすべきファイルが残っていないか確認します。

```
$ git status
```

pullします。

```
$ git pull　origin　master
```

これでローカルのmasterブランチが最新の状態になりました。

# ブランチを最新にする

変更分は既にcommitしてあります。次はブランチを最新の状態にします。

先ほど最新の状態にしたローカルブランチのmasterをmergeします。

```
$ git checkout develop
$ git merge master
```

コンフリクトが発生したら修正し、再度addとcommitを行います。
commitせずにもう一度mergeしようとすると、このようなエラーが出ます。

```
$ git merge master
error: Merging is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add/rm <file>'
hint: as appropriate to mark resolution and make a commit.
fatal: Exiting because of an unresolved conflict.
```

コンフリクトはmasterとブランチのどちらを優先させても、addとcommitが行われていれば解消とみなされるようです。
このメッセージが出ればひとまず大丈夫です。

```
$ git merge master
Already up to date.
```

最後にブランチをプッシュし、プルリクエストを作成します。

```
$ git push origin develop
```

コンフリクトが原因でプルリクエストが作成できないこともあるそうです。
>[プルリクエスト時に競合した時の対処方法](https://qiita.com/hituziando/items/c10b971f58f5c5031b1d)

この後リモートリポジトリのmasterがブランチをpullできたら、それをローカルリポジトリのmasterがpullし、そこから別のブランチを・・・という流れかと思います。

# git fetchとは？
ここまでの作業で、add, commit, push, pull, mergeは使用しましたが、fetchは使用しませんでした。``pull=fetch+merge``と聞きますが、コマンドを実行したことがないのでイマイチ実感がわきません；

それについては、こちらの記事が参考になりました。
>[git fetchの理解からgit mergeとpullの役割](https://qiita.com/osamu1203/items/cb94ef9da02e1ec3e921)

>[gitのふわっとした知識を調査してみた](https://nekosoftware.wordpress.com/2015/02/03/git%E3%81%AE%E3%81%B5%E3%82%8F%E3%81%A3%E3%81%A8%E3%81%97%E3%81%9F%E7%9F%A5%E8%AD%98%E3%82%92%E8%AA%BF%E6%9F%BB%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/)

>[Git で「追跡ブランチ」って言うのやめましょう](https://qiita.com/uasi/items/69368c17c79e99aaddbf)

``master``と``origin/master``と``origin master``の理解がふわふわでした・・・

fetchで更新されるのはリモート追跡ブランチ``origin/master``だけで、mergeがその情報をもとに作業ディレクトリへ変更を取り込んでいたんですね。

# ファイルの削除&名前変更時の注意点

リモートリポジトリに``test.html``が存在し、それをローカルで削除した（もしくは名前を変更した）場合、ステージングの状態はこうなります。

```
$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	deleted:    test.html

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

	test_01.txt
	test_02.txt
	testdir/

no changes added to commit (use "git add" and/or "git commit -a")
```

このままaddを実行すると、``deleted:    test.html``としてステージングされます。

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

	deleted:    test.html
	new file:   test_01.txt
	new file:   test_02.txt
	new file:   testdir/test_03.txt
```

続けてcommitとpushを実行すると、リモートリポジトリの``test.html``は削除されてしまいます。

addの後は必ずステージングの状態を確認した方が良いですね・・・