どぼじょのIT学習ブログ

高専卒土木女子がIT業界を目指してお勉強。

Rubyでlsコマンド作成

久しぶりの投稿ですが、勉強してなかったわけではありません!!笑
Rubyでlsコマンドを作っていました。
ようやくできたので、学んだことなど記録します〜😊

目次

1.経緯

フィヨルドブートキャンプの課題で、 ls コマンドを作ることになりました。
ls コマンドは、ターミナルで使えるLinuxのコマンドのひとつで、今いるディレクトリに入っているファイルを一覧で表示するコマンドです💡
ちなみに他の方も課題で作るため、作成したコードは公開できません💦

2.成果

オプションなしのlsに加え、-a-r-lオプションに対応しました💡
macのlsコマンドと比較して、以下のとおり同じ出力になりました🎉🎉

ls (オプションなし)

f:id:mistyrinth:20190222183846p:plain

ls -a

f:id:mistyrinth:20190222183902p:plain

ls -r

f:id:mistyrinth:20190222183916p:plain

ls -l

f:id:mistyrinth:20190222183933p:plain

ls -arl (オプション同時実行)

f:id:mistyrinth:20190222183950p:plain

3.新しく学んだこと

これを作るのに学んだことは沢山ありますが、主なものを紹介します!

3-1. オプションのつけかた

optparseというものを使いました。
参考サイト多すぎて紹介しきれないのですが、正直言って未経験者にとって本気で参考になったサイトってひとつも無かったような…😭
いろんなサイトの情報をかいつまんで自分なりに解釈して、どのサイトにも見かけなかった方法で作ってしまいました。使い方が合ってるのかわかりませんが、実行できたのでとりあえず結果オーライです💪笑

3-2. クラス定義、メソッド定義

今まではクラス定義やメソッド定義は概念として「こういうのがあるのかー」程度に知っていたのですが、実際にどういった場面で使うのか全然分かりませんでした!
最初はクラスもメソッドも定義せずにベタ打ちで書き始めて、複雑になってきた頃にようやくメソッドを定義しました。
実際のところ、クラスを定義する過程って「こういうオブジェクトを作りたい」→「クラス定義する(クラスメソッドも定義する)」→「クラスからオブジェクトを作る」という感じでした。分かりづらい…??🤨
クラスを定義しないとmainクラスのオブジェクトになってしまうので、不都合が出てきてしまいます。
このあたりもうちょっと学習してちゃんと説明できるようになりたいです!!

3-3. リファレンスマニュアル

gem を使っていないので、配列を作ったりファイルの情報を取得したりという細かいことは、ほとんどリファレンスマニュアルを見ながらできました🎉

3-4. その他

わからないところを時間掛けて調べて試して、95%くらい自力で考えて作ってみたので、だいぶ進歩したな!と感じています✨
他の方にいただいたアドバイスは「クラスを作って最後にオブジェクトを呼び出せばいける」ということと「mapメソッドが便利」ということだけでしたが、これが無ければかなり厳しかったですー!
アドバイスありがとうございました!
いきなり完成形を目指すのは難しいので、まず手始めに簡単なところから作っていったり、部分的に別ファイルに作って動作検証したりしたのが良かったです。
構造がイメージできればそんな手間かける必要ないのですが…😖

次はwcコマンドの作成にかかります!🙌

Git-it

今回はGithubのお勉強ということで、Git-itをやってみます!

目次

1.Git-itインストール

Git-itのアプリは以下のページからダウンロードできます。Macの方はGit-it-darwin-x64です😊

github.com

インストールしたアプリを開くと、スタート画面が出てきます。
11ステップに分けて学べるみたいですね👀 言語は日本語に設定できます✨
f:id:mistyrinth:20190116160103p:plain

2.Git-it開始

GET STARTED!から開始します。
ちなみに私は既にGitのインストールとGithubのアカウント作成は済んでいるので、終わっているところは飛ばしながらやっていきます。

2-1. Gitをインストールして設定をする

既に終わっているので飛ばします〜!
参考記事:Git入門 part1 / Gitの基本

2-2. ローカルのrepositoryを作成

ローカルリポジトリを作成します。
hello-worldという名前のディレクトリを作成し、プロジェクトを初期化して新しいGitインスタンスを作成します。
このあたりも既に学習済みなのでさくさく進めていきます💪
f:id:mistyrinth:20190116161507p:plain

2-3. ステータスを確認して、コンテンツを追加してcommitをする

作成したリポジトリの中にテキストファイルを作成します。
readme.txtというファイルを作成し、Helloとだけ書きます✋

f:id:mistyrinth:20190116162624p:plain

statusコマンドでファイルに変更が加わっていることを確認したら、addコマンドでコミットをライブラリに追加し、commitコマンドでコミットします💡
f:id:mistyrinth:20190116163201p:plain

更に、readme.txtに2行目(World!)を追加します。
diffコマンドで最後にコミットした内容と現在の内容を照らし合わせ、差分を確認できます👀
差分を確認したら、先程と同様にコミットします✨
f:id:mistyrinth:20190116164825p:plain

2-4. GitHubのアカウントを作成

Githubのアカウントは持っているのですが、以下のコマンドでGitにGithubのユーザー名を登録できるようなので、やってみます!

$ git config --global user.username ユーザー名

f:id:mistyrinth:20190116165516p:plain

登録できました!

2-5. ローカルのrepositoryをGitHub.comのrepositoryに接続

Githubにログインして、新規リポジトリを作成します。
このとき、ローカルリポジトリhello-worldと同じ名前を指定します💪💪
f:id:mistyrinth:20190116165858p:plain

ローカルリポジトリ側の操作で、リモートリポジトリ(Github)に Push します。
リモートリポジトリにoriginという名前をつけ、masterブランチに Push です😇
f:id:mistyrinth:20190116172258p:plain
参考記事:Git入門 part2 / リポジトリの共有, 変更履歴の統合

2-6. オープンソースのrepositoryをforkしてcloneする

今度はリポジトリのフォーク(fork)をやってみます!
フォークとは、対象のリポジトリのコピーをリモートリポジトリ(Github)のひとつとして使うようにすることです。
この時点ではGithub上でリポジトリの複製をしているだけで、ローカルリポジトリには対象のリポジトリはありません🙁

ここでは、以下のリポジトリをフォークします!

github.com

f:id:mistyrinth:20190116215549p:plain

右上のForkボタンを押します👆
読み込みのアニメーションが現れたあと、フォーク完了です🎉
f:id:mistyrinth:20190116215722p:plain

次に、フォークしたリポジトリをローカルリポジトリにクローンします。
このとき、ローカルリポジトリhello-worldディレクトリ)にいる場合は外に出ます👣
以下のコマンドでリポジトリをクローンすることができます。

$ git clone GithubのURL

また、元々のリポジトリ(フォーク元)に変更が加わった場合に簡単に Pull できるように、元々のリポジトリに名前をつけておきます。
名前はなんでも良いのですが、upstreamという名前をつけることが多いみたいです🙂
f:id:mistyrinth:20190116221146p:plain

2-7. 新機能・修正のためにbranchを作成

ブランチについては学習済みのため、割愛します〜!
参考記事:Git入門 part3 / ブランチ

