検索
連載

VS Codeでソースコード管理:ブランチを操作してみようVisual Studio Codeで快適Pythonライフ

VS Codeが提供するGitサポート機能を使って、ブランチを作成したり、ブランチをマージしたり、コンフリクトを解決したりする手順を紹介します。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
「Visual Studio Codeで快適Pythonライフ」のインデックス

連載目次

 前回は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)コマンドを実行します。

[Git: 分岐の作成]コマンド
[Git: 分岐の作成]コマンド

 これにより、コマンドパレットにはブランチ名を入力するボックスが表示されるので、ここでは「utility」と入力しましょう。

ブランチ名を入力
ブランチ名を入力

 これで「utility」というブランチが作成されて、そのブランチに移動(チェックアウト)します(実際には「git checkout -b utility」コマンドに相当する操作が行われています)。ステータスバーの左端に表示されているブランチが「utility」になっていることに注目してください。また、コミットメッセージを入力する欄からもこれがutilityブランチであることも分かります。

「utility」ブランチに移動
「utility」ブランチに移動

 これで初めてのブランチが作成できました。次にこのブランチで先ほど述べたように、myutil.pyファイルを作成して、そこに2つの関数を記述してみます。

ブランチのマージ

 では、[エクスプローラー]ビューでmyutil.pyファイルを作成して、まずはhello関数を記述しましょう。コード自体に深い意味はもちろんありません。

def hello():
    print('hello')

hello関数とgoodbye関数

 hello関数を記述したら、[ソース管理]ビューで[+]ボタンをクリックして、myutil.pyファイルをステージングして、「def myutil.hello function」などのメッセージと共にコミットします。

hello関数の定義をコミット
hello関数の定義をコミット

 本来はここで単体テストなどを実行してコードの振る舞いが正しいかどうかを確認すべきですが、ここでは省略し、コードが正しいものとしてmainブランチにマージをしてみましょう。mainブランチは基本的には常に正しく動作するコードだけを集めたブランチとなります。

 utilityブランチのコードをmainブランチにマージするには、まずmainブランチに移動する必要があります。これにはコマンドパレットに「git checkout」などと入力して[Git: チェックアウト先](Git: Checkout to)コマンドを実行します。

[Git: チェックアウト先]コマンド
[Git: チェックアウト先]コマンド

 すると、以下のような選択肢が表示されます。

チェックアウト先を指定するダイアログ
チェックアウト先を指定するダイアログ

 このダイアログでは、新規にブランチを作成してそこに移動する[新しい分岐の作成]、指定したブランチから新規にブランチを作成してそこに移動する[新しい分岐の作成元]、既存のブランチにデタッチモードで移動する[チェックアウトがデタッチされました](英語の選択肢は[Checkout detached]です)*2、既存のブランチやタグ(ここでは[main]と[utility]の2つ)が表示されます。この操作に対応するのは「git checkout」コマンドです。

*2 既存のブランチにデタッチモードで移動するというのは、移動先のブランチで何らかの機能やコードを実験的に記述することを目的としたものです(これらは別のブランチに移動した時点で消えてなくなってしまうので、保存が必要であれば、それらのコードを含んだブランチを新規に作成するなどの対処が必要です)。


 ここではmainブランチにutilityブランチの内容をマージするので[main]を選択してください。mainブランチに戻って[エクスプローラー]ビューを見ると、myutil.pyファイルがないことに気付くはずです。utilityブランチに移動してから、このファイルを作成して、コードを記述したので、mainブランチにはないのが当たり前です。エディタ領域でもmyutil.pyファイルが「削除済み」となっています。

mainブランチ
mainブランチ

 マージを実行するには、コマンドパレットで「git merge」などと入力して[Git: ブランチをマージ](Git: Merge Branch)コマンドを実行します。

[Git: ブランチをマージ]コマンド
[Git: ブランチをマージ]コマンド

 すると、マージ元のブランチ(現在のブランチにマージしたいブランチ)を選択するダイアログが表示されるので、ここでは[utility]を選択してください。

マージ元のブランチの指定
マージ元のブランチの指定

 utilityブランチで行われた作業がmainブランチにマージされました。[エクスプローラー]ビューにmyutil.pyファイルが作成され、エディタ領域にあるmyutil.pyファイルのタブでも「削除済み」というコメントがなくなりました。

マージ後のmainブランチ
マージ後のmainブランチ

 全てがこのようにうまくいけばよいのですが、そうとも限りません。

コンフリクトの解決

 そうとも限らない例として、ここではmainブランチとutilityブランチの両方でmyutil.pyファイルに手を加えてみることにしましょう(これはかなり恣意的なやり方です。mainブランチのコードには直接手を入れないで、開発用のブランチを用意して、そこでコードを記述し、テストを重ねた後でmainブランチにマージするといったやり方をする方が適切でしょう)。まずは、mainブランチでmyutil.pyファイルのコードを以下のようにします。

def hello():
    print('hello world')

def goodbye():
    print('goodbye world')

mainブランチのmyutil.pyファイルの内容

 修正が済んだら、「modify myutil.py」などのメッセージと共にコミットしましょう。そして、utilityブランチに移動して(コマンドパレットの[Git: チェックアウト先]コマンドを使用)、こちらのmyutil.pyファイルのコードを以下のようにします。

def hello():
    print('hello')

def goodbye():
    print('goodbye')

utilityブランチのmyutil.pyファイルの内容

 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]を選ぶと次のようになります。

mainブランチの内容を生かす
mainブランチの内容を生かす

 この操作は[Ctrl]+[Z]キーや[Command]+[Z]キーで取り消せるので、これは違うと思ったら、別の選択肢を選び直すことも簡単です。最後の[Compare Changes]を選ぶと、両方のファイルの差分(diff)が別のエディタ(タブ)に表示されます。

差分の表示
差分の表示

 このエディタは読み込み専用なので編集はできません。が、この差分を見ながら、コンフリクトをどのように解決するかを検討するのに役立つでしょう。あるいは、上記のリンクを使わずにファイルを直接編集しても構いません。

 ここでは[Accept Incoming Change]を選択して、utilityブランチの内容を生かすことにしました(実際には、コードの振る舞い、プログラム全体との整合性などからどのようにコンフリクトを解決するかが決まるでしょう)。

[Accept Incoming Change]を選択した結果
[Accept Incoming Change]を選択した結果

 コンフリクトを解決したら、[ソース管理]ビューからmyutil.pyファイルをコミットすれば、マージは完了です(このように両方のファイルの変更を取り込むやり方を「マージコミット」と呼ぶことがあります)。


 今回はブランチの作成とマージ、コンフリクトの解決の初歩を見ました。次回はコミットとマージについてもう少し詳しく見てみる予定です。

連載一覧


「Visual Studio Codeで快適Pythonライフ」のインデックス

Visual Studio Codeで快適Pythonライフ

Copyright© Digital Advantage Corp. All Rights Reserved.

[an error occurred while processing this directive]
ページトップに戻る