NITICNoobsによるGit/GitHub講座 第6回 GitHub入門編

# どうも

**[ko](https://twitter.com/ko_CottonLove)** と申します。
春からぷよぐやみんぐを始めた身ながら未だなんもできません。
**[限界開発鯖](https://approvers.dev)**の底辺でクソBotを作ったりしています。

今回はGitHubの解説を担当させていただきたいと思います。対戦よろしくお願い致します。

※この記事は**茨城高専生2I向け**に書かれたものです。

　**実際に手を動かしながら読み進めてくれると嬉しいです。**

# お説明

※前回までの説明を理解していること前提で説明をしていきます

今回の記事では、

- **GitHub**について
- **リモートリポジトリ**とは
    - ローカルリポジトリと何が違うの？
- **`push`**について
- GitHubに**リモートリポジトリを作成**し、**`push`**するまでの流れ
    - **`clone`**とは
    - `push` コマンドの詳細
    - `.gitignore`について

主に以上の点について説明していきます。

※以下で`Git Bash`と出てきますが、`コマンドプロンプト`でも同様の操作ができます。

## GitHubとは

GitHubとは、**Gitリポジトリ**をインターネット上に共有し、
様々な利点とともに開発を行えるリポジトリホスティングサービスとなっています。
類似のサービスとしては**GitLab**などが挙げられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/f28f4b2f-83cd-8465-88db-74e21158f2cc.png)


### GitHubを使用する利点

- ローカル(自分のパソコンにある)リポジトリを何らかの理由で**破壊**してしまった場合、<br />
	GitHub下で管理されているリモートリポジトリの内容を持ってくることで**修復することができる**
- 共同開発者と簡単にコードを共有できる
- 他の開発者にソースコードの**レビュー(精査)**をしてもらえる
- 機能追加のリクエスト(**issue**)を受けられる

無条件でこれらの**徳**を得られるので、Gitを使えてGitHubを使わない理由はないと思います。
というかプログラマ業界において、基本的に**GitHubは人権**です。

## GitHubの基本的な要素

![repo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/38a51b74-06f6-a455-27f3-a03f8bd77b85.png)
GitHubでは、Commit履歴やBranchなどの情報を視覚的に扱うことができます。
ファイル名やディレクトリ名をクリックすることでソースコードの内容を見たりできます。
Commit履歴では、`diff`(変更内容)を見やすく表示してくれたりします。

※ここの情報は**誰でも**見れるので、**くれぐれも**個人情報を載せることのないようにしてください。

## リモートリポジトリについて

リモートリポジトリとは、**GitHubなどのホスティングサービス側で管理される**リポジトリのことです。
ローカルのリポジトリをGitHubにアップロードし、それを共同開発者や協力者と共有することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/406f3f80-453e-b588-a8b0-8fd08221cedd.png)

