【Git】もっと便利にバージョン管理【VSCode】

web

こんにちは、なかだ(@newNakata)です。

前回の投稿でバージョン管理(Git、GitHub)の基本的な使い方を紹介しました。
今回は前回あまり触れなかったブランチ(バージョン管理だけなら master ブランチだけでも良いため)と、コマンドで行った作業を VSCode で簡単に行う方法を紹介します。
続きですが2部構成の様になっています。
ブランチの紹介が不要な方は “VSCodeのソース管理について” まで読み飛ばして頂ければと思います。
また Git の操作は多岐にわたるため、本稿で紹介するのは前回のコマンドメインでの操作および通常よく行う操作に絞ってあります。

ブランチについて

本体に影響を与えることなく開発を行うことのできる機能です。

「ん?」って思いますよね。僕もです。
ブランチ(直訳すると枝)は追加(切るとも言う)する事でプロジェクトを枝分かれさせ、同時に別の作業を行う時に使われます。
(プロジェクトとはリポジトリに格納されているソース群を指すと思ってください)

ブランチの説明として以下がよく挙げられます。

  • プロジェクトの本体に影響を与えることなく作業をすることができる
  • ブランチを切ることで目的に合った作業を同時並行で行える
  • 不具合が発生した場合の対応を容易に行える

良く挙げられるだけあって本当にこの通りなのですが、最初は書いてある事は理解できてもイメージがわきませんよね。
結果的 ”とにかく作業前にブランチ切ればいいんでしょ” と思っている方も多いかと思います。
僕も最初はそんな感じでしたし、間違いではありません。
ですが、ここではもう少しイメージして貰えるよう、作業前後の状況とブランチの状態を一緒に解説しようと思います。

前置き

状況は前回の投稿(【Git】すぐ使えるバージョン管理【Github】のファイル管理(レポジトリ作成時))で紹介した作業の直後から始めます。

あくまでも一人での開発を元に解説します。

ブランチ物語

レポジトリ develop-1 にmaster ブランチを作成し、master ブランチには index.php だけがあります。
今はテスト表示でデータベースの中が見えている状態。
index.php は色々な情報を表示したいと思い、何を表示したいか考えました。
そこで日々の日記を残したいと考え、まず最初に日付順に並んだ日記一覧を作成しようと思いました。

11月1日  
状況  ファイル管理環境を構築。
状態  ・master 作成
11月2日
状況 master ブランチをリリース(サイトに公開する)ブランチと決めた。
リリースまでの開発作業は dev ブランチで行おうと考え開発統合ブランチとして dev を作成。
状態 ・master、dev ブランチの状態は同じ
11月3日
状況 index.php に日記のリスト表示(機能1)させるための func1_dev ブランチを dev ブランから作成。
状態 ・master、dev、func1_dev ブランチの状態は同じ
11月7日 
状況 リスト表示機能を func1_dev で作成していたが、リスト作成するのにも時間がかかる。
日々の日記を残すのが目的なのに残す機能が無い。
そのため、先に登録機能を実装すべきだと思い途中まで実装が進んでいる func1_dev ブランチでの作業は一旦中止。
登録ページ(機能2)を作成するため dev ブランチから func2_dev ブランチを作成。
状態 ・mater、dev 、func2_dev ブランチの状態は同じ
・func1_dev ブランチは4日開発を行ったいるので dev(=master) ブランチと違う
11月9日
状況 登録ページが出来たので dev ブランチへマージ(反映)を行う。
状態 ・master ブランチは11月2日の状態
・dev ブランチは func2_dev ブランチを取り込んだため最新の状態
・func1_dev ブランチは master、dev ブランチとも違う状態
11月10日   
状況   dev(開発統合)ブランチの環境でも動作的に問題無く、開発環境内での登録はできるようになった。
ただ、隙間時間を使ってスマホなどから登録したくなりサイトに公開(リリース)する事を決めた。
11月2日に”リリースは master ブランチのプロジェクトだけで行う”と決めているため、公開するために master ブランチへマージ(反映)を行う。
状態 ・master、dev ブランチの状態が同じになった
・func1_dev ブランチは引き続きどのブランチとも違う
11月12日
状況 登録を作ったはいいが日記の内容を変更しようと思った時の機能が無い。
そのため、変更ページ(機能3)を作成するためdevブランチから func3_dev ブランチを作成。
状態 ・master、dev、func3_dev ブランチは状態が同じ
・func1_dev ブランチは引き続きどのブランチとも違う
11月14日
状況 編集機能を作っている最中だが4日前のリリースで index.php がテスト実装のまま表示されている事に気づいた。
func1_dev ブランチで表示調整する必要がある。
ただし4日前のリリースで dev ブランチが更新されているため、最新情報を取得するために dev ブランチを func1_dev ブランチにマージした。
状態 ・master、dev ブランチは状態が同じ
・func1_dev ブランチは dev を取り込んだため11月3~7日まで行った作業分以外は dev ブランチと同じ
・func3_dev ブランチは最初から dev ブランチの最新からブランチを切って作業しているため、dev ブランチを取り込んだ func1_dev ブランチ同様にブランチ内で行っている開発箇所以外は dev ブランチと同じ

