Gitを用いて、ファイルをaddしてcommitしてGitHubにPushしてPullするやり方

##GitHubってどこが便利なんだよ？
と思っていました。現場での開発経験がないと、Gitという仕組みは難しいだけに感じますが
使ってみたらとても便利でした。
GitHubを使えるとポートフォリオにもなりますし、いいことづくめではないでしょうか。
今回は、Gitbash(CUI)を用いた方法とVisual Studio Code(GUI)を用いた方法の2種類のやり方でやってみたGitの使い方をまとめたいと思います。

##Gitの仕組み(超ざっくりと)
.gitディレクトリ(隠しフォルダ)をしのばせることで親ディレクトリを管理可能。
.gitが特殊な構造を持ち、二層の構造になっている。そのうちの一つがstage,もう一つがrepository(厳密には少し違う気がしますが…)。

ファイルをcommitしたときにそのファイルの情報をrepositoryに格納するのですが、このときにハッシュ値を一緒に持ちます。
このハッシュ値があることで、commitされたファイルが一意に特定できます。
つまり、commitがチェックポイントとなってcommitされるたびにその時点でのファイルの情報を複製します。
これによって、昔よりも開発の手戻りなどが行いやすくなったそうです。~~(昔を知らないので何とも言えませんが…)~~

さらに、この仕組みによって、branchというものを作成することでそれぞれ別なファイルとして格納できるため、それぞれが｢試しにこういうのを試してみよう｣といったことが気軽にできます。
詳しく知りたい方はコチラの記事が結構参考になりました。
[参考サイト](https://yakst.com/ja/posts/3811)
##init
```git init```

このコマンドを入力したファイルの中に.gitが作成されます。(CUIのみ)

##configでユーザー名とメールアドレスを設定(初回のみ)
```git config --local(--global) user.name ユーザー名```
```git config --local(--global) user.email メールアドレス```

これは文字通りです。
addまではできた気がしますが、commitなどの手続きはuser.nameおよびuser.emailがないと行えませんので追加します。
ちなみに、--localは現在のディレクトリ専用の設定で、--globalはその端末の設定です。
--globalで名前を追加すると、その端末でコミットしたものはすべてその名前の人がコミットしたことになります。

##add
```git add ファイル名 ```

編集したファイルをステージに上げます(ステージング)。
先ほどcommitの話がありましたが、その時に｢ファイルの情報を｣と書いたのは、このステージングという手続きがあるからです。
というのも、おそらくファイルそのものが格納され、スナップショットファイルを作りだしているのは、このaddによって移動したステージング領域と呼ばれるところだと思われます。

commitはこのファイルを圧縮して、圧縮データをステージング領域の奥にある領域に格納しています。実際、一緒に作られるハッシュ値はobjectsと呼ばれる場所に入っていました。

こうすることで何度も編集してデータ量がものすごいことになるのをある程度防いでいます。

##commit
```git commit -m "メッセージ" ```

表現が正しいかはさておき、commitコマンドを叩くことでチェックポイントを確定させます。
-m でコミット時のメッセージを書いておくことで、後々戻りたいときにわかりやすくなるため
-mを付けてメッセージを書いておきます。(そもそも、アプリケーションとかでコミットするときはメッセージ必須のはず。)

##GitHub側の準備
GitHubにログインして、リポジトリを追加します。
(手順)
ログイン→repositoryの登録→publicかprivateかの選択→READMEを作るかの設定
完了後、URLが発行されます。

##push
```git push URL(さっきのURL) ```

pushというものを行うことで、自分のサーバがなくてもサーバ上でコードを管理できます。
そのためのアプリケーションに、githubとgitlabというものが代表としてあるらしいのですが、今回はより知名度が高いと思われるGitHubを使います。
privateに設定した場合はこの後IDおよびパスワードを入力します。
branchには頭(HEAD)とよばれるポイントがあって、これは最後にcommitした地点です。
逆にとらえるならば、commitが行われると、HEADが一つ進みます。(これは先述したcommitされたときにスナップショットを作成されるという仕様によるもの)
master(ローカル側)⇔origin(GitHub側)

##pull(clone) 
```git pull URL(さっきのURL)```

privateに設定した場合はこの後IDおよびパスワードを入力します。

##merge
```git merge branch名(取り込みたいbranch)```

複数人で開発する場合に起こる矛盾などを回避するための策です。
mergeという単語をネットで調べても｢マージする｣と出てきます。ふざけるでない。俺は日本語訳が知りたいんや。→ 一応｢併合する｣と訳するみたいです。

それはさておき、margeというのは、AとBを統合することと認識しておいていいでしょう。
ファイルをcommit地点からスタートさせ、branchを分けて開発を進めた場合、その情報をmaster(元のbranch)に適用させることが基本的なマージの意味です。
これには注意点がいくつかあります。

###※conflict(ケンカ)した場合
どちらを勝たせるか選びます。ただし、サーバ側でpushやpullをしたときにコンフリクトを起こした場合、CUIなので選ぶ ということができません。
この場合は、ケンカしたファイルを直接編集しに行きます。

```sudo vi ファイル名(あるいはファイルパス)```

コンフリクトしたファイルは変な記述が追加されています。
\>>>>>>>>HEAD
みたいなやつ。
これを取り除くと一応コンフリクトしなくなります。
(本来は開発中の矛盾をなくすためにいったんコードをもとに戻す方がいいと思います。)

###pullしたときのmarge先はpullしたブランチ。
コンフリクトというのは同じファイルが異なる編集をされていたときに起こるもの。
それとは別に、例えば別のPCでファイルを編集してGitHubにPushして
元のPCでPullせずに別の編集をしてPushしようとすると、できません。
これを解決するためには先にpullすればいいのですが、このときにもmergeが行われます。

このときmergeで取り込むのはpullした方のbranch、取り込まれるのはpullされた方のbranchです。つまり、ほかの人の編集が自分にも反映されてしまうことになるので注意してください。


##その他
公開範囲がpublicの場合、DBのアクセス情報などをPushしてしまうとえらいことになっちゃう…
そこで! .gitignoreというファイルを用意することで公開したくない情報だけ公開しないように設定できます。
しかも簡単。ファイルの中にGitに上げたくないファイル名を書いておくだけ。ファイル数が多い場合は正規表現も使えるようです。
[.gitignoreの書き方(引用)](https://qiita.com/inabe49/items/16ee3d9d1ce68daa9fff)
それ以外にもやりようはあるらしいですが、それはおいおい調べていきたいと思います。

GUIの方は改めて書きます。