GitHubの機能として、gh-pagesという名前のブランチにあるファイルを、自動的に静的なWebサイトとしてホストしてくれるそうです。
今回フォークしたプロジェクトはWebサイトを作るためのものなので、メインブランチの名前はmasterではなくgh-pagesです😶
また、このようなサイトのURLは以下のようになっています。

http://githubusername.github.io/repositoryname

早速ブランチを作成しますが、その前に今どこのブランチにいるのかをstatusコマンドで確認しておきます。
f:id:mistyrinth:20190116222621p:plain
gh-pagesという名前のブランチにいることが分かりましたね!!Webサイトを作るためのメインブランチです。

新しくadd-mistyrinthという名前のブランチを作成し、チェックアウトします。
f:id:mistyrinth:20190116223022p:plain

クローンしたpatchwork内にある既存のcontributorsという名前のディレクトリ内に、新しくadd-mistyrinth.txtというファイルを作成します。
中身はmistyrinthというユーザー名のみ記入しました🙃
このテキストファイルをaddcommitコマンドによりコミットします。
最後にこの変更をGitHub上の自分のリポジトリにPushします!
一連の流れは以下のとおりです☀️
f:id:mistyrinth:20190116224509p:plain

2-8. Collaboratorを追加して作業を同期する

GitHub上で、他の人のリポジトリにアクセスして編集する権限を持つ人をコラボレーター(Collaborators)と言います。
コラボレーターはSettingタブから簡単に追加できます😊
追加したら相手に通知がいき、承認されればコラボレーターになっていただけます!
f:id:mistyrinth:20190117142906p:plain

2-9. 修正をGitHub.comと同期するためにpushとpullを行う

同じプロジェクトで他の人もファイルに修正を加えている場合などに、ファイルを pull することで、最新の状態を取り込むことができます⛱

参考記事:Git入門 part2 / リポジトリの共有, 変更履歴の統合

f:id:mistyrinth:20190117152904p:plain
何も変更がされていなければ、Already up to date.と表示されます✨

2-10. Pull requestを作成

フォークしたリポジトリに変更や修正を加えたら、変更元のリポジトリの所有者に対して、自分が行った変更や修正を元のリポジトリにも反映してもらえるよう、プルリクエストを送ることができます。
参考記事:Git入門 part5 / Pull Request

元のリポジトリにプルリクエストを送ります!
f:id:mistyrinth:20190117155539p:plain

変更箇所は以下のとおりでしたね〜🙃
f:id:mistyrinth:20190117155601p:plain

相手がチェックして問題が無ければプルリクエストがマージされます💡
f:id:mistyrinth:20190117160050p:plain

2-11. Branchをmergeしてdelete(削除)する

プルリクエストがマージされたら、作業用のブランチは不要になりますね。
整理のため、変更を自分のフォークバージョンにもアップデートします。
まず、自分のローカルリポジトリのメインブランチgh-pagesにマージします🙌
その後不要になったブランチadd-mistyrinthは削除し、リモートリポジトリに push します😊
f:id:mistyrinth:20190117161130p:plain

これにより、Github上のadd-mistyrinthブランチも削除され、ブランチはメインブランチの1本だけになります🎉

また、フォーク元のリポジトリupstream)の変更を Pull すると、最新にアップデートされてます。

f:id:mistyrinth:20190117161834p:plain
他のユーザーさんたちもGit-itやってますね笑

Git-itは以上です〜!🧚‍♀️

Git入門 part5 / Pull Request

本日はサルでもわかるGit入門 プルリクエスト編です!

目次

1.プルリクエス

本日学習するプルリクエスとは、Githubなどで利用できる機能で、ローカルリポジトリでの変更を他の開発者に通知する機能です💡
チームで開発をする時に、作業内容をレビュー担当者・マージ担当者などの関係者に通知し、確認してもらうといった使い方ができます😊
自分で作った成果品を、客先に納品する前に上司に確認してもらうようなイメージですね。
プルリクエストの利用により、最終的にマージされるソースコードの品質を高くすることができます。

プルリクエストは一覧で表示され、未完了のプルリクエストを漏れなく確認できます。
プルリクエスト上では、担当者同士でコメントのやりとりをして議論できます。更に、対象のブランチにプッシュされたコミットは、自動的にプルリクエスト上に反映されます。

プルリクエストを利用した開発プロセスは、以下のとおりです。

プロセス 開発者 レビュー・マージ担当者
1 作業対象のソースを clone または pull
2 作業用ブランチを作成
3 開発作業(機能追加や改修)
4 push
5 プルリクエストを作成
6 プルリクエストから変更を確認しレビュー
7-1 修正が必要なら開発者にフィードバック
(プロセス3へ戻る)
7-2 修正が不要ならマージ
7-3 プルリクエスト自体が不要ならクローズ

2.チュートリアル

早速チュートリアルに入ります🙂
JavaScriptで配列だけが準備されている状態のソースコードに、リストの内容をソートする処理を追加するという内容です。
BacklogとGitHubが選択できるので、Githubでやってみます!

2-1. サンプルリポジトリの準備

まずはGithubにログインし、新規リポジトリを作成します。

f:id:mistyrinth:20190116105712p:plain

作成したリポジトリの中に、以下のようなjsファイルを作成します。

f:id:mistyrinth:20190116134915p:plain

2-2. 開発ブランチでの修正

次に、作業するためのブランチを作成します💪
add-sort-funcというブランチを作成し、切り替えます。
f:id:mistyrinth:20190116140039p:plain

ブランチを切り替えたら、先程作成したjsファイルを修正します🖋
f:id:mistyrinth:20190116140230p:plain

コメントを追加してコミットします。
f:id:mistyrinth:20190116140351p:plain

2-3. プルリクエストの作成

リポジトリのトップに戻ると、直近 Push されたブランチが表示されるので、Compare & pull requestを実行します💡
f:id:mistyrinth:20190116140657p:plain

実行すると、次のような画面が表示されます。スクロールして画像2枚に分かれています🙂
f:id:mistyrinth:20190116140922p:plain
f:id:mistyrinth:20190116140932p:plain

上のほうにbase: mastercompare: add-sort-funcと書かれていますね😶
これは、baseがプルリクエストをマージする対象のブランチ、compareがプルリクエストをマージしてもらうブランチを指しています。
更に2枚目のキャプチャは、baseに対してcompareを比較し、10行追加されていることが分かりますね✨
次はCreate pull requestボタンを押します。
f:id:mistyrinth:20190116141620p:plain

これで他の担当者にレビューしてもらうことができるようになりました!🎉

2-4. レビューとマージ

プルリクエストが作成されたら、今度はレビュー担当者がFiles changedタブから変更内容を確認します。
f:id:mistyrinth:20190116141836p:plain

修正してほしい箇所があった場合、該当行の左端にある+からコメントを追加することができます😳便利〜!
f:id:mistyrinth:20190116142407p:plain

自作自演になってしまいますが、修正指示がきたので修正し、再度コミットを行います。
f:id:mistyrinth:20190116142736p:plain

2-5. 画面上でマージ

レビュー担当者は、再度レビューした結果、問題が無ければマージします👌
f:id:mistyrinth:20190116143155p:plain

Merge pull requestを押すと、以下のようにコメントを書くことができます。
f:id:mistyrinth:20190116143303p:plain

コメントは「修正ありがとうございました」などなんでもOKです😊
コメントを書いてConfirm mergeを押すと、マージされます😆✨
f:id:mistyrinth:20190116143412p:plain

