【60日目】今日から始めるGit/GitHubーーリモートリポジトリ編

# 1 GitHub
今日は昨日に引き続きGitの使い方ーリモートリポジトリ編となります。
昨日までの内容でローカル環境においてバージョン管理することができていると思います。
その内容を他の開発者と共有するための方法についてまとめました。

## 1.2 GitHubへの登録
学習段階ではリモートリポジトリとして、GitHubの無料版プライベートリポジトリを使用します。どうやら今年からプライベートリポジトリも無料化されたようです。圧倒的感謝！
https://github.com/join
からアカウントを登録します。

## 1.3 リモートリポジトリの作成
アカウントを作成したら「start a project」というボタンを押します。
押すと「Create a New Repository」というページに遷移します。
ここで下記の内容を設定します。

- owner　GitHubアカウント名が設定されます。
- Repository Name　ここではtutorialとします。アルファベットにした方が良いようです。
- Description　リポジトリの説明を書きます。
- ラジオボタンでパブリックかプライベートを選択します。

他の設定はgit ignoreに関する設定とライセンスに関する設定ですが一旦オフにしておきます。
上記を設定したらCreate Repositoryを押下します。

## 1.4 SSH keyの設定
パスワードよりもセキュリティが高い公開鍵認証という方法によって通信を行います。
GitHub側に公開鍵を配置し、ローカルリポジトリに秘密鍵を配置する認証方法です。
### 1.4.1 ローカル側の設定
cloud9のターミナルで下記のとおり入力します。

```
$ ssh-keygen -t rsa -b 4096 -C "GitHubアカウントのメールアドレス"
```

エンターすると、keyのファイル名を求められます。
ファイル名をデフォルトのままにする場合は空白でエンターします。

```
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ec2-user/.ssh/id_rsa): 
```

次にパスフレーズを求められます。
万が一秘密鍵が流出しても、パスフレーズがなければ認証できません。

```
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
```

エンターすると公開鍵が作成されます。
公開鍵は下記のコマンドで確認できます。

```
$ ls ~/.ssh
```

実行すると下記のように表示されます。

```
$ authorized_keys  先ほど入力したファイル名  先ほど入力したファイル名.pub
```

左が秘密鍵、右の.pubが公開鍵です。

### 1.4.2 公開鍵の登録
まず公開鍵をコピーします。ここではファイル名をデフォルトのまま進めます。


```
$ cat ~/.ssh/id_rsa.pub
```

とコマンドを打って表示される長い文字列をコピーします。
そしてGitHubの一番右上のアイコンからsettingを選択し、左側のカラムの「SSH and GPG keys」に進みます。

「New SSH key」を開き、titleをつけてkeyに貼り付けて、「Add SSH key」を押下します。
登録メールアドレスに通知が来ます。

SSHkeyは複数登録できるので、開発環境ごとに異なる鍵を使えます。

### 1.4.3 GItHubとの認証
下記のコマンドを入力します。

```
$ ssh -T git@github.com
```

接続を継続したいか尋ねられるので、yesとします。

```
The authenticity of host 'github.com (140.82.114.3)' can't be established.
RSA key fingerprint is XXXXXXX
RSA key fingerprint is XXXXXXX
Are you sure you want to continue connecting (yes/no)?  yes # yesと入力
```

 先ほど設定したパスフレーズを入力すれば接続完了です。

# 2 リモートリポジトリへのプッシュ
プッシュとは、ローカルリポジトリの状態をリモートリポジトリに更新し、共有することです。

## 2.1 リモートリポジトリの登録
プッシュしたいディレクトリで下記のコマンドを実行します。

```
$ git remote add origin 追加先のリモートリポジトリのURL
```

リモートリポジトリのURLはGitHubのホームから取得することができます。
これによって、今後は「origin」という識別子でリモートリポジトリのURLを指すようになります。

## 2.2 リモートリポジトリへのプッシュ
登録したリモートリポジトリにマスターブランチの状態をプッシュします。
まずマスターブランチに移動し、現在位置がマスターブランチになったことを確認します。

```
$ git checkout master
$ git branch -a
```

git pushコマンドでプッシュします。

