【Git】新人エンジニア、git pushまでの道

# はじめてのgit push

私事ですが、8月からWebエンジニアとして企業で働いています。

先日１つの作業を終えて``git push``しようとしましたが、驚くほどgitコマンドを忘れていました。その時は先輩に一通り教えてもらい、作業自体は無事に終了することができましたが(´；ω；`)

知識はあったのに、どこで・どのように・どんな理由でgitコマンドを使用するのかが分からなかった、というのが本音です。

今回はその時に使用したgitコマンドを振り返り、コマンドそのものと言うよりも、作業の流れ自体をおさらいしようと思います。

似たような内容で以前にも記事を作成してました。今回は、内容がより実践的になるかと。

> [【GitHub】アプリのバージョン管理を行う](https://qiita.com/33yuki/items/067714d9adec6a6b69d8)

# リポジトリ作成〜コミット
## init
リポジトリを作成します。（初期化する？）

ここでは``git_testディレクトリ``にリポジトリを作成しています。

```git
$ cd git_test
$ git init
Initialized empty Git repository in /Users/yuki/workspace/git_test/.git/
```

## add
コミットしたいファイルをステージングさせます。``-Aオプション``で現在のディレクトリ以下の全ファイルを選択可能です。

ファイル別にコミットしたい場合は、ファイル名を指定します。

```
$ git add test.html
```

## commit

コミットします。``-mオプション``でコミットメッセージを添えています。

```
$ git commit -m "first commit"
[master (root-commit) aba6a83] first commit
 1 file changed, 9 insertions(+)
 create mode 100644 test.html
```

# リモートリポジトリに反映
リモートリポジトリはGitHubを使用。あらかじめリポジトリを作成しておきます。

## remote add
指定した名前にリモートリポジトリのアドレスを関連付けます。

リモートリポジトリはネット上に存在するため、ローカルリポジトリとのやり取りを行う時は、アドレス（パス）を指定する必要があります。

作業の都度アドレスを指定するのも大変なので、ここで``origin``という名前と関連付け、以後``origin``として扱えるようにしています。

```
$ git remote add origin git@github.com:ユーザー名/リポジトリ名.git
```

## push
リモートリポジトリに変更を書き込みます。

originの``masterブランチ``にコミットの内容を反映させます。

```
$ git push origin master
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 308 bytes | 308.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:ユーザー名/リポジトリ名.git
 * [new branch]      master -> master
```

# ブランチの切り出し

先ほどまで使用したブランチは、すべて``masterブランチ``です。今度はmasterとは別のブランチを切り出し、それをリモートリポジトリのmasterブランチに反映させるまでを追ってみます。

ブランチの切り出し方の基準はよく分からないのですが、ここでは``developブランチ``を用意します。

## branch（その１）
指定する名前のブランチを作成します。ブランチ作成と同時にカレントブランチとして使用したい場合は、``git checkout -b ブランチ名``となります。

今回作成する``developブランチ``は、``masterブランチ``と同じ内容になります。

```
$ git branch develop
```

## checkout
指定したブランチへ移動します。

```
$ git checkout develop
Switched to branch 'develop'
```

## branch（その２）
現存するすべてのブランチとカレントブランチを確認できます。

ここではブランチはmasterとdevelopの２つが存在し、今はdevelopブランチにいるよ、という意味です。

```
$ git branch
* develop
  master
```

この``developブランチ``で作業を行います。

## status
変更が加えられたファイルを表示します。

developブランチで新しく作業を行なったため、その対象である``test.html``が表示されています。

```
$ git status
On branch develop
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:   test.html

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

``git status``の結果の見方と、変更の基準となるタイミングがわかりにくいです。こちらの記事が参考になります。

> [Git の基本 - 変更内容のリポジトリへの記録](https://git-scm.com/book/ja/v1/Git-の基本-変更内容のリポジトリへの記録)

## diff
前回のステージングから変更が生じた箇所を、差分として表示します。ファイル名を指定して実行することも可能です。

``test.html``のどの部分に変更があったか、上下に比較表示されています。

```
$ git diff
diff --git a/test.html b/test.html
index d1e9fdb..5bd36cc 100644
--- a/test.html
+++ b/test.html
@@ -6,6 +6,6 @@
   <body>
     <p>git_test</p>
     
-    
+
   </body>
 </html>
```

一見差分が無さそうに見えても、不可視文字が影響している場合もあります。

> [【Atom】git diffで判明した不可視文字（タブ・スペース）の対処方法](https://qiita.com/33yuki/items/bb04d68a7f24f8a0a70b)

問題がなければ、``git add``で該当ファイルをステージングします。

```
$ git add test.html
```

コミットしましょう。

```
$ git commit -m "second commit"
[develop 9701c20] second commit
 1 file changed, 2 insertions(+)
```

リモートリポジトリへ``git push``します。今回のプッシュ先は``developブランチ``になります。

```
$ git push origin develop
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 293 bytes | 293.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To github.com:ユーザー名/リポジトリ名.git
   aba6a83..9701c20  develop -> develop
```

# リモートリポジトリのmasterブランチに反映

次はローカルリポジトリの``masterブランチ``を操作します。``git checkout``で移動します。

```
$ git checkout master
Switched to branch 'master'
```

## pull
リモートリポジトリとローカルリポジトリの同期を行い、ローカルリポジトリのブランチに変更を取り込みます。

複数人で作業している場合、リモートリポジトリを共通で使用することになります。そのため、自分が作業している間も、他の誰かがmasterブランチを更新しているかもしれません。

そのため、最初にリモートリポジトリのmasterブランチから最新の状態を取得し、それをローカルリポジトリのmasterブランチに反映させておきます。（今回は何も変更がありませんが。）

```
$ git pull origin master
From github.com:ユーザー名/リポジトリ名
 * branch            master     -> FETCH_HEAD
Already up to date.
```

ちなみに``git pull``は、``git fetch（リモートリポジトリとローカルリポジトリの同期）``と``git merge（取り込み）``を合わせたコマンドなのです。

## merge
他のブランチの内容を取り込みます。

ローカルリポジトリにおいて最新の状態にしたmasterブランチに、developブランチの内容を取り込みます。

これでリモートリポジトリに``git push``する準備ができました。

```
$ git merge develop
Updating aba6a83..9701c20
Fast-forward
 test.html | 2 ++
 1 file changed, 2 insertions(+)
```

masterブランチの内容をリモートリポジトリにpushします。これで作業終了です。

```
$ git push origin master
Total 0 (delta 0), reused 0 (delta 0)
To github.com:ユーザー名/リポジトリ名.git
   aba6a83..9701c20  master -> master
```

基本、masterブランチで変更作業を行うことはありません。最後にdevelopブランチに戻り、作業を継続しましょう。

```
$ git checkout develop
Switched to branch 'develop'
```