プログラマー1年目の自分が辿り着いたGitまとめ その2

##概要
[プログラマー1年目の自分が辿り着いたGitまとめ その1](https://qiita.com/milkynapoly/items/e085d9e8b439f2539030)
の続きです。

前回はコードの変更を記録していく、というバージョン管理の基本動作について触れたので、今回は少し発展的な動作と、リモートリポジトリの活用という段階に進んでいきたいと思います。
##revertとreset
RPGで何のためにセーブするかといえば、『セーブした場所からやり直す』ためである(一概に言えないけど)。

なのでGitにも当然、"巻き戻し"に相当する操作があります。

####reset - 指定したコミットを打ち消す
`git reset コミット番号`
と指定することで、そのコミットで変更した内容を打ち消すことが出来る。

ここで登場するコミット番号とは、コミットに割り振られている識別子のようなもの。
`git log`やGitHubの履歴で確認出来る「727cd618f38hd8hd38bae476...」みたいな英数字の羅列。
因みに全部書く必要は無く、最初の4文字(上記の例でいえば727c)でコミットを認識してくれます。

resetコマンドには2つの主なオプションが存在し
`git reset --soft 727c`
とすると、巻き戻された変更が"ステージング前"の変更として残ります(なのでadd - commitすれば復活する)。
`git reset --hard 727c`
とすると、変更は何も残らず完全にコミットが削除されます。
何かしらの検証のために行った変更などをまとめて巻き戻す時に使うと便利です。
####revert - 指定したコミットを打ち消すコミットを作成する
resetとの違いは、あくまでも**巻き戻し用の新たなコミットを作成している**部分。
`git log`でコミットグラフを確認すると分かるが、resetと違って打ち消したコミットは残っている。
なのでresetを2連続で行うと、コードの状態としては元に戻るけどコミットは純粋に2つ増えている……みたいなことが起きる。

巻き戻したいけれど、記録としては残しておきたい時に使う(不具合が出ている状態のコードの保存など)。
resetより若干気楽だけども、上述の通りコミットグラフに巻き戻しコミットが追加されるので濫用は避けるべき。

わかりやすく変更を巻き戻してくれるreset/revertだが、指定したコミットの内容全てを巻き戻すので沢山の変更をまとめてコミットしてしまっている場合などは注意(巻き戻すことも考慮して、前回書いたようにコミットはこまめに行うべき)

add-commitのサイクルとreset/revertを使うことで、変更の記録及び巻き戻しというバージョン管理っぽいことが出来るようになります。
因みにcheckoutコマンドで擬似的に巻き戻しを行うことが可能ですが、これは次回以降の記事で紹介する予定です。
##リモートリポジトリ(GitHub)
いよいよここで環境を遷移し、ローカルだけでなくリモートにコードを公開しながら作業を進める、ということを考えていきます。

ここで意識するのはGitの大きな特徴、『分散型』のバージョン管理という点です。
分散型とは文字通り**複数の場所でソースコードを管理する**ということなので、手元のPC内のリポジトリ(ローカルリポジトリ)とは別の、**遠隔リポジトリ(リモートリポジトリ)**が必要になってくる。
このリモートリポジトリを介して複数の開発者が、それぞれのローカルリポジトリで行った内容を共有するという訳である。

Gitのリモートリポジトリを作成できるサービスとして最も有名なのが上にも少し登場したGitHub。
有名なライブラリとか、いわゆるオープンソースのソフトウェアとかはここでソースコードが管理及び公開されている事が多く、今は無料でプライベートリポジトリも作成できるので、業務で使う機会も多いはず。

個人開発や自己学習を行っている方は、ポートフォリオを作成するような気持ちでGitHubにコードを公開していくのがオススメです(周知の事実かもしれませんが)。
##remoteとpush
という訳で、ローカルの変更をGitHubのリモートリポジトリに共有するという作業を考えていきます(GitHubでリポジトリを作成する方法などについては割愛)。
####remote - 現在のローカルリポジトリにリモートリポジトリを関連付ける
まずはGitHubで作成したリモートリポジトリを、現在のローカルリポジトリの共有先として登録します。
`git remote -v`
とすると登録しているリモートリポジトリの一覧が確認できるので、最初はまず何も登録されていないことを確認しましょう。

その後、
`git remote add [URL]`
の形で登録。再び上記のコマンドを叩くことで登録されたことが分かるはずです。

#####注: プライベートリポジトリを登録する場合
GitHubにプライベートリポジトリとして作成していた場合は、URLにユーザ名を含める必要があります。そうすると`git remote add`実行後にパスワードの入力を求められ、登録が完了します。
URLをそのまま貼って実行すると、特に何の注釈もなく「そのリポジトリは存在しません」的なエラーが出てくるので注意が必要です……
####push - コミットをリモートリポジトリに共有する
前回基本サイクルの一部として紹介したpush。
このコマンドを実行することで、現在のローカルリポジトリのコミットをリモートリポジトリに共有することが出来る。

今はmasterブランチのみで作業している前提なので、前述のremoteコマンドによるリポジトリ登録及び変更のコミットが完了したら、
`git push origin master`
と実行。これにより、GitHubのリモートリポジトリに変更が共有されていることが確認出来るはずです。
#####originについて
originはリモートリポジトリにデフォルトで適用されるリポジトリ名。
pushコマンドは本来
`git push [リモート名] [ブランチ名]`
という指定を行うので、上述のようなコマンドになっている訳です。
なのでリモートリポジトリを複数登録するというようなことが無い限りは、originという名前についてそこまで意識する必要はありません。

一度pushを行うと、origin masterが『デフォルトのpush先』のように認識されるため
`git push`
だけで十分になります。
→ 因みにこれが上手くいかない方は同じく`git push origin master`とするか、`git fetch`で追跡ブランチを設定して下さい(追跡ブランチについては次回以降の記事で説明できればと思います)。
#####注: 別ブランチにおけるpush
まだブランチについては説明していないのですが、pushコマンドの危険な勘違いについて先に注釈しておきます。
初学者の方だと結構`git push origin master`を定型文みたいなものだと思って使ってしまうことが多いのですが、あくまでもこのコマンドは『リモートリポジトリoriginのmasterブランチに』現在の内容をpushするという操作です。

なので別のブランチ(例:develop)に居る時に`git push origin master`とかやってしまうと、**developでの変更内容がmasterにダイレクトに適用される**という酷い事故が起きるので、それだけは絶対にやってしまわないように、
`git push [リモート名] [ブランチ名]`
という構造を正しく理解しましょう。

因みに上記のケースでは`git push origin develop`とするのが正しいです。
基本的にリモートに初めてpushするブランチの場合は具体的に名前を指定し、それ以降は`git push`とすれば大丈夫です。
#####補足 - configについて
Gitにはコミットを作成したりpushしたりする際に使用されるユーザー情報を登録することが出来ます。
`git config --global user.name [ユーザー名]`
`git config --global user.email [メールアドレス]`
という感じです。確認する場合は`git config --global user.name`のように手前で止めればOK。--globalオプションはどのローカルリポジトリでも適用されるようにする為の設定です。

この設定でメールアドレスをGitHubに設定したものと同じものにしておかないと、ローカルからのpushがリポジトリを管理している自分とは別の人によるものだと認識されてしまい、GitHubのコントリビューション(所謂芝というやつです)が更新されないので、GitHubを使う場合は必ず設定を確認しておきましょう。
##まとめ
add-commitのサイクルに加え、reset/revertを使うことでコミットの追加、削除というバージョン管理の基本的な動作が行えるようになります。
ここにpushコマンドが加わることでGitHubのようなリモートリポジトリを介して自身のコードを公開するということが可能になりました。

最初はGitHubに自分の履歴がちゃんと共有されていることや、ログ及び差分が確認できるGitHubの便利な機能について触れ、慣れてみて欲しいと思います。

次回からは自分一人ではなく、複数人で一つのコードを編集する、という環境に遷移します！

前: [プログラマー1年目の自分が辿り着いたGitまとめ その1](https://qiita.com/milkynapoly/items/e085d9e8b439f2539030)
次: [プログラマー1年目の自分が辿り着いたGitまとめ その3](https://qiita.com/milkynapoly/items/d3761943c809a53f2865)