解説

プロジェクトの本体に影響を与えることなく作業をすることができる

ファイル管理は”プロジェクトをどの様に管理したいか”が重要になってきます。
複数人での開発の場合、運用は主に管理者が行う事が多いです。
この運用がどの様に管理したいかを意味し、それを決めるのが管理者であり、この度は一人なので自身が管理者です。
今回は master を運用、dev を開発にわけました。
一人で開発するのでリリースタイミングや内容も全て調整できる事を考えるとこの2つをわける必要はないのかもしれません。
ですが、例え一人でも複数でも本体(運用)に影響なく、自由(柔軟)に開発を行うための方法は一緒です。

ブランチを切ることで目的に合った作業を同時並行で行える

ここでは master (リリース)、dev(開発統合)、インデックス(func1_dev)、登録(func2_dev)、編集(func3_dev)ブランチが目的になっています。
dev ブランチは開発統合ブランチなので、各機能は dev ブランチに集約されます。
また各機能は現在開発中以外の箇所を絶えず dev ブランチと同じにする事で現在のブランチを最新にする事ができます。
上記で言うと11月12日に作成した func3_dev ブランチは dev の最新の状態からの作成になりますが、11月14日に func1_dev へ dev をマージする事によって func1_dev(インデックス) と func3_dev(編集) は自身が開発する箇所以外(func2_devの登録部分)が同じ状態になります。
今回は一人で思いついた順に行いましたが、要件定義と設計がある(最初から何をどう作るかがわかっている)状態であれば大きな機能(例えば日記ブランチ)や開発者ごとのブランチを作成してもいいかもしれません。

不具合が発生した場合の対応を容易に行える

サービスに問題や不具合が発生した場合、早期解決のための大事な要素の1つとして問題箇所の断定があります。
ブランチごとに作業履歴を残し、コミット時に的確なコメントを付ける事で発生した問題の切り分けや対応がスムーズになります。
またプロジェクトのまき戻し、問題ブランチの上被せ修正など、状況によって様々な対応が可能になります。

コマンドでブランチ作成

それでは実際に作ってみましょう。
状況は引き続き、前回の投稿(【Git】すぐ使えるバージョン管理【Github】のファイル管理(レポジトリ作成時))で紹介した作業の直後からです。

ブランチを作るまでの確認を含めた入力コマンドと実行結果は次の通りです。

上から順番に作業の詳細と内容は以下の通りです。

git branch -a

上記コマンドはリモートとローカルの両方に存在する全て(-a は ‘all’)のブランチを表示します。
アスタリスク(*)が付いているブランチ名が現在の作業ブランチです。
レポジトリを作った直後なので master ブランチが選択されています。

git branch dev

次に上記コマンドでブランチを作成します。
ブランチを作成したい場合、派生させたいブランチを選択(作業ブランチの状態)した状態でコマンドを入力します。
これで master ブランチから dev ブランチが作成されました。
再度 git branch -a コマンドで確認すると dev が増えているのがわかります。
また下記赤文字の remotes には含まれていないのでローカルのみに存在する事がわかります。

git checkout dev

git checkout はブランチの切り替えやコミットの復元など、作業ディレクトリの状態を変更するために使うコマンドです。
上記は master ブランチから作成した dev ブランチへ切り替え(移動)しました。
再度 git branch -a コマンドで確認すると dev にアスタリスク(*)が付いているのがわかります。

git push origin dev

