Android Studio最速入門~効率的にコーディングするための使い方

第26回 バージョン管理 ─Git連携の使い方[後編]

この記事を読むのに必要な時間:およそ 6 分

はじめに

後編の今回は,ブランチやマージ,リベースといったGitコマンドをAndroid Studioで実行するにはどうするか?といった内容で進めていきます。GitHubやリモートリポジトリの話はあまり登場しません。

ファイルの移動やリネーム

この章は機能の紹介ではなく,調査結果の報告です。Git連携中のファイル操作のうち移動とリネームがどのように行われるのか確認してみました。⁠Projectツールウィンドウ」から2つのファイルbar.txtfoo.txtをそれぞれ以下のように操作してみました。

  • bar.txtを別のディレクトリに移動
  • foo.txthoge.txtにリネーム("Rename..."リファクタリングを実行)

「Versionツールウィンドウ」に記録された,それぞれの実行結果はリスト1のとおりです。

リスト1 ファイルと移動とリネームの実行ログ

20:20:09.103: cd /Users/masanobuimai/AndroidStudioProjects/MyApplicationProject
20:20:09.104: git rm --ignore-unmatch -- bar.txt
rm 'bar.txt'

20:20:09.228: cd /Users/masanobuimai/AndroidStudioProjects/MyApplicationProject
20:20:09.229: git add --ignore-errors -- MyApplication/bar.txt
20:20:19.973: cd /Users/masanobuimai/AndroidStudioProjects/MyApplicationProject
20:20:19.974: git add --ignore-errors -- hoge.txt
20:20:20.064: cd /Users/masanobuimai/AndroidStudioProjects/MyApplicationProject
20:20:20.064: git rm --ignore-unmatch -- foo.txt

ログを見る限りではどちらもgit rmgit addの組み合わせで移動とリネームを実行していました。git mvを使ってないのに大丈夫だろうか?」と思いましたが,コミット後の「Changesツールウィンドウ / Logタブ」にてコミットログを確認すると,それぞれ「移動した(moved)⁠「リネームした(renamed)⁠と記録されています。

図1 ファイルの移動とリネーム結果

図1 ファイルの移動とリネーム結果

念のためSourceTreeで同じリポジトリのログを確認したところ,こちらでも「移動」「リネーム」と認識されていました。さらにだめ押しで「Terminalツールウィンドウ」からgit mvで,それぞれをファイルを移動/リネームして元に戻してみました。

図2 "git mv"でのファイルの移動とリネーム結果

図2 

結論としては,以下のとおりです。

Android Studioでは,移動・リネームには git mv を使わず,git rmgit add を使う

ブランチ&マージ

Gitに限らず分散バージョン管理システムの真骨頂であるブランチ&マージについてです。筆者の私感ですが,Android Studioのブランチ&マージサポートは「まあまあイケてる」と思います。

ブランチの作成

辿り着く先のメニューは同じなのですが,辿り着く方法はいくつかあります。

  • "VCS Operations Popup..."から"Branches..."を実行する。
  • メニューバーの「VCS → Git → Branches...」を実行する。
  • ステータスバーのブランチ名をクリックする。

いずれも同じく図3「Git Branches」ポップアップが表示されます。

図3 ⁠Git Branches」ポップアップ

図3 「Git Branches」ポップアップ

ここで「New Branch」を選択すると「今のブランチ」から枝分かれしたブランチを作成します。それ以外に「Local Branches」「Remote Branches」の特定のブランチを選択してサブメニューの「Checkout as new branch」を実行すると「そのブランチ」から枝分かれしたブランチを作成を作成します。

特定のブランチの「最新の状態」ではなく「特定のリビジョン」からブランチを作成したい場合は「Changesツールウィンドウ / Logタブ」のコミットログからブランチを作りたいログを選び,コンテキストメニューから「New Branch」を実行します。

図4 ⁠Changesツールウィンドウ / Logタブ」のコンテキストメニューからブランチを作成する

図4 「Changesツールウィンドウ / Logタブ」のコンテキストメニューからブランチを作成する

ブランチの切り替え

先ほどの「Git Branches」ポップアップの「Local Branches」から任意のブランチを選択し,そのサブメニューから「Checkout」を実行します。当たり前ですが,すでに複数のローカルブランチが存在している状態でないと使えません。

これも一種の切り替えなのですが「特定のリビジョン」に切り替えたい場合は「Changesツールウィンドウ / Logタブ」のコミットログから特定の行を選び,コンテキストメニューの「Checkout Revision」を実行します。

このチェックアウトが完了すると,ステータスバーのブランチ名にはそのリビジョンのコミットハッシュ値が表示されます。

図5 特定のリビジョンに切り替えた場合の例

図5 特定のリビジョンに切り替えた場合の例

似たような方法で「Git Branches」ポップアップの「Checkout Tag or Revision」から切り替える方法があります。

図6 ⁠Checkout Tag or Revision」からのブランチ切り替え(クリックすると動きがわかります)

