# Git 講座 (2019/12/20)
## Gitとは
Gitは**バージョン管理システム**の一つで, ディレクトリ内のすべてのファイルの履歴をまとめて保存するためのソフトウェア
使用例は以下のサイトなどを参照
https://misw.github.io/git/index.html
## gitのinstall
まず, どこでもいいのでターミナルなどを開く
<span class="width130px">Windows</span> ➡ **wsl, git-bash, powershell** (winキーから検索)
<span class="width130px">Mac, Linux</span> ➡ **ターミナル**
そこで
```bash
git
```
と打って色々出ればGitがインストールされている. やったね!
なければ, https://git-scm.com/ ここからgitを落としてくる
* Windowsの方はこちらが参考になるかも
~~WSLを入れたりLinuxをデュアルブートすると, 後々いいことあるかもね~~
https://eng-entrance.com/git-install
* MacOSの方はこちらが参考になるかも
https://tracpath.com/bootcamp/git-install-to-mac.html#id3
* Linux(ubuntuとかの方は)
```bash
sudo apt install git
```
とかで入るはず(最初からインストールされている場合もある)
## GitHubアカウントを取得する.
ミノエル君のこちらの記事からGitHubアカウントを取得しましょう.
なお, GitとGitHubは別物です. GitHubはGitでの共同開発に必要なGitホスティングサービスの一つです.
ssh取得のところは今はしなくて大丈夫です.(今後もしなくて大丈夫です)
あとから自分のGitHubの**ユーザー名**と**パスワード**を使うので覚えておいてください.
https://misw.github.io/markdown/mis_github.html
## これだけは覚えて帰る
* GitとGitHubは違う. (GitHubはGitホスティングサービスの一つ)
* Git は **pull** して **add** して **commit** して **push**すればいい.
* 共同作業では**ブランチ**を分けて作業をして, (**プルリクエスト**を出して)**マージ**する
### Git/GitHubの雰囲気
これはMMORPG企画の早稲田祭直前のinsights/network
![](https://i.imgur.com/9ayKWQm.png)
* 図中にある各点が**コミット**と呼ばれるもの. プロジェクトを作る時はコミットを重ねていく.
昔のコミットの状態に戻れたり, コミットを打ち消したりすることができる.
* 図中の複数枝分かれしている線が**ブランチ**と呼ばれるもの. 共同編集ではブランチを切り分けて作業して, 各ブランチを合流させる(**マージする**)ことで機能追加/バグフィックスなどを行っていく.
* GitHubでは, 「こういう機能を追加したので, マージさせてもらえませんか?」という要求である**プルリクエスト**を投げて機能改善などをしていく.
## コマンドライン操作
windowsの方はWSL(Windows Subsystem for Linux)か, gitについてきた**git-bash**を使うといいです.
この講座では講師が硬派(?)な人なので, **Linuxコマンド操作**だけでGitを操作していく予定です.
**基本的なコマンドライン操作**(ls, cd, mkdir など)が分かるといいです. ディレクトリはフォルダーみたいなものです.
|コマンド|できること|
|---|---|
|**ls** (リスト)|カレントディレクトリ(現在いるフォルダ) のファイル一覧を表示する.|
|**cd** (チェンジディレクトリ)|`cd <ディレクトリ名>` で指定したディレクトリに移動する. `cd ..` とすることで, 現在いる位置から一つ上の階層のディレクトリに移動する.<br><span class="gray">例: `cd Documents`</span>|
| **mkdir** (メイクディレクトリ) | `mkdir <ディレクトリ名>` 新しいディレクトリを作成する.<br><span class="gray">例: `mkdir proj1`</span>|
|表記|意味|
|---|---|
|**.** (ドット)|カレントディレクトリを示す.|
|**\.\.**(ドット2つ)|親ディレクトリを示す.|
|**~**(チルダ)|ホームディレクトリを示す.|
## Git + GitHub図解
![](https://i.imgur.com/9ilE0yM.png)
## gitのレポジトリを作ってみよう!
まず, ユーザー名とメールアドレスを登録しましょう.
参考: https://help.github.com/ja/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address
```bash
git config --global user.name <username>
git config --global user.email <username>@users.noreply.github.com
```
まず, 適当なところ(~/workなど)にファイルを作りましょう.
```bash
mkdir ~/work # mkdir /home/ユーザー名/work の省略表記
mkdir ~/work/git-tutorial
cd ~/work/git-tutorial
```
そこで適当なファイルを作ったりしましょう.
```bash
vim main.c
```
<div class = "otaku">vimっていう素晴らしいエディタがあります! vim main.c と打って編集に入ります. から i を押して編集, ESCを押して :wq で保存できます!</div>
さて, gitレポジトリを作ってみよう
```bash
git init
```
ここで `ls -a` (~~コマンドプロンプトならば`dir`~~コマンドプロンプトは非推奨)を実行すると,
作ったmain.cファイルの他に.gitフォルダが作成されています.
ここにgitの設定や, 今までの更新が記録されています.
## 自分のファイルをコミットしてみよう
Gitにて, 自分の現在の作業状況を記録することを **コミットする**といいます.
開発する際はこまめにコミットを重ねて開発状況を記録していくことで, 途中で成果物に不具合が起きても昔の記録(コミット)に復元することなどができます(`git reset` コマンドなど)
コミットするためには**add**と**commit**の2つのコマンドを使います.
まず, **add**コマンドで変更をコミットしたいファイルをまとめておきます.
```bash
git add main.c
```
次に, **commit**コマンドでaddされた変更点をコミットとして確定します.
commitコマンドではどんな作業をしたのかを判別するために`-m`などを使って
**コミットメッセージ**をつける必要があります.
```bash
git commit -m "main.cを追加"
```
ユーザー名とメールアドレスを入れてねという由のエラーがでたら, メッセージにある2角コマンドを入れてあげましょう.
これでコミットが完了しました
### Gitレポジトリの状態を見る
**何がaddされているのか, 何がコミットされてきたのか** を確認するコマンドについて紹介します.
main.cを編集して, その変更をコミットしてみます.
```bash
# main.cを作成して編集する
vim main.c
```
ここで, gitのレポジトリの状態を見るコマンド git statusを使ってみます.
```bash
git status
```
`Untracked files: main.c` というふうに, main.cがまだaddされていないことを示すメッセージが出ます.
```bash
git add main.c
```
addしてからもう一回 git status で確認しましょう.
```bash
git status
```
すると, `Changes to be committed:` という欄に先程addしたファイルがあることがわかります.
addしたファイルをstaged file, addされたファイル郡をインデックスと呼ぶことがあります.
たまにコミットしたくないファイルがstageされている(addされている)場合があるので, その時は
```bash
git reset <ファイル名>
```
とすると, addされていない状態になります. さて, コミットしましょう
```
git commit -m "main.cを修正"
```
ここでgit logコマンドを使ってみましょう
git logコマンドは今までのコミット履歴一覧を見ることができます.
デフォルトはlessなので~~vimキーバインドが使えます! やったね~~, "q"で終了することができます
```
git log
```
昔のコミットは, git reset, git rebase, git revertなどを使って参照/操作することができます.
## GitHubを使ってみよう!
こちらも参照してください https://misw.github.io/git/index.html
複数のGitレポジトリ(git initを実行したディレクトリ)を同期させて共同作業をするには, 各ユーザーからアクセスできる場所にある**リモートレポジトリ**と呼ばれるものが必要.
リモートレポジトリに各人の更新分を付け加えていく形で共同作業をする.
ネット上にあるリモートレポジトリに対して, 自分のpcの中にあるレポジトリ(git initしたディレクトリ)を**ローカルレポジトリ**と言う.
リモートレポジトリを作成, 運用できる**Microsoft**のGitホスティングサービスである**GitHub**を使う.
Gitホスティングサービスは他にもいくつかある(Git Lab, Bitbucketなど)
### 自分のリモートレポジトリを作る.
https://github.com/Githubの自分のユーザー名 のページの**右上の+ボタン**などから`New repository`を選択しましょう. 適当なレポジトリ名をつけて, 良ければ`Create repository`を押します.
![](https://i.imgur.com/j4mLp3K.png)
下図に示された部分を押してurlをコピーします
![](https://i.imgur.com/4CXWHKL.png)
さて, いままでpc上で作業してきたローカルレポジトリにいま作成したリモートレポジトリを知らせます. 先程まで作業していたコマンドラインにて,
```bash
git remote add <リモートレポジトリにつけるお名前> <コピーしたurl>
```
と打つとローカルレポジトリが同期するリモートレポジトリを設定することができます
特別な理由がない時は慣習的にリモートレポジトリ名を**origin**とすることがおおいので今回もそうします.
以下を打ち込みましょう.
```bash
git remote add origin <コピーしたurl>
```
これで, 今までしてきたコミットをGitHub上にあるリモートレポジトリにさせることができます.
今までのコミットをリモートレポジトリに上げるためには`git push`コマンドを使用します.
```bash
git push <リモートレポジトリ名> <ブランチ名>
```
ブランチ名はその名の通り, これから説明するブランチというものの名前なのですが, Gitでレポジトリを作成した時, 最初に`master`というブランチに我々はいることになります.
ですので, masterブランチのコミット内容ををリモートレポジトリの`origin`にアップロードするので, 以下のコマンドを打てば良いです (-uは上流ブランチを設定するためのおまじない)
```bash
git push -u origin master
```
これで, リモートレポジトリにローカルレポジトリの内容をアップロードできました.
実際 https://github.com/ユーザー名/レポジトリ名 にアクセスすると, ローカルで編集してきた内容が反映されていることがわかります.
これから(個人で)開発していく時は
1. `git add <ファイル名>` `git commit -m "コミットメッセ-ジ"`でコミットを重ねていって
2. リモートの内容を`git push origin master`で更新していけば良いです
## ここまでのまとめ
* **ローカル/リモートレポジトリ**を作る
* `git init` でローカルレポジトリを作成
* GitHubからリモートレポジトリを作成
* `git remote add origin <url>` でローカルレポジトリにリモートレポジトリの場所を設定
* **add して commit して push**
* `git add <ファイル名>`で変更点をgitに教えていく
* `git commit -m "コミットメッセージ"` で変更を確定
* `git push origin(リモートレポジトリ名) master(ブランチ名)` でローカルでの変更内容をアップロード
## 共同開発をしよう <ブランチ, プルリクエスト, マージなど>
ここでビラキが今回のために作った適当なリモートレポジトリを公開します. それをみんなで編集しようという魂胆です.
ここでは,
* `git clone`
* ブランチ作成, ブランチ移動 `git branch, git checkout`
* プルリクエスト, merge
* `git pull origin master` などで他の人の変更を取り入れる
ということをします.
### git clone
ローカルに, 先程作ったレポジトリと別のレポジトリを作成します.
まず, 別に公開されるURLのページに移動して, gitのリモートレポジトリへのurl(~.gitで終わるurlを取得します)
以下のような手順を踏んでリモートにあるレポジトリをクローンしてきます.
先程の`git remote add origin <url>`はもともとあったローカルレポジトリにリモートレポジトリを紐付けするコマンドでしたが, `git clone <url>`はもともと存在していたリモートレポジトリをローカルに持ってくるためのコマンドです.
```bash
# いままで作業していたレポジトリは使わないので, 親ディレクトリに移動します.
~/work/git-tutorial$ cd ..
# git clone コマンドでリモートにあるレポジトリを落としてきます.
~/work$ git clone <url>
# 新しくクローンしてきてできたレポジトリに移動します
~/work$ cd mis-git-tutorial
# ls -a をするとリモートにあるレポジトリを落としてこれたことがわかります.
~/work/mis-git-tutorial$ ls -a # windowsのコマンドプロンプトは dir
. .. .git index.html README.md
```
### ブランチについて
さて, 練習用のレポジトリにコミットしてみましょう.
共同開発では開発をする時は
1. ブランチ(枝)を切って作業する
2. プルリクエスト(製品ブランチなどに合流(マージ)させていいですか??というリクエスト)を送る.
3. マージされる.
という流れを踏みます.
![](https://i.imgur.com/9ayKWQm.png)
コミットが衝突しないようにするために, 作業ごとに**ブランチを切る**ということをします.
#### ブランチの役割
例えば...
* 機能の実装状況が中途半端なものを本番環境(masterなど)に置かないようにするため
* AさんとBさんが同じファイルの同じ機能を編集した. 同じファイルの近い場所を複数人が編集すると, どちらを採用すればいいかgitはわからないため, 機械的に合体(マージ)させることができない (**コンフリクト**) !
#### git branch
いまいるブランチから新しいブランチを切る時は`git branch`コマンドを使います.
例えば自分のハンドルネームのブランチを作ってみましょう. (実際は, ブランチ名はどんなことをするか(機能追加, バグフィックスなど), issuesの何番に対応するかなどの情報を含めたブランチ名にします.)
```bash
git branch 新たに作るブランチ名
```
<div class="otaku">git checkout -b ブランチ名 とすればブランチを切ると同時にそのブランチに移動します</div>
#### git checkout
また, ブランチ間を移動する時は`git checkout `コマンドを使います.
```bash
git checkout <ブランチ名>
```
masterブランチに再び戻りたい時は`git checkout master`と打てば戻れます.
<div class = "otaku">
*ブランチを移動する時に, コミットしてない変更などがあると, エラーが起きることがあります. その時は `git stash` コマンドで変更を一時的に退避させたりしましょう. `git stash pop` コマンドで退避させていた変更を取り出せます.*</div>
#### 作ったブランチでコミット+push
現在いるブランチは `git branch` とただ打てばわかります.
新しく作った自分のブランチで, 例えば 自分のハンドルネーム.htmlのようなファイルを作って, そこに自分の自己紹介を書いてみたりしましょう.
作ったファイルを今までどおり `git add `, `git commit -m "コミットメッセージ"`としてコミットしましょう. ファイルについてきたhtmlにcssアニメーションとかをつけたりとかしても大丈夫です.
pushする際は
```
git push origin <作ったブランチ名>
```
とします.
個人開発ではいいのですが, **git push -f origin master**などとmasterにしかもフォースプッシュするとプロジェクトを破壊する可能性があります. やむおえず使う時はプロジェクトの管理者とよく話し合ってください. 基本的にはブランチを分けて, プルリクエストを投げましょう.
### GitHubのPull request機能を使う
さて, いよいよ終盤です.
いまローカルでした変更をリモートレポジトリに適用させましょう.
共同開発では, 「このブランチでした変更を合流(マージ)させていいですか?」という要求であるところの**Pull Request**をそのレポジトリのメインの開発者(今回の場合は僕とか)に送ります.
GitHubのレポジトリの**Code**から, `Branch:ボタン`から自分のブランチを選択. そして`New pull request`を押します.
![](https://i.imgur.com/xcsGpim.png)
次の画面で, Pull requestのタイトルと何を変更したかなどの概要を書いて`Create new pull request`とすれば完了です~!!
**お疲れ様でした!!!!!!**
あとは僕とかが適当にマージしたりします.
### 他の人がした変更を git pullして取り入れる.
最初にリモートレポジトリごとPCに落としてくるコマンドは`git clone`コマンドでしたが, すでにPCにレポジトリが存在していて, 他の人がした変更を持ってくる時は, `git pull`コマンドを使います.
```
git pull origin <ブランチ名>
```
とすることでリモートレポジトリ中の指定したブランチの変更を持ってくることができます.
<div class="otaku">実は持ってくるだけではなく, マージもしています. git fetch + git merge コマンドを略したものです. また, 最初の方で git push -u origin master などとしている場合, 上流ブランチが設定されているため, git pull (引数なし)とするだけで変更を取ってくることができます.</div>
## まとめ
### つまり
1. **ローカルレポジトリ**/**リモートレポジトリ**を作成する
* init & git remote add
* Gitホスティングサービスでリモートレポジトリを作成
* clone
2. **add** して **commit** して **push**すればいい.
* add ... 変更点をgitの管理下に追加
* commit ... 変更を確定
* push ... リモートに変更をアップロード
3. こまったら
* エラーメッセージをググる
* git status
* git logでコミット番号を参照して, git resetやrevertなどをする
4. 共同開発では
* **pull**で他人の変更点を持ってくる
* **ブランチ**を切る
* **プルリク**を出す
* **masterに直接pushはよくない**.(よくない)
### 共同開発のフローまとめ(びらき視点)
1. レポジトリがなければ, `git clone <GitHubのURL>`でリモートレポジトリをローカルに落としてくる.
2. 最新の状況を `git pull origin <ブランチ名>`などで持ってくる.
2. `git branch <ブランチ名>`, `git checkout -b <ブランチ名>`で, 自分が作業するブランチを切る.
3. そのブランチでコミットを重ねて, 適宜pushする.
5. 作業が終わればGitHubを通してPull requestを送信する. → マージされる
### GitHubを使うプロジェクトでのGitの使い方まとめ
ネット上に他のユーザーが作ったレポジトリが存在し,まだそれをダウンロードしたことがないのであれば,以下のコマンドでレポジトリ全体をダウンロードする。
```bash
git clone <GitHubのレポジトリのURL>
```
他の人が更新したものを持ってくる
```bash
git pull origin ブランチ名
```
自分のブランチを作ってそこに移動する
```bash
git checkout -b 作るブランチ名
```
ブランチを移動する
```bash
git checkout ブランチ名
```
ファイルを変更したら変更したファイルをステージングする
```bash
git add 変更したファイル名かディレクトリ名
```
ファイルの更新を確定する
```bash
git commit -m "ここにコミットメッセージを書く(~~を修正, 追加とか)"
# コミットメッセージを丁寧に書く場合はこうする。
git commit -m "タイトル(70文字程度)
変更点の要約(数百字程度)"
```
ファイルをリモート(github.com)に上げる
ブランチ名はリモートに上げるブランチ(masterブランチに直接pushは良くない)
```bash
git push origin ブランチ名
```
このあとプルリクエストを送ってマージしたりする.
# 参考資料
* oguniくんが書いてくれた講座資料
https://misw.github.io/git/index.html
<style>
.gray {
color: gray;
font-size: 0.8em;
}
.width130px {
display: inline-block;
width: 130px;
}
.otaku {
color: gray;
font-size: 0.6em;
}
</style>