前の投稿ではブランチを作成後に作業を行ってコミット後にプッシュしましたが、この度はブランチ作成後にすぐプッシュします。
この状態でのプッシュはファイルなどに変更は無く(masterとdevブランチが一緒の状態)リモートレポジトリに dev を反映(作成)するためのプッシュになります。
実際に GitHub の方を見てみましょう。

dev ブランチが作成されています。
次はターミナルの方からも再度確認してみましょう。

今度は赤文字の remotes には含まれているのがわかります。
func1_dev ブランチなどは同じ作業の繰り返しなので割愛します。

以上でブランチ作成の作業は完了です。

コマンドでマージ

それでは実際にマージしてみましょう。
今回は func2_dev ブランチを dev ブランチへマージします。
マージをするまでの入力コマンドと実行結果は次の通りです。

上から順番に作業の詳細と内容は以下の通りです。

git checkout dev

まずマージしたいブランチへ移動します。
と言うと誤解が生じる(た事があった)ので、func2_dev ブランチを dev ブランチに統合したいので統合先である dev ブランチへ移動します。

git merge func2_dev

統合先のブランチ移動したら統合したいブランチ(func2_dev)を指定します。
差分(ファイル名、変更箇所)が表示されマージが完了します。

git pull

リモートレポジトリに変更を反映します。
GitHub で dev ブランチを表示すると func2_dev ブランチで作成したフォルダやファイルが一緒に表示されていると思います。

以上でマージ作業は完了です。

余談ですが、リリースブランチへのマージは一緒にリリースタグを付けるといいと思います。

VSCodeのソース管理について

前回の投稿(【Git】すぐ使えるバージョン管理【Github】のファイル管理(レポジトリ作成時))をそのまま行われた方は気づいているかもしれませんが、ターミナルからコマンドを入力している最中、VSCodeのメニュー横のアイコンに数字が付いたり、ファイル表示の文字色が変わったり、編集した箇所の行番号に色付きの線が表示されたりしていませんでしたか?

VSCode は標準で Git のソース管理マネージャー(Git SCM)拡張機能が組み込まれています。
この拡張機能は VSCode がインストールされた時から有効になっているので始めから画面左アイコンに表示されています。
SCM は Source Control Manager の略でソース管理を指します。
VSCode は .git ディレクトリを検出するとそのフォルダを自動的に Git 管理対象フォルダと認識します。
Git 管理対象と認識したフォルダに含まれるファイルの状態を VSCode の UI (見た目)に反映します。
ですので、ターミナルからコマンドを入力しても、VSCode のソース管理機能で操作しても、どちらも VSCode の UI の反映される仕組みです。

ちなみに VSCode 自体や 拡張機能(Git SCM )に Git ソフトの機能があるわけではありません。

VSCodeからソース管理

この度は前回の投稿(【Git】すぐ使えるバージョン管理【Github】のファイル管理(レポジトリ作成時))で行ったコマンドメインでの作業を VSCode のソース管理機能を使って行っていきます。

始めに

この度は GitHub にアカウントを作った直後の状態からの作業を想定して解説します。
ですのでリモートレポジトリ(develop-1)の作成は行っていない状態からの開始になります。
前回の投稿で言う1番を行わない状態です。

次に、コマンドで作業をする際に行った GitHub との連携が済んでいる状態での解説になります。
連携されていない状態で操作を紹介したく、色々調べて設定を削除したり、1度主要ソフトを全てアンインストールしたりしましたが、何をやっても連携済の GitHub のアカウントが表示されるため断念しました。

ローカルリポジトリを作成する(init)

VSCode 画面左アイコンメニューのソース管理(丸と線が枝の様な)アイコンを押下します。
現在開いているフォルダに .git が無い(=管理対象外)場合、サイドバーは上の画像の様に表示されます。
リポジトリを初期化する ボタンを押下します。

.git フォルダが作成されサイドバーの表示が変わりました。
.git フォルダがあるフォルダを選択した状態でソース管理アイコンを押下すると上の画像の様に表示されます。
ターミナルから確認してみます。

.git ディレクトリが作成されているのがわかります。

余談ですが、サイドバーでは .git フォルダは表示されません。
隠しディレクトリと言うのもありますが、基本的にこの .git ディレクトリを直接編集など触る事がないため非表示の設定になっているためです。
特別な理由が無い限り、サイドバーでの表示は不要だと思いますので、この度はターミナルからの確認になります。