「⁠Checkout Tag or Revision」からのブランチ切り替え` &title=`図6 ⁠Checkout Tag or Revision」からのブランチ切り替え` &width=`400` />

この「Checkout」ダイアログに任意のブランチ名やタグ名,コミットハッシュ値を入れて,切り替える事ができるのですが,コード補完が効かないなど正直やっつけ感がにじみ出てます(筆者は,まず使いませんね。今回の記事を書くために初めて使ったくらいです)⁠

そういえば,どうゆうわけかブランチの切り替え(Checkout)は,"VCS Operations Popup..."やメニューバーの「VCS → Git」にはありません。ちょっと不思議ですね。

マージ

ブランチときたらマージです。マージも"VCS Operations Popup..."やメニューバーの「VCS → Git」から行う"Merge Changes..."と,おなじみの「Git Branches」ポップアップから行う方法の2通りありますが,ブランチの時と異なり辿り着く先が異なります

まずは"Merge Changes..."の場合,コマンドを実行すると図7のようなダイアログが表示されます。

図7 ⁠Merge Branches」ダイアログ

図7 「Merge Branches」ダイアログ

ここでマージしたいブランチやそれに関連するオプションを指定して実行します。

もう一方の「Git Branches」ポップアップの場合,⁠マージしたいブランチ」を選び,サブメニューから「Merge」を実行します。

図8 ⁠Git Branches」ポップアップからマージを実行する

図8 「Merge Branches」ダイアログ

こちらの場合,コマンド実行後に確認用のダイアログは表示されず即座にマージが実行されます。その際どのようなオプションが設定されたか「Version Controlツールウィンドウ / Consoleタブ」で確認してみましたが,直球勝負でgit merge <branch名>としているだけでした。

どちらの方法も現在のブランチ(ステータスバーに表示しているブランチ名)に対して,指定したブランチの内容をマージします。つまり常に次の関係になります。

「指定したブランチ」 ⁠現在のブランチ」⁠ マージする

せっかくのGitなのでばんばんブランチを作ってマージしましょう!とは言っても慣れないうちはマージは怖いものです。すでにお気づきかと思いますが「Git Branches」ポップアップのサブメニューに「Compare」というのがあります。これを利用することで現在のブランチと指定したブランチを比較する事ができます。

図9 ⁠Git Branches」ポップアップからブランチ同士を比較する(クリックすると動きがわかります)

「⁠Git Branches」ポップアップからブランチ同士を比較する` &title=`図9 ⁠Git Branches」ポップアップからブランチ同士を比較する` &width=`335` />

コンフリクトした場合

では何かしらの問題でマージでコンフリクトを起こしてみましょう。図10のようにわざとファイルの更新を衝突させてマージでコンフリクトを起こします。

図10 マージ前のコミットログ

図10 マージ前のコミットログ

コンフリクトを検知すると図11のようなダイアログが表示され,コンフリクト解決方法を促してきます。

図11 ⁠Files Merged with Conflicts」ダイアログ(クリックすると動きがわかります)

「⁠Files Merged with Conflicts」ダイアログ` &title=`図11 ⁠Files Merged with Conflicts」ダイアログ` &width=`400` />

右側にあるボタンがコンフリクトの解決方法です。コンフリクトが起きたファイル一覧のうち,選択中のファイルに対してそれぞれ解決方法を指示していきます。

表1 ⁠Files Merged with Conflicts」ダイアログのボタンの意味

ボタン名意味
Accept Yours自分のファイルを採用する。
Accept Theris相手(マージ側)のファイルを採用する。
Merge手動でマージを行う。

「Files Merged with Conflicts」ダイアログで「Merge」を選択すると,さらに図12のようなダイアログが表示され,手動でマージを行いコンフリクトを解決します。

図12 ⁠Merged Revisions for」ダイアログ(クリックすると動きがわかります)

「⁠Merged Revisions for」ダイアログ` &title=`図12 ⁠Merged Revisions for」ダイアログ` &width=`400` />

「Merged Revisions for」ダイアログで「×」⁠≫」⁠≪」アイコンによる変更の取り込みを行い,すべての取り込みが完了すると図13のようなダイアログが表示され,処理を完了するかどうかを聞いてきます。

図13 ⁠All Changes Processed」ダイアログ

図13 「All Changes Processed」ダイアログ

ここで「Save and Finish」ボタンを押すと,コンフリクトは解決したとみなし自動的にコミットを行います。まだ修正したい箇所が残っている場合は「Continue」ボタンを押してコンフリクト解決を継続してください。

すべてのコンフリクトを解決すると自動的にコミットが行われます。

間違って,もしくは意図的にコンフリクトの解決前に「Files Merged with Conflicts」ダイアログを閉じた場合どうなるでしょう?コンフリクトが発生したステータスは残っているので,Android Studioがそれを自動検知してポップアップメッセージを表示します。

図14 コンフリクトの自動検知

図14 コンフリクトの自動検知

または,メニューバーの「VCS → Git → Resolved Conflicts...」から再び「Files Merged with Conflicts」ダイアログを表示できます。コンフリクトの解決を中断しているとステータスバーに「Merging(マージ中)⁠と表示されます。この状態はコンフリクトを解決してコミットするまで続きます。

余談ですが,コンフリクトの解決を一度中断して,あらためてそれを解決し,コミットしたときだけ任意のコミットログでマージすることができます。それ以外ではコミットは自動で行われるため,コミットログは一律で「Merge branch '<ブランチ名>'」となります(意図的というより,マージ処理の抜け道でたまたまそうできただけだと思います)⁠

著者プロフィール

今井勝信(いまいまさのぶ)

システムエンジニア。日本ユニシス株式会社所属。仙台在住。

Android開発はまったくやったことがないけれどIntelliJ IDEAが大好き。

Twitter: @masanobuimai

コメント

コメントの記入