```
$ git push -u origin リモートリポジトリのブランチ名
```

認証情報を確認されるので入力し、下記のように表示されればプッシュ成功です。
指定したブランチがない場合、ブランチが追加されます。

```
Counting objects: 24, done.
Compressing objects: 100% (21/21), done.
Writing objects: 100% (24/24), 1.99 KiB | 254.00 KiB/s, done.
Total 24 (delta 5), reused 0 (delta 0)
remote: Resolving deltas: 100% (5/5), done.
To https://github.com/username/repository_name.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
```

プッシュが成功すると、GitHubのリモートリポジトリのディレクトリ内にローカルリポジトリの内容が更新されているのが確認できます。

# 3 リモートリポジトリのクローン
リモートリポジトリの内容を手元の開発環境にそのまま持ってくることができます。

まず、配下にローカルリポジトリを置きたいディレクトリに移動します。
例えば /git_repositories/tutorial という構造でtutorialディレクトリをローカルディレクトリとしたい場合、

```
cd git_repositories
```

 に移動して、下記コマンドを実行します。
 リモートリポジトリのURLはGitHubの「Clone or download」ボタンから取得できます。

```
$ git clone クローンしたいリモートリポジトリのURL  任意のローカルリポジトリ名
```

認証情報を確認されるので入力し、

```
remote: Enumerating objects: 24, done.
remote: Counting objects: 100% (24/24), done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 24 (delta 5), reused 24 (delta 5), pack-reused 0
Unpacking objects: 100% (24/24), done.
```

のように表示されれば成功です。
実際にgit_repositories配下にtutorial_2というクローンされたローカルリポジトリが生成されています。

# 4 リモートリポジトリからのプル
## 4.1 リモートリポジトリとの差分の確認
まず最初にリモートリポジトリとの差分を確認します。
git fetchコマンドでリモートリポジトリの状態をローカルリポジトリに持ってきて、その後でdiffをとります。

```
$ git fetch [リポジトリ] (ここではoriginとしました)
```

と入力し、認証情報を入力して、指定したリポジトリのデータを取得します。
データを取得するだけで、直ちにはローカルリポジトリの状態を更新することはありませんが、必要に応じて取得したデータに基づいてマージできます。

今回はひとまずリモートリポジトリのマスターブランチとの差分を見たいので、

```
$ git diff origin/master
```

と入力することで、指定したリポジトリ/ブランチのデータとの差分を取れます。
リモートリポジトリにローカルリポジトリが遅れていることが確認できたら、リモートリポジトリの状態をローカルリポジトリに同期する必要があります。

## 4.2 リモートリポジトリからのプル
リモートリポジトリの状態をローカルリポジトリに反映するには、

```
$ git pull
```

と入力し、認証情報を入力します。

念の為

```
$ git log --graph
```

などでログを確認しておくと良いでしょう。

## 4.3 pullとcloneの違い
git pullコマンドは書き下すと「git fetchとgit merge origin/masterを実行してくれる便利コマンド」のことです。
一方で、git cloneコマンドは「mkdirしてgit initしてリモートトラッキングブランチの作成、git pullをしてくれるコマンドで」といった感じです。
簡単に言えば、cloneはclone元からpullできるように、リモートリポジトリとローカルリポジトリのブランチ間の設定をしてくれるということ。

gitの公式ページを見ると

>Clones a repository into a newly created directory, creates remote-tracking branches for each branch in the cloned repository (visible using git branch --remotes), and creates and checks out an initial branch that is forked from the cloned repository’s currently active branch.(https://git-scm.com/docs/git-clone 20/10/2019訪問)

と書かれています。

より正確に表現すると、

```
$ mkdir repo
$ cd repo
$ git init
$ git remote add origin git://github.com/cmcculloh/repo.git
$ git cofig branch.master.merge refs/heads/master 
$ git config branch.master.remote origin
$ git fetch --all
$ git merge origin/master
```

ということをやってくれるコマンドのようです(正確に理解できていないので、間違いあったらご指摘ください！)
この辺まだよく分かっていないので、今後使っていく中ではとりあえずgit cloneしようと思います。
何か問題が起きた場合に解決方法として記事にすると思います。