変更(追加、更新)ファイルをインデックスに追加(add)する

サイドバーの変更カテゴリーに表示されているファイルは何かしらの状態にあります。
ファイル名の右端に U と表示されているため未追跡(Untracked)状態です。
ファイル名にマウスカーソルを持って行くとアイコンが表示されます。
+(変更をステージング)アイコンを押下します。

インデックスにステージ(追加)されました。
ファイル名の右端が U(未追跡)から A(追加) に変わっている事からも確認できます。

また、ステージされた状態でファイル名までマウスカーソルを持って行くとマイナス(ー)アイコンが表示されます。
このマイナスアイコンをクリックするとインデックスに追加を取り消す事ができます。

インデックスにあるファイルをリポジトリに追加(commit)

サイドバーの状態はインデックスに追加した時と変わりません。
その上部にコミットボタンと一緒にメッセージを入力する箇所があります。
プレースホルダーに ”main” にコミットとあります。
コマンドの時は初期ブランチ名が master でしたが、VScode から行う場合は main のようです。
僕はメッセージを入力した後にそのままキーボードから操作したいので Ctrl + Enter でコミットさせます。

コミットが完了するとサイドバーが上の画像のようになりました。

ローカルレポジトリの内容をリモートレポジトリに反映(push)

この作業で

・リモートレポジトリ作成
・リモートレポジトリとローカルレポジトリの紐づけ(最初の1回)
・ローカルレポジトリのブランチ(main)をリモートレポジトリに登録
・プッシュ

が行われます。
また、特記事項でも記載しましたが GitHub とは連携後です。
コマンドの時とは大きく違いますので注意してください。

Branch の発行ボタンを押下します。

画面上部中央に現在のフォルダ名が入力され、連携済の GitHub が選択された状態で表示されています。
この入力項目はレポジトリ名になりますので develop-1 と入力し、下部のリスト(画像では同じ名前なので1つ)から選択し押下します。
以上で操作は完了ですので、GitHub の方を確認してみましょう。

develop-1 レポジトリが作成され、main ブランチで登録されています。

ここまでの作業が前回の投稿(コマンド)で行った作業になります。
以降は本稿でコマンドで行った作業を VSCode で行います。

ブランチ作成

VSCode ウィンドウの左下に現在作業中のブランチ名が表示されています。
更にブランチ名の横のリサイクルの様な円(ステータスインジケータ?)があります
ブランチ名とその円とは押下した時の挙動が違いますが、ここでは一旦置いておきます。

マウスカーソルを持って行くとホバーヒントが表示されます。
main 表記部分を押下します。

ウィンド上部中央にリストが表示されます。
+ 新しいブランチの作成… を押下します。

リストの表示が切り替わるので、プレースホルダーが表示されている入力項目に作成したいブランチ名を入力(今回は dev)してエンターを押下します。

先ほど main と書かれていた箇所が dev に変わっているので作業ブランチが作成したブランチへ変わりました。
つまり、dev ブランチを作成し、checkout コマンドを実行して dev ブランチへ移動した状態です。
次に、先ほどはリサイクルの様な円が表示されていた箇所が雲のアイコンに変わっています。
これはリモートレポジトリとの同期の状態を示していて、ローカルの変更がリモートレポジトリに反映(プッシュ)されていない事を意味しています。
雲のアイコンを押下(プッシュ)します。

ブランチ名の横のアイコンがリサイクルの様な円に戻りました。
dev ブランチがリモートレポジトリに反映されたので、GitHub の方を確認してみてください。

ブランチの切り替え

ブランチの切り替えはウィンドウ左下のブランチ名をクリックします。

ウィンドウ上部中央にリストが表示されます。
切り替えたいブランチ名をリストから選択します。
ウィンドウ左下のブランチ名が変わり、選択するだけでブランチを切り替える事ができます。

プッシュとプル

func1_dev ブランチで index.php を変更しました。
ソース管理の変更リストに変更ファイルが上がっています。

コミットまで完了すると画像のような状態になります。
変更の同期ボタンを押下するとプッシュされます。
ウィンドウ下部のリサイクルの様な円もプッシュなのですが、ここはプッシュだけではありません。
今回はリサイクルの様な円を押下します。