3.マージできない場合は?

3-1. 競合の発生

練習のため、別の開発者との競合が発生して、マージできない状況を作ってみます🙁
開発者Aが先程の等価演算子==を使用し、開発者Bが厳密等価演算子===を使うとします。
条件は先程と同じなので、再度新規リポジトリを作成してmasterブランチにjsファイルを作成します🖋
f:id:mistyrinth:20190116144936p:plain

開発者Aが作業するためのadd-sort-func1というブランチと、開発者Bが作業するためのadd-sort-func2というブランチを作成します。
add-sort-func1には、等価演算子==を使ってコードを書き足します。
f:id:mistyrinth:20190116145149p:plain

先程のチュートリアルと同様に、Compare & pull requestからプルリクエストを作成し、修正が無いものとしてマージします!
f:id:mistyrinth:20190116145458p:plain

続いて、ブランチをadd-sort-func2に切り替えて、厳密等価演算子===を使ってコードを書き足します。
f:id:mistyrinth:20190116150044p:plain

今度はPull requestsメニューからNew pull requestボタンを押して、プルリクエストを作成します。
f:id:mistyrinth:20190116150232p:plain

base: masterのままcompare: add-sort-func2を選択すると、自動マージができないと言われました🤨
競合が発生しているからですね〜!
そのままConfirm pull requestを行い、プルリクエストの作成を実行すると、コンフリクトがあると言われます。
f:id:mistyrinth:20190116150652p:plain

InsightsNetworkから、ブランチの様子を見ることができます。
f:id:mistyrinth:20190116150828p:plain

3-2. 競合の解決

この競合を解決するには、Resolve conflictsボタンを押します🙂すると競合箇所が表示されます!!
f:id:mistyrinth:20190116151238p:plain

今回の場合は厳密等価演算子===を使用するように競合を解決して、Commit mergeボタンを押します。
f:id:mistyrinth:20190116151556p:plain

あとは通常通りにマージしていき、完了です👏✨
f:id:mistyrinth:20190116151722p:plain

f:id:mistyrinth:20190116151731p:plain

以上です〜!

Git入門 part4 / タグ, コミット

本日もサルでもわかるGit入門の発展編の続きをやっていきます〜!

目次

1.発展編

1-1. タグ

コミットを参照しやすくするために、コミットに名前を付けることができます。
この名前をタグと言い、どのコミットかわかりやすいように任意の名前を付けることができます😊

Gitでは以下の2種類のタグが使用できます。

できること 軽量タグ 注釈付きタグ
名前を付ける
コメントを付ける ×
署名を付ける ×

一般的には、軽量タグはローカルで一時的に使用するような、使い捨てタグとして使用されます。注釈付きタグは、リリース用のタグとして使われます💡
また、一度付けたタグは位置が移動することがなく、固定されます。

1-2. チュートリアル タグ

前準備

タグを作るチュートリアルをやっていきます💪
まずはtutorialというディレクトリを作って、リポジトリを作成するところから!
このあたりはGit入門 part1で解説しているとおりです。
f:id:mistyrinth:20190108151617p:plain
リポジトリを作成し、myfile.txtの中に以下の1文を書いてコミットしました😊

サルでもわかるGit入門

軽量タグを追加する

まずは簡単な軽量タグから!🔖
現在のHEADが指しているコミットに軽量タグを追加するには、tagコマンドを使用します。

$ git tag タグ名

今回はappleというタグを付けます🍎
ちなみに、タグ名を指定せずにtagコマンドを実行することで、タグの一覧を表示できます。
また、履歴の一覧を表示するlogコマンドに--decorateオプションを付けて実行すると、タグ情報を含めた履歴を表示することができます😇
f:id:mistyrinth:20190108153408p:plain

注釈付きタグを追加する

現在のHEADが指しているコミットに注釈付きタグを追加するには、tagコマンドに-aオプションを指定します。
実行するとテキストエディタが起動するので、タグに設定するコメントを入力します✍️
-mオプションを指定して、直接コメントを与えることもできます。
また、tagコマンドに-nオプションを指定すると、タグの一覧とコメントを表示できます🔍

$ git tag -a タグ名

ここではbananaという注釈付きタグを付けます🍌
f:id:mistyrinth:20190108153559p:plain

タグを削除する

作成したタグを削除するには、tagコマンドに-dオプションを指定します!
f:id:mistyrinth:20190108153858p:plain

タグは簡単でしたね〜🥳🥳🥳

1-3. コミットの書き換え

コミットを書き換える方法として、以下のようなものが挙げられます。

コマンド 用途
commit --amend 同じブランチの直前のコミットに対し、内容の追加やコメントの修正を行う
※amend は commit コマンドのオプション
revert 指定したコミットの内容を打ち消すコミットを作成する
コミットが公開済みで削除できない場合にrevertが使われる
reset 不要なコミットを削除する
※詳細は下記
cherry-pick 別のブランチにある指定したコミットをコピーし、現在のブランチに取り込む
rebase -i コミットの書き換え、入れ替え、削除、統合を行う
※ i はrebase コマンドのオプション
merge --squash 指定のブランチのコミット全てをまとめたコミットを追加する
※ squash は merge コマンドのオプション

resetコマンドについては前回の記事でかなり雑に扱ってしまいましたが、改めて学習します!
参考にしたのはこちらのサイトです🙋‍♀️

www-creators.com

resetコマンドの用途は以下の2つです。

- 用途1:インデックスを任意の状態にリセットする
- 用途2:ブランチの先頭`HEAD`を指定したコミットに強制移動する

また、resetコマンドのオプションには、--soft--hardがあります。内容は以下のとおりです😊

モード オプション 解説
mixed 無し(default) HEADの位置を戻したい場所に移動してインデックスを更新するが、作業ツリーはそのままにする
soft --soft HEADの位置を戻したい場所に移動するが、インデックスと作業ツリーはそのままにする
hard --hard HEADの位置を戻し、インデックスも作業ツリーも丸ごとリセットする

1-4. チュートリアル コミットの書き換え

以上を踏まえ、チュートリアルを進めます🏃‍♂️

commit --amend

予め履歴が用意されているローカルリポジトリを使ってチュートリアルを行います。
ダウンロードはチュートリアルページの始めのほうにリンクがあります✨
stepup-tutorialというファイルがダウンロードされるので、私はデスクトップに置いてアクセスすることにします。(もちろんどこでもいいです)
f:id:mistyrinth:20190108160502p:plain
キャプチャのように、stepup-tutorialの中にはtutorial1からtutorial7までのディレクトリが保存されています。
まずはtutorial1に移動し、リポジトリの履歴をチェックしたところ、既に2回コミットがされていますね👀
1回目がfirst commit、2回目がaddの説明を追加と書いてある部分です。

早速commit --amendを行います!これは直前のコミットの内容の追加やコメントの修正を行うオプションですよ🙌

tutorial1には予めsample.txtが保存されているので、中身を確認すると、以下の2行が書かれています。

サルでもわかるGitコマンド
add 変更をインデックスに登録する

前回のコミットでは、addコマンドの説明(2行目)を追加したことがわかりましたね。
ここに3行目を記載するのですが、commit --amendを使って、前回のコミットで2〜3行目を同時に追加したことにします😎
3行目の内容は以下のとおりです。