通常、リモートリポジトリ内のファイルを**直接**書き変えたりすることはありません。
ではどうするかというと、まずローカルリポジトリの内容を変更し、変更後のファイルの状況を
リモートリポジトリに**渡してあげる必要**があります。
GitHubにリポジトリをアップロードするには「**[push](https://qiita.com/ko_5/items/c0c45c80f12e0072e51e#pushとは)**」というコマンドを使用します。

### ローカルリポジトリとの違い

ローカルリポジトリは自分しか見えませんが、リモートリポジトリは「**インターネット上にいる誰でも**」見ることができます。
つまり、パスワードやtoken(識別情報)、API Key、本名などの重要な個人情報を載せてしまうと
**悪質なハッキングに遭ってしまう危険性**があります。くれぐれも気を付けてください。
その他にも**共有したくないファイル**がある場合があります。
(例： プロジェクトで使用しているパッケージをまとめたディレクトリなど)

Gitでは、そんなファイルを`push`コマンドから**無視(`ignore`)**するように設定することができます。
　　詳細は下記(**[.gitignoreについて](https://qiita.com/ko_5/items/c0c45c80f12e0072e51e#.gitignoreとは)**)で説明しています

もしもリモートリポジトリに上げたくないファイルがある場合、`.gitignore`ファイルを記述するといいでしょう。

また、リモートリポジトリ内のファイル状態がおかしくなってしまうと共同開発者に迷惑なので取り扱いには**少し注意**が必要となってきます。

### `push`とは

`push`とは、**ローカルの変更内容をリモートリポジトリに報告**するコマンドです。
コミットなどの作業をローカルで行うだけでは、その変更内容はリモートに反映されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/e5707518-0c08-2ade-aa18-d046f59be3a8.png)
(上の丸一つ一つがコミットを表しています)
Aさんが**`push`をすることによって初めて**、Bさんは変更を取り寄せることができますし、コードレビュアーはソースコードを読むことができます。
変更を取り寄せる方法は次回で出てきます。

## リモートリポジトリ作成から`push`するまでの流れ

**事前準備**
自分のパソコンの任意の場所にリポジトリを作成しておいて、任意のファイルを追加しておいてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/f174faac-8eb7-53fc-eb78-6c9b50520738.png)
↑ *`.git`*というディレクトリは`git init`をすると**自動的に作成される**ので後から**作成する必要はありません**。
(*`.git`*は**隠しファイル**になっているので利用している環境によっては見えない場合がありますが**問題ありません**。)

ローカルリポジトリ内で`Git Bash`を起動しておいてください
(または`コマンドプロンプト`を起動しリポジトリのディレクトリまで移動しておいてください。)

※ディレクトリを移動する方法についてはこるくが**[第2回](https://qiita.com/Colk-tech/private/8d4b28b9001b862eeb99#つくってみよう)**で説明しています。

---

1. GitHubアカウントページにアクセスします
	　**https://github.com**
　ログインしてあればこのような画面が表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/7cdcf4f5-9f55-97ef-9e3f-6ae3f1f2eb56.png)

2. 左の`Repositories`から、`New`を選択します

3. 新しいリモートリポジトリの情報を入力します
	![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/6cd8e9a8-7881-2777-8665-c5c79b677463.png)
**以下はオプションです**
**・** ***`initialize this repository with a README`***
　このオプションは**`README`(説明書)**を生成するので、リモートリポジトリの中身が空ではなくなり、
　後述する`git clone`の使用を余儀なくされてしまいます。今回は最初に`git remote add URL`の方から
　紹介する予定なので**オフ**にしておいてください。
**・** ***`public` or `private`***
　GitHubには`private ripository`という機能があり、**機密性を保ちたいコード**(会社のプロジェクトや
　大会などのコード)　を書くときなどに**リポジトリをプライベートにして非公開にする**
　機能があります。今回は特に隠す理由が無いと思いますので、**オフ**にしておきましょう。

　上記以外にも***`add .gitignore`***やら***`add a license`***やらオプションがありますが、
　今回は**オフ**にしておいてください。

4. `Create repository` をクリックします

5. リモートリポジトリとローカルリポジトリを紐づけます。ここのやり方は主に二通りあります

#### 一つ目

一つ目は、あなたのパソコンに**先に**リモートリポジトリの場所を覚えさせておいて、そこに`push`できるようにする方法です。
`Git Bash`で、`git remote add origin URL`(**URLは自分のリモートリポジトリのURLに置き換えてください**)と入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/7c361b09-f6bc-b902-37eb-01b05dd12432.png)



```bash
$ git remote add origin <"リモートリポジトリのURL">
```

<br />
これで、ローカルリポジトリの`remote`という情報に**`origin`**という名前の**リモートリポジトリURL**が追加されました。(なぜ`origin`なのかは後ほど)

この方法では、**ローカルリポジトリが既に存在しており、変更を与えてしまっている場合**に役立ちます。二つ目の方法ではリモートリポジトリの内容をダウンロードしてくるためローカルのファイルを移動させて`push`しないといけないという二度手間になってしまいます。
それに対し、この方法(`git remote add origin URL`)では、ローカルに与える影響は「**リモートリポジトリURLの追加**」なので、**既にローカルにリポジトリを作ってある場合**においても実行できます。
では、コミットして、先ほど行った任意のファイル作成を記録します。



```bash:Bash
$ git add --all
$ git commit -m "<コミットメッセージ>"
```



次にその変更内容をリモートに`push`しましょう。



```bash:Bash
$ git push origin master
```



(このコマンド文の詳細については下で説明します。)

#### 二つ目

この方法では、ローカルにファイルを作る前にリモートリポジトリを作成して行うので今回のような事前準備は必要ありません。
二つ目は、先ほど作成したリモートリポジトリを`clone`してくる方法です。
知らないコマンドが出てきました。

### `clone`とは何か

**リモートリポジトリの情報、内容のコピーををあなたのパソコン上にダウンロードしてくる**コマンドです。ダウンロードしてきたリモートリポジトリの情報には**URLも含まれているので、`clone`するとその後は`push`を行うことができます**。

先ほどの`initialize this repository with a README`のオプションをオンにしていた場合や
共同開発を行うとき、最初にリポジトリを初期化した人以外などの場合はこちらの方法を使うことが多いです。


##### コマンド

リポジトリを保存したいディレクトリに移動して
`git clone URL` (ここのURLもリモートリポジトリのURLに置き換えてください。) と入力します。