このリサイクルの様な円を初めて押下した場合は画像の様に表示されます。
そうです、このリサイクルの様な円はプルしてからプッシュしてくれます。
複数人で作業を行う場合、いつリモートレポジトリが更新されるかわかりません。
最新を取り込む事でファイルの衝突(コンフリクト)を回避できるのでプッシュのみを行うよりミスを防げて便利です。
リサイクルの様な円プルしてからプッシュの動作がわかったので OK, Don’t Show Again(次から表示しない) ボタンを押下します。
プル(今回はリモートブランチに変更が無いので動作無し)された後にプッシュされ、表示が変更前に戻ります。

余談ですが、僕は作業前に必ずこのボタンを押下して最新を取り込みます。
プッシュは頻繁に行うのですが、プッシュ作業を行う前も押下し、最新を取り込んでからコミットした後、このボタンを押下しています。

マージ

それではマージしてみましょう。
今回は dev ブランチを main ブランチへマージします。

dev ブランチを main ブランチに統合したいので統合先である main ブランチへ移動します。

サイドバーソース管理項目の一番右にある ・・・ > ブランチ > ブランチをマージ を選択します。

ウィンドウ上部中央にリストが表示されます。
プレースホルダーにマージ元のブランチを選択と表示されていて「ん?マージ元?」と思うかもしれませんが、あくまでもマージしたいブランチの選択ですので dev を選択します。

マージをリモートレポジトリに反映させます。
GitHub で main ブランチを表示すると dev ブランチに反映されていた内容が一緒に表示されていると思います。

これでマージ作業は完了です。

余談ですが、リリースブランチへのマージは一緒にリリースタグを付けるといいと思います。

ファイルの差分と履歴について

ソース管理を行うとファイルの更新履歴を簡単に確認する事ができます。
エクスプローラー表示のサイドバー下部にタイムライン項目があります。
ファイルを選択した状態でタイムラインを表示します。

画像のようにファイルの更新履歴がコミット時のコメントで表示されています。
このコミット時のコメントを選択すると選択したコミット時の状態と、1つ前のコミットの状態の差分が確認できます。

右ペーンに差分が表示されました。
左側が選択したコミット時の1つ前、右が選択したコミット時のファイルの状態になっています。
便利!

余談ですが、ソース管理下にない(.gitフォルダが無い)場合は以下の様な表示になります。

ブランチの履歴確認について(必須)

Git はブランチに対するコミット履歴やマージ遷移などを確認する事ができます。
ただ、履歴が複雑になれば確認が困難になり、コマンドでの履歴表示だけでは限界があります。
VSCode には Git Graph と言う Git リポジトリの履歴やブランチの遷移を可視化し、操作や差分の確認を容易にするための拡張機能があります。

Git Graph インストール

ウィンドウ左の拡張機能アイコンを選択します。
サイドバー上部に拡張機能検索入力項目があるので git graph と入力します。
上記画像に表示されているアイコンの Git Graph 右にあるインストールボタンを押下します。

インストールはすぐ完了し、画像のように表示されます。

履歴確認

ウィンドウ左のソース管理アイコンを押下しソース管理サイドバーを表示します。
ソース管理項目の右側にあるアイコンに上記画像のグラフの様なアイコンが追加されています。
Git Graph 拡張機能をインストールした事によって表示されているアイコンですので、押下します。
右側のエディタペーンに新しい Git Graph タブと共に、レポジトリのブランチ履歴が表示されました。

最新のコメントや、マージ、作業日付が一目でわかります。
また各項目を押下すると、作業ファイル一覧が表示され、そのファイルを押下するとタイムライン項目で見たファイルの差分を確認する事ができます。

まとめ

本稿はここまでになります。

こうして見ると VSCode での操作が簡単に見えますね。
でもコマンドとGUI、一長一短だと思いますのでどちらも知っていた方が柔軟に対応できます。
ですので前回の投稿と本稿である程度の環境で、通常の開発の基本的なバージョン管理は行えるのではないかと思います。
ただ、バージョン管理は色々な場面があります。
ブランチを巻き戻したり、コミットを取り消したり、上被せでマージされてたり・・・。
これを1度に全て紹介するのは難しいの今後都度投稿していきたいと思います。

さて、本稿まである程度の環境(LAMP(P)+ソース管理)は整ったと思います。
次は何を紹介しようかなと思いつつ、本稿を終わりたいと思います。