commit インデックスの状態を記録する 

一連の流れを以下に貼り付けます。
f:id:mistyrinth:20190108161757p:plain

最後のgit commit --amendを実行すると、エディタが起動し、コメントの編集ができます。
キャプチャはこちら👇
f:id:mistyrinth:20190108162336p:plain
1行目のaddaddとcommitに書き換えます!😆
f:id:mistyrinth:20190108162551p:plain
これでエディタを閉じると、コミットの書き換えが行われます🙃
そして再度logコマンドで履歴を確認すると、最初に現れた内容と変わっているため、前回のコミットが書き換えられていることが確認できますね🎉🎉

revert

次に、コミットの内容を打ち消すコミットを作成するrevertコマンドを使います。
ディレクトリはtutorial2に移動します👣
ひとまずtutorial2の中身と履歴を確認していきます。

f:id:mistyrinth:20190108163757p:plain

tutorial2の中身はsample.txtですね👀
コミットは4つあることと、sample.txtの中身は3行であることがわかります。
最初のコミットの後、1行ずつ追加してコミットしていったのですね〜🧚‍♀️

revertコマンドを使って打ち消すコミットの内容は「pullの説明の追加」にします。
最新のコミットなので、HEADが指しているところにあたりますね😊

f:id:mistyrinth:20190108164900p:plain

revertコマンドを実行すると、エディタが起動します。キャプチャは以下のとおりです📷
f:id:mistyrinth:20190108164949p:plain
これは特に修正する必要がないので、このまま閉じました🙂
logコマンドで履歴を確認すると、revertの履歴が追加されました!
sample.txtを開くと、pullの説明がなくなっています。
これが「コミットの内容を打ち消すコミットを作成する」ということなんですね💪

reset

今度はtutorial3ディレクトリを使って、resetコマンドをやってみます!
最初はtutorial3の中身と履歴を確認します。

f:id:mistyrinth:20190108200943p:plain

tutorial2と同様、tutorial3の中身はsample.txtだけですね。
コミットは4つあることと、sample.txtの中身は4行であることがわかります。

チュートリアルでは、resetコマンドを使ってmasterブランチの先頭から2つ分のコミットを削除します。

先程挙げたresetコマンドのオプションをおさらいします👀

モード オプション 解説
mixed 無し(default) HEADの位置を戻したい場所に移動してインデックスを更新するが、作業ツリーはそのままにする
soft --soft HEADの位置を戻したい場所に移動するが、インデックスと作業ツリーはそのままにする
hard --hard HEADの位置を戻し、インデックスも作業ツリーも丸ごとリセットする

masterブランチの先頭から2つ分のコミットを削除」ということは、--hardオプションがつきます!
また、HEAD(masterブランチの先頭)から2つ前はHEAD~~と書いて表すことができます。
参考記事:Git入門 pert3 / ブランチ

つまり実行するコマンドはgit reset --hard HEAD~~になります💪

f:id:mistyrinth:20190108202847p:plain

sample.txtの中身は、commit と pull の説明がなくなっていますね👌 logコマンドで履歴を確認すると、コミットが削除されていることが一目瞭然です。
--headオプションなので、ツリーごと削除してしまいました😊

ちなみに、間違えてresetしてしまった場合などは、resetコマンドでORIG_HEADという名前のブランチに reset することで、 reset 前の状態に戻すことができます。

cherry-pick

次にtutorial4ディレクトリを使って、cherry-pickコマンドをやります。
cherry-pickとは、別のブランチにある指定したコミットをコピーし、現在のブランチに取り込むコマンドでしたね🍒
これまでと同様、まずtutorial4の中身と履歴を確認します。

f:id:mistyrinth:20190108205500p:plain

tutorial4も中身はsample.txtだけです。
コミットは3つあり、sample.txtの中身は3行です。
また、最後にbranchコマンドで確認したとおり、今はissue1というブランチにいます!
このissue1ブランチで行った「commitの説明の追加」という変更をmasterブランチに取り込みます。

まずmasterブランチにチェックアウトします。
次に「commitの説明を追加」したコミットのコミットIDを指定してcherry-pickコマンドを使うことで、コミットを取り出し、masterに追加します。

コミットIDは上のキャプチャでいう99daed25b45fcae2ce9d707a3434951cf69f253aですね🧐
長すぎるのですが、全部入力しなくても、最初の数文字だけで大丈夫みたいです✨

f:id:mistyrinth:20190108214430p:plain

cherry-pickコマンドを行ったときに競合が発生したため、sample.txtを修正してからコミットしました😆
また、最後にコミットした時に表示されたエディタでは、コメントを編集できました。
このあたりはcommit --amendのときと同じなので割愛します。

rebase -i でコミットをまとめる

今度はtutorial5rebase -iチュートリアルを進めます。
rebase -iは、コミットの書き換え、入れ替え、削除、統合を行うコマンドでした。
tutorial5ではsample.txtの中身は触らないため、中身の確認はしません🙃
logコマンドで履歴の確認をします。

f:id:mistyrinth:20190108215337p:plain

コミットが4つありますね👀
ここでrebase -iコマンドを使って、HEADから2つめ(HEAD~~)の「pullの説明を追加」以降の変更をひとつのコミットに統合します!

f:id:mistyrinth:20190108220659p:plain

rebase -iを実行すると、HEADからHEAD~~までのコミットがエディタで表示されます。
f:id:mistyrinth:20190108220749p:plain
この2行目先頭のpicksquashに書き換えます🖋押し込めるという意味ですね💡
f:id:mistyrinth:20190108220923p:plain
この状態で保存すると、統合した後のコミットに設定するメッセージがエディタで表示されます。
必要に応じて編集し、保存します。私は編集せずそのまま保存しました🙂
f:id:mistyrinth:20190108221148p:plain

以上で、2つのコミットが1つのコミットに統合されました🎉🎉
logコマンドで履歴を確認します。
f:id:mistyrinth:20190108221517p:plain
3つめのコミットに、元々2つだったコミットが統合されていますね☀️

rebase -i でコミットを修正する

先程と同じくrebase -iコマンドですが、今度はコミットを修正する方法です。
tutorial6を使います。

f:id:mistyrinth:20190108221847p:plain

既にコミットが4つあります。
ここでは、HEADから2つめの「commitの説明を追加」で行った変更内容を修正します✍️
手順は途中まで先程のtutorial5と同様で、まずはrebase -i HEAD~~を実行します。

f:id:mistyrinth:20190108223356p:plain

途中で現れる別画面エディタはこちらです。
f:id:mistyrinth:20190108222529p:plain

rebase -i HEAD~~コマンドを実行すると、エディタに HEAD から HEAD~~ までのコミットが表示されます。
先程と異なるのは、今度は1行目先頭のpickeditに変更して保存するところです😊
エディタを終了すると、修正したいコミットがチェックアウトされた状態になります。
その状態でsample.txtを修正します\(^^)/
ここからは少しだけチュートリアルと進みが異なるのですが、 私は文章の一番最後に顔文字\(^^)/を付け足しました。

f:id:mistyrinth:20190109195858p:plain

rebase -i HEAD~~を実行したときに現れるエディタは以下のとおりです。
※私が\(^^)/を書き加えています💡
f:id:mistyrinth:20190109195450p:plain