```bash:Bash
$ git clone <"リモートリポジトリのURL">
```

(ここで、`warning: You appear to have cloned an empty repository`と警告が出ることがありますが、
これは「**リポジトリをクローンしてきたけどこれ空っぽだよ？間違ってたりしない？**」と心配してくれているだけなので問題ありません。)
(ちなみにここのコマンドには**`origin`という単語が含まれていません**が、その説明も後ほど行います。)
`git clone`でダウンロードしてきたリポジトリは、既にGitリポジトリとして初期化されているので**`git init`をする必要はありません**。
任意のファイルを追加して一連の流れを執り行いましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/f174faac-8eb7-53fc-eb78-6c9b50520738.png)


```bash:Bash
$ git add --all

$ git commit -m "<任意のメッセージ>"
[master (root-commit) 96f6293] <ここにコミットメッセージが表示されます>
 1 file changed, 1 insertion(+)
 create mode 100644 <追加したファイル>

$ git push origin master                                           
Username for 'https://github.com': <ユーザー名>
Password for 'https://<ユーザー名>@github.com': (パスワードを入力)← 表示はすべて「*」になってしまいますが問題ありません。
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 392 bytes | 392.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To <"リモートリポジトリのURL">
 * [new branch]      master -> master
```



上記の二種類の操作(`remote add`か`clone`)のうちどちらかを実行することで紐づけは完了です。
**ローカルリポジトリがリモートリポジトリの場所を覚えていてくれる**ので、次から簡単に`push`をすることができるようになります。

リモートリポジトリの*URL*が`origin`として登録されていることを実際に確認してみましょう。

```bash
$ git remote
origin
```


`remote`に`origin`が追加されていることがわかります
`URL`も確認することができます。


```bash
$ git remote get-url origin
https://github.com/ユーザー名/リポジトリ名
```


ちゃんと登録されていることが確認できたでしょうか。

場合によって使い分けることになるので、**両方覚えておきましょう**。

- `git remote add origin URL`で、`remote`の情報に`origin`という名前で**URLを追加**
- `git clone URL`でリモートリポジトリを**コピーしてくる**

6\. うまくいっていれば、これで先ほど作成したリモートリポジトリにローカルの内容が反映されているはずです。
　リモートリポジトリのURLにアクセスして確認してみましょう。
　`https://github.com/ユーザー名/リポジトリ名`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/c1d60a94-4628-794d-842a-f58afb1cf8ae.png)

## pushの詳細

GitHub上でリポジトリを共有するには、`Git Bash`か`コマンドプロンプト`で
***`git push リモートリポジトリ名 ブランチ名`***と入力します。

この`リモートリポジトリ名`というのは、**リモートリポジトリ作成時に入力した`Repository name`とは異なります**。
上の説明で使用されていた`origin`というのがここでのリモートリポジトリ名です。(ローカルにおける**リモートの*URL*の名前**と言った方がわかりやすいかもしれません。)
リモートリポジトリ名には自由な名前を付けることもできますが、**通常の開発目的で作成した場合**、**メインのリモートリポジトリ**には`origin`という名前を付けるのが**慣習**です。(`clone`した場合は、リポジトリをダウンロードしてきた時点で自動で`origin`が登録されています。)
次は`ブランチ名`についてです。上の説明でのブランチ名は`master`となっていましたが、これは**`push`したいブランチのブランチ名**によって変化します。
例えば`add-feature`ブランチを`push`したいとなったら、`git push origin add-feature`となります。

ということで、**`git push origin master`**というのは
**「`origin`という名前が付けられた*URL*に存在するリモートリポジトリの`master`ブランチに
　ローカルリポジトリの`master`ブランチの変更内容を`push`する。」**
とも言い換えることができます。

ちなみに**一つのローカルリポジトリ**に対して、リモートリポジトリを**複数**関連付けることは可能です。
その場合はメイン以外のリモートリポジトリの名前は`origin`とはせず、役割に対応した名前を付けることになります。`origin`というのは**あくまでもメインのリモートリポジトリのみに付ける名前**というのが慣習です。

## `.gitignore`とは
Gitリポジトリ内に`.gitignore`ファイルを作成し、その中で、**無視してほしいファイル**や**拡張子**などを
指定することで**リモートリポジトリに`push`されないように**することができます。
<br />
**では実際に`.gitignore`を活用してみましょう。**
1\. **リポジトリ直下**に`.gitignore`ファイルを作成します。<br />
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/61fe028e-5b0e-3a8f-a6ea-b47a47176520.png)

