VS Codeでソースコード管理:ブランチを操作してみよう:Visual Studio Codeで快適Pythonライフ
VS Codeが提供するGitサポート機能を使って、ブランチを作成したり、ブランチをマージしたり、コンフリクトを解決したりする手順を紹介します。
前回はVisual Studio Code(以下、VS Code)のソース管理機能の初歩の初歩として、リポジトリの初期化からファイルのコミットまでを見ました。今回は、ブランチの作成とマージ、コンフリクトの解決をVS Codeで行う方法を見ていきましょう。
ブランチの作成
「ブランチ」はGitの大きな特徴の一つです。これを使って、日々のコード記述の流れを管理できます。
VS Codeの[ソース管理]ビューの[リポジトリを初期化する]ボタンをクリックすれば、「master」あるいは「main」などのブランチが作成されます*1。このブランチは、プロジェクト全体を通してメインとなるブランチであり、そのプロジェクトの成果物が常に安定して動くように維持していきます。新機能の追加やバグフィックスなどの作業はメインブランチから別のブランチを派生させて、そこで行うことが一般的です。それらの作業で書かれたコードが問題なく動くことが確認できたら、コードをメインブランチ(あるいは開発用のブランチなど)に「マージ」して、そのブランチを削除して、今度はまた別のブランチを作成して……といった具合に開発は進められます。
*1 Gitではリポジトリを初期化した際に作成されるデフォルトのブランチの名前は特に構成を行っていないと「master」となりますが、バージョン2.28からデフォルトブランチの名前を変更できるようになっています。例えば、デフォルトブランチ名を「main」にするには、コマンドラインから「git init --global init.defaultBranch main」コマンドを実行します。
本稿ではVS CodeのUIやターミナルを使って、ブランチを操作してみることにしましょう。以下は新規にフォルダを作成して、[ソース管理]ビューにある[リポジトリを初期化する]ボタンをクリックしたところです(上の脚注で述べたようにしてデフォルトのブランチ名を「main」に変更してあります)。
ここではmainブランチにREADME.mdファイルを作成して(中身は取りあえず空で構いません)、コミットしておきましょう。
次にmainブランチから新たに「utility」という名前のブランチを作成します。このブランチでは、hello関数とgoodbye関数の2つの関数をmyutil.pyファイルに記述する予定です。ブランチを新規に作成するには、コマンドパレットに「git create branch」などと入力して[Git: 分岐の作成](Git: Create Branch)コマンドを実行します。
これにより、コマンドパレットにはブランチ名を入力するボックスが表示されるので、ここでは「utility」と入力しましょう。
これで「utility」というブランチが作成されて、そのブランチに移動(チェックアウト)します(実際には「git checkout -b utility」コマンドに相当する操作が行われています)。ステータスバーの左端に表示されているブランチが「utility」になっていることに注目してください。また、コミットメッセージを入力する欄からもこれがutilityブランチであることも分かります。
これで初めてのブランチが作成できました。次にこのブランチで先ほど述べたように、myutil.pyファイルを作成して、そこに2つの関数を記述してみます。
ブランチのマージ
では、[エクスプローラー]ビューでmyutil.pyファイルを作成して、まずはhello関数を記述しましょう。コード自体に深い意味はもちろんありません。
def hello():
print('hello')
hello関数を記述したら、[ソース管理]ビューで[+]ボタンをクリックして、myutil.pyファイルをステージングして、「def myutil.hello function」などのメッセージと共にコミットします。
本来はここで単体テストなどを実行してコードの振る舞いが正しいかどうかを確認すべきですが、ここでは省略し、コードが正しいものとしてmainブランチにマージをしてみましょう。mainブランチは基本的には常に正しく動作するコードだけを集めたブランチとなります。
utilityブランチのコードをmainブランチにマージするには、まずmainブランチに移動する必要があります。これにはコマンドパレットに「git checkout」などと入力して[Git: チェックアウト先](Git: Checkout to)コマンドを実行します。
すると、以下のような選択肢が表示されます。
このダイアログでは、新規にブランチを作成してそこに移動する[新しい分岐の作成]、指定したブランチから新規にブランチを作成してそこに移動する[新しい分岐の作成元]、既存のブランチにデタッチモードで移動する[チェックアウトがデタッチされました](英語の選択肢は[Checkout detached]です)*2、既存のブランチやタグ(ここでは[main]と[utility]の2つ)が表示されます。この操作に対応するのは「git checkout」コマンドです。
*2 既存のブランチにデタッチモードで移動するというのは、移動先のブランチで何らかの機能やコードを実験的に記述することを目的としたものです(これらは別のブランチに移動した時点で消えてなくなってしまうので、保存が必要であれば、それらのコードを含んだブランチを新規に作成するなどの対処が必要です)。
ここではmainブランチにutilityブランチの内容をマージするので[main]を選択してください。mainブランチに戻って[エクスプローラー]ビューを見ると、myutil.pyファイルがないことに気付くはずです。utilityブランチに移動してから、このファイルを作成して、コードを記述したので、mainブランチにはないのが当たり前です。エディタ領域でもmyutil.pyファイルが「削除済み」となっています。
マージを実行するには、コマンドパレットで「git merge」などと入力して[Git: ブランチをマージ](Git: Merge Branch)コマンドを実行します。
すると、マージ元のブランチ(現在のブランチにマージしたいブランチ)を選択するダイアログが表示されるので、ここでは[utility]を選択してください。
utilityブランチで行われた作業がmainブランチにマージされました。[エクスプローラー]ビューにmyutil.pyファイルが作成され、エディタ領域にあるmyutil.pyファイルのタブでも「削除済み」というコメントがなくなりました。
全てがこのようにうまくいけばよいのですが、そうとも限りません。
コンフリクトの解決
そうとも限らない例として、ここではmainブランチとutilityブランチの両方でmyutil.pyファイルに手を加えてみることにしましょう(これはかなり恣意的なやり方です。mainブランチのコードには直接手を入れないで、開発用のブランチを用意して、そこでコードを記述し、テストを重ねた後でmainブランチにマージするといったやり方をする方が適切でしょう)。まずは、mainブランチでmyutil.pyファイルのコードを以下のようにします。
def hello():
print('hello world')
def goodbye():
print('goodbye world')
修正が済んだら、「modify myutil.py」などのメッセージと共にコミットしましょう。そして、utilityブランチに移動して(コマンドパレットの[Git: チェックアウト先]コマンドを使用)、こちらのmyutil.pyファイルのコードを以下のようにします。
def hello():
print('hello')
def goodbye():
print('goodbye')
mainブランチとutilityブランチで2つの関数の内容が異なっているので、単純にutilityブランチの内容を上書きすればよいというわけにはいかないと予想できますね。
こちらも修正が済んだら、何かのメッセージと共にコミットをしておきましょう。コミットが済んだら、mainブランチに戻って、先ほどと同じ手順でmainブランチにutilityブランチの内容をマージしてみます。すると、以下のように2つのコミットの内容がコンフリクト(衝突)していることが報告されます。
おおざっぱに説明をすると、上側の緑色の部分はmainブランチのmyutil.pyファイルの中でutilityブランチの同ファイルと違っている部分です。上部にある「HEAD」というのは、その部分が現在存在しているブランチ(mainブランチ)のものであることを示していると考えてください。下側の青い部分はその逆です。下部にある「utility」はもちろんその内容がutilityブランチのものであることを意味しています。
さらに一番上には[Accept Current Change][Accept Incoming Change][Accept Both Changes][Compare Changes]というリンクがあります。[Accept Current Change]は現在(のブランチ)の変更を生かすことを、[Accept Incoming Change]はマージ元(この場合はutilityブランチ)の変更を生かすことを指示します。[Accept Both Changes]は両方の変更を取り込むことを指示します。これらをクリックすると、選んだリンクに応じてファイルの内容が修正されます。例えば、[Accept Current Change]を選ぶと次のようになります。
この操作は[Ctrl]+[Z]キーや[Command]+[Z]キーで取り消せるので、これは違うと思ったら、別の選択肢を選び直すことも簡単です。最後の[Compare Changes]を選ぶと、両方のファイルの差分(diff)が別のエディタ(タブ)に表示されます。
このエディタは読み込み専用なので編集はできません。が、この差分を見ながら、コンフリクトをどのように解決するかを検討するのに役立つでしょう。あるいは、上記のリンクを使わずにファイルを直接編集しても構いません。
ここでは[Accept Incoming Change]を選択して、utilityブランチの内容を生かすことにしました(実際には、コードの振る舞い、プログラム全体との整合性などからどのようにコンフリクトを解決するかが決まるでしょう)。
コンフリクトを解決したら、[ソース管理]ビューからmyutil.pyファイルをコミットすれば、マージは完了です(このように両方のファイルの変更を取り込むやり方を「マージコミット」と呼ぶことがあります)。
今回はブランチの作成とマージ、コンフリクトの解決の初歩を見ました。次回はコミットとマージについてもう少し詳しく見てみる予定です。
連載一覧
- 第1回「Visual Studio Codeから「Hello Python」してみよう」
- 第2回「VS Codeでのファイルの作成と編集の第一歩:アクティビティーバーと[エクスプローラー]ビューを使ってみよう」
- 第3回「VS CodeでのPythonコーディングを快適にするエディタ機能の使い方」
- 第4回「コマンドパレットを駆使してVS Codeを使いこなそう!」
- 第5回「ショートカットキーを活用して、VS Codeをより快適に!」
- 第6回「ここから始めるVS Codeのカスタマイズ」
- 第7回「フォントからエディタ、改行文字まで、VS Codeを自分好みにカスタマイズ」
- 第8回「VS Codeの拡張機能でPythonの仮想環境構築からコード整形、Lintまでを体験してみよう」
- 第9回「VS Codeを使ってPythonコードをデバッグするための基礎知識」
- 第10回「VS CodeでPythonコードのデバッグ構成をしてみよう」
- 第11回「VS CodeでJupyterしてみよう」
- 第12回「Jupyter対話環境を使ってVS Codeでノートブックのデバッグ」
- 第13回「ColabCodeを使って、Google Colabの上でVS Codeを使ってみよう」
- 第14回「colab-sshを使って、VS CodeからGoogle Colabに接続してみよう」
- 第15回「VS Codeのタスクを構成してみよう」
- 第16回「VS Codeでソースコード管理、始めの一歩」
- 第17回「VS Codeでソースコード管理:ブランチを操作してみよう」(本稿)
Copyright© Digital Advantage Corp. All Rights Reserved.