チュートリアルと違うのは、私の場合HEAD~~を編集してHEAD~(Pullの説明)と競合してしまうところです。
チュートリアルでは競合が発生しないようにHEAD~の内容を書き足しているのですが、私にはちょっとわかりにくかったので自分なりにやってみます笑
私の場合だと、rebase --continue実行時に競合が発生していますね🙂

ここからはチュートリアルから少し逸れてしまいますが、競合が発生したら、sample.txtに書かれているコンフリクトを見て修正し、再度addrebase --continueを実行します。
この際、commit --amendは行いません✋
競合を解消した後には必要ないですね😊

f:id:mistyrinth:20190109200747p:plain

最後のrebase --continueで現れるエディタの内容はこちらです。
f:id:mistyrinth:20190109201126p:plain
これはそのまま編集せずに保存・終了しました😎

ちなみに途中で出てくるstatusコマンドは、前回のコミットと比較してどのファイルが変更されたか表示されます。
競合発生時にもやっておけば見比べられて良かったのですが、競合解消後と最後しかやってなくてすみません…笑

merge --squash

最後はtutorial7を使ってmerge --squash`コマンドをやってみます!
これは「指定のブランチのコミット全てをまとめたコミットを追加する」というものでした。

まずtutorial7に移動し、現状の履歴をlogコマンドで確認します。 f:id:mistyrinth:20190108233726p:plain

3つのコミットがあることが分かりますね🙂それから、今はissue1ブランチにいます。
ここからmasterブランチにチェックアウトし、merge --squashコマンドを実行することで、issue1のコミットを全てまとめてmasterの新規コミットを作成できます✨✨

f:id:mistyrinth:20190108235150p:plain
競合が発生したため、sample.txtを開いて競合を解消しました💡
競合を解消したら、コミットしていきます。
f:id:mistyrinth:20190108235544p:plain

issue1ブランチのすべてのコミットを1つにまとめたコミットがmasterブランチに追加されましたね😆😆

発展編は以上です〜!次回はPull request編!😊

Git入門 part3 / ブランチ

サルでもわかるGit入門の発展編に突入です!
入門編の記事は、part1part2があります😊

目次

1.発展編

1-1. ブランチ

ブランチとは 

Git入門 part2で少しだけ登場したブランチというものを学習します。
ブランチ(branch)は英語のとおり、履歴の流れを枝のように分岐して記録していくためのものです🌲
ブランチは他のブランチの影響を受けないため、同じリポジトリ中で複数の変更を並行して進めることができます。
また、ブランチは他のブランチと合流(マージ)し、ひとつのブランチとなることもできます🤝
そのためソフトウェア開発において、各担当者が別々のブランチでそれぞれ作業を行い、最後にマージしてひとつのソフトウェアとすることが可能になります✨
リポジトリに最初のコミットを行うときはmasterという名前のブランチが作成されます。
それ以降のコミットは、ブランチを切り替えるまでmasterブランチに追加されていきます。

ブランチとの運用方法

ブランチの運用方法についてはおそらくチームごとに決めるのですが、今回は統合ブランチトピックブランチの2つを使った運用方法について学習します💡

統合ブランチは、リリース版をいつでも作成可能な状態にしておくためのブランチです。
通常、masterブランチを統合ブランチとして使用するようです😗
トピックブランチは、機能追加やバグ修正など、ある課題に関する作業を行うためのブランチです。
統合ブランチから課題に関するトピックブランチを作成し、トピックブランチでの作業が完了したら、統合ブランチに取り込むという使い方をします。
芯となる統合ブランチがあることで、情報がごちゃごちゃしなくて良いですね😊

ブランチの切り替え

作業するブランチを切り替える操作をチェックアウトと言います。
また、現在使用しているブランチの先頭のことをHEADと表します。このHEADが移動することで、作業するブランチが変更される仕組みです💡

コミットを指定するときに、この時にHEADと後述の記号を組み合わせて、あるコミットからの相対位置で指定することもできます。

記号 読み方 用途
~ チルダ 何世代前の親かを指定する
^ キャレット 何番目の親かを指定する

使い方のイメージは以下のような感じです😊凡例を書き忘れてしまったのですが、葉っぱはコミットです。
f:id:mistyrinth:20181224124710p:plain

変更内容をコミットしていないままチェックアウトを行うと、その変更内容はワークツリーやインデックスに残ったまま、移動先のブランチに移ります。
ただし、移動先のブランチで既にそのファイルに変更が行われている場合、チェックアウトに失敗してしまいます💦
このような場合に、一時的に変更内容を退避させてからチェックアウトする方法があります。
stashという、ファイルの変更内容を一時的に記録しておく領域を使い、ワークツリーとインデックス内にあるコミットされていない変更を、一時的に退避させることができます!
また、退避させた変更は後から取り出して、元のブランチや別のブランチに反映させることができます👏

ブランチの統合

トピックブランチでの作業が完了したら、最終的に統合ブランチに統合されます。
ブランチを統合する方法として、mergeを使う方法と、rebaseを使う方法の2種類があります。
どちらを使うかによって、統合後のブランチの履歴が大きく異なるそうなので、しっかり学習しておきます😎

方法 特徴
merge ・各々の変更履歴を統合する
・変更内容の履歴がそのまま残る
・履歴が複雑になる
rebase ・それぞれのコミットで競合を解消し、履歴を一本化する
・元のコミットの変更履歴が変わる
・履歴は単純になる

図で表すと以下のようになります。
f:id:mistyrinth:20181226171143p:plain

うーん分かりにくい…😶笑
チュートリアルに進んでみましょう!!

1-2. チュートリアル1 ブランチを使ってみよう

早速チュートリアルに沿って進めていきます🚗

前準備

まずはtutorialディレクトリを作って、空のリポジトリを作成します。

$ mkdir tutorial
$ cd tutorial
$ git init

次にmyfile.txtというファイルを作成し、サルでもわかるGitコマンドというテキストを入力してコミットします。

今回からコンソールの入力/出力の表示を変えました〜!
今までは枠で囲ってたのですが、沢山続くと見にくいのでマーカーにしました😊
f:id:mistyrinth:20181226175741p:plain

ブランチを作成する

早速、branchコマンドを使ってissue1という名前のブランチを作成します。

$ git branch ブランチ名

また、branchコマンドで引数を指定しない場合、ブランチ一覧を表示します。
*が付いているのが、現在のブランチです🌲

f:id:mistyrinth:20181226180718p:plain
今はmasterブランチにいますが、他にissue1ブランチがあることが確認できますね✨

ブランチを切り替える

issue1ブランチにコミットを追加していくには、checkoutコマンドを使ってissue1ブランチをチェックアウトします😊
宿泊施設のチェックアウトとは違って指定したブランチを出るのではなく、指定したブランチに切り替えるコマンドです!

$ git checkout ブランチ名

ここではブランチ名はissue1になります👆
f:id:mistyrinth:20181226183838p:plain

ちなみに、以下のようにcheckoutコマンドに-bオプションを付けると、ブランチの新規作成とチェックアウトを同時に行えます✨

$ git checkout -b ブランチ名

続いて、myfile.txtの中身に2行目を追加してコミットします🙂

f:id:mistyrinth:20181226184228p:plain

ブランチをマージする

先程issue1で行った変更をmasterブランチに merge します。
まずはcheckoutコマンドでmasterブランチに移動します。

$ git checkout master

f:id:mistyrinth:20190107160646p:plain

myfile.txtの編集はissue1ブランチ上で行ったため、masterブランチのほうでは内容は変更されていないことが確認できます。

ブランチのmerge はmergeコマンドで実行できます😊

$ git merge 取り込みたいブランチ名

このコマンドを実行すると、指定したブランチがHEADの指しているブランチに取り込まれます!

f:id:mistyrinth:20190107161431p:plain

masterブランチのコミットがissue1と同じ位置(HEAD)に移動しました👌
このマージはfast-forward(早送り)マージと呼ばれます。 遅れているmasterブランチのコミットをさくっとissue1と同じコミットの位置まで持ってくることができるので、早送りと言われるんでしょうね😶

ブランチを削除する

issue1ブランチの内容はmasterブランチに無事統合されたため不要になりました。
issue1ブランチを削除します!
ブランチの削除は、branchコマンドに-dオプションを指定して実行します。

$ git branch -d ブランチ名

f:id:mistyrinth:20190107162252p:plain
branchコマンドでブランチの一覧を確認すると、issue1が削除されているのがわかります🎉

並行で作業する

今度は、2つのブランチで並行で作業してみます!
まずissue2ブランチとissue3ブランチを作成し、issue2ブランチをチェックアウトします。

f:id:mistyrinth:20190107162911p:plain

まずはissue2ブランチ側の作業です!
myfile.txtcommitコマンドの説明を追加してコミットします。
f:id:mistyrinth:20190107163334p:plain

一方、issue3ブランチのmyfile.txtにはpullコマンドの説明を追加します👀
issue3ブランチをチェックアウトし、myfile.txtpullコマンドの説明を追加してコミットします。

f:id:mistyrinth:20190107164028p:plain
これでissue2issue3masterに統合しようとすると、衝突が起きますね…!💥

マージでの衝突を解決する

いよいよ、issue2ブランチとissue3ブランチそれぞれでの変更をmasterブランチに統合します💪
まず、masterブランチをチェックアウトして、issue2ブランチを merge します。

f:id:mistyrinth:20190107164912p:plain

ここでは何の問題も無くfast-forwardマージが行われますね🙂
続いて、issue3ブランチをmasterブランチにマージします。

f:id:mistyrinth:20190107165408p:plain

自動マージに失敗し、myfile.txtには競合箇所が示されています。
前回のおさらいですが、競合箇所の読み方は以下のとおりです!

<<<<<<<
現在チェックアウトしている側の内容(ここではmasterブランチ)
=======
競合相手の内容(ここではissue3ブランチ)
>>>>>>>

これを受け、myfile.txtを以下のように修正します✍️

サルでもわかるGitコマンド
add 変更をインデックスに登録する
commit インデックスの状態を記録する
pull リモートリポジトリの内容を取得する

修正したら、改めてコミットします。
f:id:mistyrinth:20190107180928p:plain
出てくる文字が少ないですが、エラーではないので、たぶんOKだと思います!笑

今回の merge では、競合箇所を修正して、その変更を記録するマージコミットが作成されました。そこにmasterの先頭が移動していることになります🚗
このようにfast-forwardではないマージは、non fast-forwardマージと呼ばれます😂

rebaseでマージする

先程issue3ブランチをマージする際にissue3ブランチを rebase したら、履歴を一本にすることができました💡
rebase のチュートリアルをやってみます🙌
まずは一旦、resetコマンドの--hardオプションで先程行ったマージを取り消します!
resetコマンドはそれだけで結構書ける内容なので、ここでは解説を割愛して以下のコマンドをそのまま実行します。

$ git reset --hard HEAD~

resetコマンドについて詳しくは以下のブログを拝見しました!わかりやすかったです😊

git reset コマンドの使い方と、主要オプションまとめ | WWWクリエイターズ

実行するとこんな感じになります。
f:id:mistyrinth:20190107184018p:plain

これで現状issue2masterブランチにマージ済みで、これからissue3ブランチをマージするところまで戻りました!
ここでissue3ブランチをチェックアウトし、masterブランチに対して rebase を実行します!

f:id:mistyrinth:20190107184349p:plain

やはりmyfile.txtで競合が発生するため、mergeの時と同じmyfile.txtを修正します。
myfile.txtの中身は先程と全く同じなので、修正も割愛します〜👣

競合箇所を修正したら、rebase の場合にはコミットではなく、rebaseコマンドに--continueオプションを指定して実行します。
これにより、masterブランチはissue3ブランチをfast-forwardマージできるようになります✨
masterブランチをチェックアウトしてマージを実行します。

f:id:mistyrinth:20190107185913p:plain
mergeと比べて履歴(経緯)は異なりますが、myfile.txtの最終的な内容は同じです🤝

1-3. リモートリポジトリ

リモートリポジトリに対する動作として、pushやpullを学びました。
参考記事:Git入門 part1 / Gitの基本

おさらいを兼ねて、Fetchも合わせて意味を確認します!

用語 意味
Push ローカルリポジトリの履歴をリモートリポジトリにアップロードすること
Pull リモートリポジトリの履歴をローカルリポジトリにダウンロードすること
自動的にマージコミットが作成されるが、競合があれば手動で解決する
内部的に Fetch + merge をしている
Fetch マージせずにリモートリポジトリの履歴を取得すること
取得したコミットは名前の無いブランチとして作成される
(FETCH_HEADという名前でチェックアウトできる)

本日は以上です🙂

Git入門 part2 / リポジトリの共有, 変更履歴の統合

本日はサルでもわかるGit入門 リポジトリの共有から勉強していきます!
前回の記事はこちらになります。

目次

1.前回のおさらい

前回の記事では、様々な Git 用語が出てきました💡
記事の最後に用語の意味を一覧にまとめたので、おさらいとして再掲します。

用語 意味
repository データの状態を保存する場所
作業用のローカルリポジトリと共有用のリモートリポジトリがある
Push ローカルリポジトリからリモートリポジトリにアップロードすること
Pull リモートリポジトリからローカルリポジトリにダウンロードすること
commit ファイルやディレクトリの追加・変更をリポジトリに記録する操作
worktree 実際に作業をするディレクト
index リポジトリとワークツリーの間にあり、リポジトリにコミットするための準備をするところ

2.入門編

2-1. リポジトリの共有

早速サルでもわかるGit入門を進めていきます!

リポジトリとは、ファイルやディレクトリの状態を保存(コミット)しておく場所のことでしたね🙂
作業を行うためのローカルリポジトリと、他の人と共有するためのリモートリポジトリがありました。
前回の記事では、新規のローカルリポジトリを作成するところまでやったので、ここではリモートリポジトリの使い方を学びます!

Git では、ローカルリポジトリ内の変更履歴をリモートリポジトリにアップロードする操作を Push と言います。
逆に、リモートリポジトリの変更履歴をローカルリポジトリにダウンロードする操作を Pull と言います。

また、リモートリポジトリを複製する操作は、Clone と言います。
クローンを実行すると、リモートリポジトリの内容をまるまるダウンロードしてきて、別のマシンにローカルリポジトリとして作成できます👌

2-2. チュートリアル2 リポジトリの共有

チュートリアルにある「リモートリポジトリをBacklog上に作成する」というのは GUI環境でやるっぽいですね。
Backlogはどうやら有料サービスのようなので、 Github でやってみます!
Githubも非公開リポジトリを作るのは有料プランにする必要があるみたいなので、公開リポジトリにしちゃいます😊
勉強用だし、見られてもたぶん困らないでしょう笑
f:id:mistyrinth:20181222134252p:plain
何も設定されていない空のリポジトリが作成されました。名前はtutorialです。
前回の記事で作成したtutorialという名前のローカルリポジトリの履歴を、このリモートリポジトリに Push します!💪💪

Push する際に、対象のリモートリポジトリのアドレスを指定するのですが、毎回いちいちアドレスを入力しなくても済むように、アドレスに名前をつけて記録しておくことができます💡
ここではリモートリポジトリのアドレスにoriginという名前を付けて登録し、Pushを行います。
アドレスの登録にはremoteコマンドを使います👆

$ git remote add 登録名 リポジトリURL

先程Github上に作成したリモートリポジトリのURLはhttps://github.com/mistyrinth/tutorial.git です。
私の場合、以下のようになります👌
f:id:mistyrinth:20181222135637p:plain

いよいよローカルリポジトリのコミットをリモートリポジトリに Push します!
pushコマンドを使用します😊

$ git push プッシュ先URL ブランチ名

ブランチについては発展編で詳しく学習できるみたいなので、今はチュートリアルのとおり、ブランチ名をmasterにして進めてみます!
なお、空のリモートリポジトリに初めて Push するときはブランチ名を指定する必要がありますが、pushコマンドの-uオプションを指定すると、次回以降はブランチ名の指定を省略できます✨
プッシュ先URLは、先程originという名前で記録したので、originと書けばOKです!
実際にやってみました。
f:id:mistyrinth:20181222141145p:plain
成功したみたいですね〜🎉
ブラウザで Github を見てみると、空だった tutorial にsample.txtが追加されています!
前回作ったテキストファイルが反映されていますね。

今度はリモートリポジトリのクローンをしてみます😆
練習のため、先程自分で作ったリモートリポジトリをクローンします。
cloneコマンドを使用します。はリモートリポジトリのURL、は複製先のディレクトリ名を指定します。

$ git clone リモートリポジトリURL 複製先ディレクトリ

複製先ディレクトリに任意の名前を指定すると、カレントディレクトリにその名前のディレクトリ名を作って複製することができます。
ここでは複製先ディレクトリをtutorial2とします。今はtutorial2という名前のディレクトリは存在しないので、カレントディレクトリ(この場合ホームディレクトリ内のtutorial内)にtutorial2という名前のディレクトリが作成されます📁
f:id:mistyrinth:20181222142401p:plain

クローンが成功したか確認してみます。
f:id:mistyrinth:20181222143023p:plain
できました!🧸
tutorialの中にtutorial2というディレクトリが作成され、中にはsample.txtがあります。
誤解してはいけないのが、cpコマンドと同じようにローカルリポジトリ内で複製したのではなく、リモートリポジトリ(Github)から複製してきたという点ですね😊😊

更に、複製して作ったtutorial2からもリモートリポジトリに Push してみます。
tutorial2内のsample.txtに2行目を追記しました!
f:id:mistyrinth:20181222143628p:plain

前回と同じ流れで Push していきます。
振り返る場合は前回の記事をご参照ください🌝
f:id:mistyrinth:20181222145206p:plain
元々リモートリポジトリにあったものをクローンしたものなので、pushコマンドの際にPush先のURLやブランチ名は省略できました👌
Githubを見ると、tutorial2が反映されています✨
f:id:mistyrinth:20181222145433p:plain
注意点は、tutorial2の変更点をリモートリポジトリに Push したのであって、複製したわけではないということです。
Githubtutorialの中にtutorial2が入ったわけではなく、Githubtutorialtutorial2に更新した感じです💡そのため、前回からの変更点を見ることができます。

今度は、tutorial2からリモートリポジトリに Push した内容を、ローカルリポジトリであるtutorialに Pull します。
以下のようにpullコマンドを使用します。
リポジトリ名を省略すると、originの名前で登録されているリポジトリに対してpullを行います。

$ git pull リポジトリ名 参照仕様

参照仕様 (refspec) とは、この場合ブランチ名masterです。入門編のうちは、そのくらいの解釈で良いのだと思います!笑
実際に Pull を行い、正しくできているか確認を行いました。
f:id:mistyrinth:20181222160850p:plain
logコマンドで変更履歴を見ると、「addの説明を追加」という履歴が現れましたね!!これはtutorial2で行い、リモートリポジトリに Push したものなので、大成功です😆

2-3. 変更履歴の統合

今のところ一人で Push や Pull をしているので問題ありませんが、例えば、私が最後に Pull を実行してから次に Push するまでの間に別の人が Push をして、リモートリポジトリが更新されたとします。
こうなってしまうと、私は Push が拒否されてしまいます😖もし私が Push できてしまったら、せっかくの別の人の変更履歴を失ってしまうからですね。
この場合、マージという作業を行って自動的に他の変更履歴を取り込むことで、別の人による変更履歴を失わずに Push することができます🙌

ただし、リモートリポジトリ(別の人)とローカルリポジトリ(私)がたまたま同じ箇所を変更していた場合は、マージしようとしても、どちらの変更を取り込むかを自動で判断できず、エラーになります。
このように競合が発生した箇所は、エラーを見ながら手動で修正することになります💦

2-4. チュートリアル3 変更履歴の統合

競合を解決してマージする練習として、tutorialtutorial2を使ってセルフ競合してみます👣
現在、tutorialtutorial2それぞれにsample.txtが保存されており、中身はどちらも以下の2行です。

サルでもわかるGitコマンド
add 変更をインデックスに登録する

これをtutorialtutorial2で別の変更を行い、マージを試します!
それぞれ、最後の1行に次の異なる文章を追加します。

tutorial:commit インデックスの状態を記録する
tutorial2:pull リモートリポジトリの内容を取得する

以下がtutorialsample.txtの中身です。
f:id:mistyrinth:20181222155229p:plain
addコマンドでインデックスの追跡対象に登録し、commitコマンドでローカルリポジトリtutorialにコミットします。
f:id:mistyrinth:20181222155930p:plain

一方、以下がtutorial2sample.txtの中身です。
f:id:mistyrinth:20181222155259p:plain
こちらも同様にaddコマンドでインデックスの追跡対象に登録し、commitコマンドでローカルリポジトリtutorial2にコミットします。
f:id:mistyrinth:20181222160015p:plain

これらを同じリモートリポジトリに Push してみます!
まずはtutorial2のほうから。
f:id:mistyrinth:20181222160350p:plain
これにより、リモートリポジトリ側には3行目の変更履歴として pull の説明が追加されたことになりました!
f:id:mistyrinth:20181222160439p:plain
続いて、tutorialから Push してみると、競合が起きているためエラーになりました!!
f:id:mistyrinth:20181222160951p:plain

競合を解決するために、まずはエラーになってしまったtutorial側で Pull を行い、変更履歴を取得します。
f:id:mistyrinth:20181222161415p:plain
"Automatic merge failed"とのこと🔥🔥
あとは"Merge conflict in sample.txt"と書かれていますね👀
tutorialsample.txtを開いてみます!
f:id:mistyrinth:20181222161903p:plain
なんと、競合箇所を教えてくれています✨✨✨
読み方は以下のとおりです。

<<<<<<<
ローカルリポジトリ(ここでは競合により拒否されたほう)
=======
リモートリポジトリ(ここでは先に push されていたほう)
>>>>>>>

これをどう扱うか決めて、手動で解決していくこととなります。
今回は両方の変更を取り入れ、以下のように3行目に commit の説明、4行目に pull の説明がくるように編集します💪
f:id:mistyrinth:20181222162559p:plain
修正を Push に反映させるために、再度addcommitを行います。
f:id:mistyrinth:20181222163003p:plain

ここで Push の前に、logコマンドの--graphオプションと--onelineオプションを試してみます!
--graphオプションは、変更履歴の流れをテキスト表示することができます。
--onelineオプションは、コミットの情報を一行で表示します。
f:id:mistyrinth:20181222163827p:plain
logコマンドの表示から、2つの分岐が一つに統合されたことが分かります😆
無事pushは成功しました!!
f:id:mistyrinth:20181222163938p:plain
自作自演のため全部私のアイコンで一見わかりにくいのですが、tutorialをいじった人とtutorial2をいじった人が違う場合、このように履歴に残るので便利ですね〜!

Git入門編は以上です🌝

Git入門 part1 / Gitの基本

作った gem を Github に公開するために、Github の使い方を覚えておく必要があります😊
また、Github を使うために、まずは git の知識が必要になるようです。
ということで本日はサルでも分かるGit入門をやっていきます!
遠回りですみません😭😭

目次

1.入門編

1-1. Gitの基本

Git は、分散型バージョン管理システムのひとつです。
例えば社内サーバにおいて、Aさんがデータをサーバに保存し、後日Bさんが更新をして、更にCさんとDさんがそれぞれ編集して同時に更新したら、一方が消えてしまった…ということが起こりえます😖
Git では、データの状態を好きなときに更新履歴として保存して、過去の状態に戻したり、更新箇所を確認したりできるそうです!

ファイルやディレクトリの状態を保存する場所をリポジトリといいます。
状態を保存するということは、前回の保存状態との差分から、更新した内容を表示することもできます😊

リポジトリにはローカルとリモートの2つがあり、普段は個人がローカルリポジトリで作業を行い、作業が終わったら、他の人と共有するためにリモートリポジトリにファイルをアップロード(push)するということになります。
また、他の人が作成したファイルをリモートリポジトリから自分のローカルリポジトリにダウンロード(pull)することもできます。

また、ファイルやディレクトリの状態をリポジトリに記録する操作をコミットと言います。
コミットを実行すると、前回コミットした状態から現在の状態までの差分を記録したコミット(またはリビジョン)が作成されます。コミットは動詞でもあり名詞でもあるんですね〜!
また、コミットの実行時にはコミットメッセージを入力します。
Git のコミットメッセージの書き方は以下のとおりです💡

1行目 : コミットでの変更内容の要約
2行目 : 空行
3行目以降 : 変更した理由

そして、実際に作業するディレクトリをワークツリーと呼びます。
ワークツリーは Git の管理下にあり、ワークツリーとリポジトリの間にはインデックスというものがあります🔖
インデックスとは、ワークツリーで作業したファイルをリポジトリにコミットするための準備をする場所です。
コミットする時は、ワークツリーから直接リポジトリ内に状態を記録するのでなく、インデックスの設定に従って状態を記録します。
これにより、ファイル丸ごと全部をコミットしなくても部分的にコミットすることができます✨

1-2. チュートリアル1 Gitの基本

サルでも分かるGit入門チュートリアルでは、Windows, mac(GUI), コンソールから環境を選べます。わたしはコンソールで進めていきます💪
まずは Git のインストールを行います!Homebrewをインストール済みなので、以下のコマンドでインストールしました🙂

$ brew install git

念のため以下のコマンドでバージョンを確認すると、2.20.1でした👀

git -- version

f:id:mistyrinth:20181221204225p:plain

次に Git の初期設定として、ユーザ名とメールアドレスの登録を行います。
リポジトリにコミットする際、履歴などに表示されるそうです😊

$ git config --global user.name "ユーザ名"
$ git config --global user.email "メールアドレス"

合わせてチュートリアルに従い、Gitの出力をカラーリングする設定と、checkoutコマンドに対するcoというエイリアスの作成をしました!

$ git config --global color.ui auto
$ git config --global alias.co checkout

コンソールの場合、コマンドでも設定変更できますが、設定ファイルを直接編集することもできます。
ホームディレクトリにある.gitconfigを開いてみました!
f:id:mistyrinth:20181221210820p:plain
先程の設定が反映されていますね😆

続いて、新規ローカルリポジトリの作成です。
ローカルリポジトリの新規作成は、リポジトリという特別なものを作るのではなくて、mkdirディレクトリを作成して、そのディレクトリをリポジトリに指定するという流れです。
ここでは、ホームディレクトリにtutorialという名前のローカルリポジトリを作ります!

$ mkdir tutorial
$ cd tutorial
$ git init

f:id:mistyrinth:20181221212159p:plain
空のリポジトリができました✨✨

では、リポジトリにファイルを登録します。
まずは、先程作った tutorial ディレクトリの中にsample.txtというテキストファイルを作成します。
ファイルの中身のテキストは、チュートリアルに従いサルでもわかるGitコマンドにします。
わたしは vim で作りました!
f:id:mistyrinth:20181221213721p:plain
入力2のcatコマンドでは、ファイルの中身を確認しているだけです😶
入力3のstatusコマンドでは、Gitの管理下にあるディレクトリの、ワークツリーとインデックスの状態を確認しています💡

$ git status

ここでは tutorial ディレクトリのワークスペースとインデックスの状態を確認しています。
赤文字でsample.txtとなっているのは、インデックスによる履歴の追跡対象になっていないからです🙄
インデックスに登録すると、追跡対象に登録することができるので、インデックスに登録をします!

履歴の追跡対象としたいファイルをインデックスに登録するには、addコマンドを使用します。

$ git add ファイル名

ファイル名はスペース区切りで複数指定することができます🌝
今はsample.txtだけですね。
addコマンドでsample.txtを追加して、先程と同じくstatusコマンドを実行すると、以下のようになります。
f:id:mistyrinth:20181221214704p:plain
インデックスにsample.txtが追加され、リポジトリへのコミットの準備ができました🎉

リポジトリにコミットするにはcommitコマンドを使用します。

$ git commit -m コメント

コメントは"first commit"としておきます✍️
これでコミットができると、先程のstatusコマンドを実施しても変更履歴が無いはずですね〜☀️
また、変更履歴を確認できるlogコマンドも実行してみたので、一連のキャプチャを貼ります!
f:id:mistyrinth:20181221215603p:plain

面白いですね〜!!
複雑になってくるところを早く見てみたいです😆😆

2.用語のおさらい

今日は沢山専門用語が出てきたので、一覧にまとめました!

用語 意味
repository データの状態を保存する場所
作業用のローカルリポジトリと共有用のリモートリポジトリがある
Push ローカルリポジトリからリモートリポジトリにアップロードすること
Pull リモートリポジトリからローカルリポジトリにダウンロードすること
commit ファイルやディレクトリの追加・変更をリポジトリに記録する操作
worktree 実際に作業をするディレクト
index リポジトリとワークツリーの間にあり、リポジトリにコミットするための準備をするところ

今日は以上です😊