2\. では例として`personal_info.txt`ファイルを作ってみます
　**(実際には個人情報を載せないでくださいね！執筆者は責任を負いませんからね！)**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/0184ab70-579e-457b-5d5f-8ab2242e93e9.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/09e4d05e-d885-01f3-98e3-78db1f6feb2d.png)
この状態で`git status`を使用し、`personal_info.txt`と`.gitignore`**両方の追加**が変更内容として**表示される**のを確認してください。


```bash
$ git status
On branch master
Your branch is up to date with 'origin/master'.

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

nothing added to commit but untracked files present (use "git add" to track)
```


`personal_info.txt`の変更が確認されてしまっています
このまま`add --all`して`push`してしまうと、`personal_info.txt`が**インターネット上にアップロードされてしまいます**。

3\. `.gitignore`に、追跡しないでほしいファイル名`personal_info.txt`を記入しましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/374ef009-d669-e92d-80ae-8ed0ea75a216.png)
そうすると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/c94f7975-5ec3-07fe-1172-f56d66cdcc3f.png)
`personal_info.txt`の表示が暗くなっています。これで***`personal_info.txt`が`ignore`された***ことになります。
(これは***VSCode***での表示です。**お使いの環境によっては変化する**可能性があります。)
　***VSCode***については**[こちら](https://qiita.com/Colk-tech/private/e75c61146cabc887ad29#%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%AE%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E3%81%AE%E8%A8%AD%E5%AE%9A)**に説明があります。

`git status`でも確認してみましょう


```bash
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore  
                        ← さっきはあった「personal_info.txt」が消えている
nothing added to commit but untracked files present (use "git add" to track)
```


無事、**変更が追跡されていない**ことが確認できます。

4\. 練習も兼ねて`push`してみましょう


```bash
$ git add --all

$ git commit -m ".gitignoreを追加"
[master ec72b94] gitignoreを追加
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore
$ git push origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 308 bytes | 154.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/ko50/testrepo.git
   55c6bad..ec72b94  master -> master
```


5\. GitHubを確認しても**`personal_info.txt`はアップロードされていない**はずです
　これで個人情報を`push`の魔の手から守ることができます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564415/87ac1f32-7813-1a0a-6870-3c29b2b4a9fa.png)

※ちなみに、個人情報を含むファイルを**既にリモートリポジトリに`push`**してしまった場合、
　後から`.gitignore`に追記しても　**commit履歴から見れてしまう**ので、その時は`commit`自体を
　**なかったことにする**必要があります。(その場合の対処法は今回では扱いません。)

## まとめ

- **GitHubは人権**　使えないとGitを習得した**意味がほとんどない**まである
- リモートリポジトリに**個人情報は載せない**ようにする
- ローカル(自分のパソコン)にリモートリポジトリの情報を登録するには**二つの方法**がある
	- `git remote add origin URL`で、`remote`の情報に`origin`という名前で**URLを追加**
	- `git clone URL`でリモートリポジトリを**コピーしてくる**
- ローカルの変更内容は**`push`しないと**リモートリポジトリには**反映されない**  
	- `git push リモートリポジトリ名 ブランチ名`
	- メインのリモートリポジトリ名は**特別な理由が無ければ**`origin`にする
- パスワードなどは**`.gitignore`**を使用して**追跡されないようにする**
- コードを**外部に漏らしたくない**ときはリポジトリを**`private`**にして保護する

## 他パートへのリンク

#### **次回**
**[NITICNoobsによるGit/GitHub講座 第7回 ～fetch/pull～](https://qiita.com/isso0424/items/a7a0816d9a7f0caf1de6)**

**[第1回](https://qiita.com/Colk-tech/items/e75c61146cabc887ad29)** インストール編
**[第2回](https://qiita.com/Colk-tech/items/f0817df7c6fdc9a7f283)** 設定編
**[第3回](https://qiita.com/Colk-tech/items/8d4b28b9001b862eeb99)** 実際に使ってみよう-基本技能編
**[第4回](https://qiita.com/Flisan/items/e6398225905e0ed906dc)** ブランチ(平行世界)編-1
**[第5回](https://qiita.com/Flisan/items/6afd47345fdca42f1c3c)** ブランチ(平行世界)編-2
**[第6回](https://qiita.com/ko_5/items/c0c45c80f12e0072e51e)** GitHub入門編
**[第7回](https://qiita.com/isso0424/items/a7a0816d9a7f0caf1de6)** fetch/pull編
**[第8回](https://qiita.com/isso0424/items/6fc09a68bf0011dfc922)** issue/Pull Request編
## 執筆者

- [いっそう](https://twitter.com/kousou4129)
- [こ](https://twitter.com/ko_CottonLove)
- [こるく](https://twitter.com/Colk_)
- [フライさん](https://twitter.com/loxygenK)