WindowsでGitのコンフリクトをTortoise Mergeで解消する

プルリクした瞬間…Not able to merge と出てコンフリクトしまう… それはプログラマにとって悪夢の始まりですよね!!
コンフリクトを解消するのは神経も使うし、間違うと悲しいことになるので、難しい作業です。(>_<)
というわけで、なるべくこの苦痛な「コンフリクトを解消する」作業をうまくやるために、皆さんどうしていますか?

私は、GitのクライアントがSource Tree、コンフリクト解消ツールはTortoise Mergeを使っています。

コマンドラインでどうにかするのもカッコがいいとは思いますが、こういう時は視覚的にわかりやすいのが一番というのが私のポリシーです。(`・ω・´)

まずは、下準備として、TortiseMerge(トートイズマージ:実際にはTortoise SVNをダウンロード・インスコする)をインストールして使えるようにしておきます。
ココからバージョン番号が大きいのを選びましょう。↓
https://osdn.net/projects/tortoisesvn/storage/


で、ここで、

「は? TortiseMergeとか、Tortoise SVNとか旧世代の遺物じゃん!なぜ今更そんなの使うのー??そもそもGitのコンフリクトの話でなんでSVN出てくるんだよ!!」

と皆さん思われたことでしょう…。(>_<)

わかる、わかるよ…。

しかし、 TortiseMerge が意外といいんですよ。

・見やすい
・シンプル
・マージするときに重要な「あっちのも使うしこっちのも使う」「こっちのだけ使う」「あっちのを使う」などがボタン操作で簡単
・SVNと関係なく、 Tortise Merge は使える
・無料

そして、最大の理由が私は高解像度モニターを使っているので、WinMergeだと設定などが消えてしまったり字がちいさすぎて使いづらい(>_<) 
ここは最終的には好みもあるでしょうから、高解像度モニタではない人は、WinMergeでもいいんじゃないでしょうか。

本題に戻りまして、TortiseMergeが使えるようになりましたら、SourceTreeの

「ツール」→「オプション」→「Diff」で「外部マージツール」で「TortoiseMerge」を選択しておきます。(下記図参照)

SourceTreeのマージツール設定画面

選べない場合は、「カスタム」を選択して、「Diffコマンド」のところに TortoiseMerge のexeのパス、引数に

「-base:\”$BASE\” -mine:\”$LOCAL\” -theirs:\”$REMOTE\” -merged:\”$MERGED\”」

と入れておきます。

で、コンフリクトしているファイルのサンプルとして、次のようなファイルがあるとします。

①masterブランチにあるphpinfo.phpというファイル

<?php

//テストなの? 新一ー!!
phpinfo();

//test
?>

②developブランチにあるphpinfo.phpというファイル

<?php

//テストだっちゅーの!!!
phpinfo();

//test
?>

というわけで、3行目のコメントの部分がコンフリクトですね。

まずはWeb上のGithubでdevelopからmasterにプルリクを作ります。

下記のように、コンフリクトして、そのままマージできません、とでますね。

Github プルリクエストした時にコンフリクトが生じる画面


Githubにもコンフリクト解消ツールがありますが、ここはいったんSourceTreeに戻ります。
masterブランチに切り替えて、developをマージします。

ここでも、コンフリクトが発生しています、と表示されます。

SourceTreeでのコンフリクトしているファイルの表示

この、エクスクラメーションがついているファイルを右クリックし

「競合を解決」→「外部のマージツールを起動」

とします。すると、TortiseMergeが起動します。

次のような画面になります。赤い部分がコンフリクトです。


TortiseMergeコンフリクトしているファイル

私がTortiseMergeで気に入っているのは、この下の図で赤丸で表示してある、右上の「Use ‘therirs’ text block」という機能たちなのですが、
・相手の変更を使う
・自分の変更を使う
・相手の変更を使った後に自分の変更を使う
・自分の変更を使った後に自分の変更を使う
などができます。一番下にプレビューが出ます。

Use theirsという機能のボタン

今回は、「Use theirs block then mine(相手の変更を使って、それから自分の変更を使う」を使います。

赤くなっている行を選択し、 「Use theirs block then mine 」のボタンをクリックしてください。

次のようになったら、

TortiseMerge マージした画面

これでコンフリクトを解消したことにするため、「Mark as resolved」ボタンをクリックして「Save」をクリックします。

TortiseMergeを終了して、SourceTreeに戻ります。

すると、下記の図のように、エクスクラメーションマークがなくなっています。(注意:何も変更していなくても、外部のマージツールから戻ると、このようになっているので、コンフリクトが解消されたかどうかをSourceTreeが見ているわけではなく、ただ単に 外部のマージツールから戻ると こうなってます。)

修正内容をもう一度確認し。コミットします。

SourceTreeでのマージされたファイルの表示


Githubでも確認すると、下記の図のように

Githubでマージが成功したことを表示する画面

「Successfully merged…」

となっていて、無事にマージされたことがわかります!!

やったね⊂(^-^)⊃

便利ツール紹介のコーナー #1

便利。

difff《デュフフ》

https://difff.jp/

2つのテキスト間でdiffコマンドによるテキスト差分チェックが簡単に行えるウェブツール。

入力されたテキストのログは取っていないので安心してお使いいただけます

https://twitter.com/meso_cacase/status/190715810971516928

差分箇所がハイライトされて表示される。 (ハイライトの色は青or緑orモノクロ。春には季節限定桜色が選べる)
どうしてもローカルで使いたい場合には、GitHubのリポジトリをクローンして利用できる。

めっちゃ使ってる。イチオシ。


JSON Pretty Linter – JSONの整形と構文チェック

https://lab.syncer.jp/Tool/JSON-Viewer/

オンライン上で、JSONの整形と、構文チェックができるサービスです。処理は全てJavaScript(ローカル環境)で行なっているため、当サーバーにデータを送る必要がありません。

– サイト説明文より

JSONをちゃちゃっと整形して見たいときに便利。


複数の文字コード方式に一括変換 | エンコード / デコード ツール

https://so-zou.jp/web-app/text/encode-decode/

入力した情報はブラウザでのみ処理され、外部へ送信されません。

– サイト説明文より

複数の文字コードに一括で変換してくれるので非常に楽ちん。
使う機会はあんまり。

迷惑メールでたまに見るBase64エンコードはコイツだとダメかもしれない。


SQLフォーマッターFor WEB – ドットツールズ

https://atl2.net/webtool/sql%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%83%E3%82%BF%E3%83%BCfor-web/

SQLの整形を行うWebツール。整形時のパターンを少しだけ指定できる。

サクっと使えていい感じ。


Code Beautify

https://codebeautify.org/

オンラインでフォーマッター、エディター、コンバーターなどの機能を提供するやたらと多機能なサービス群。

UIがシンプルで一見使いやすそうだが、全体が英語だったり多機能すぎて目的の機能を見つけにくかったりするので、実はそんなに使っていない。


今回はここまで。

Ghost Inspector 変数を使う

Ghost Inspectorでテストを行う際、「判定に変数を使いたい……」とか、「画面の表示内容をパターンチェックしたい……」とかってことを思うわけです。

ググっても日本語の解説があんまり出てこなくて仕方ないので、公式のリファレンスを見ることにしました。

今回やりたいことは 、
「画面に表示されている、ある文字列が、現在時刻を示しているか判定する」
です。

めっちゃ簡単。

テスト中にJavaScriptを実行することもできるようです。

やってみる

例えば下記のような、日付時刻が表示される箇所があったとします。

ここで、現在の日付が表示されているかを判定するようなときには、 例えば以下のようにすればよさそうです。

実行すると以下のようになりました。

めっちゃ簡単でしたね。

正規表現パターンチェックとかもできるんだろうか。
「表示内容→変数→JS内で処理」はできそうにないけど、JS内でElementの値参照する感じでやったらちょろっとできそうな気もする。 いけそう。まあ後々。

参考

osmdroid E/OsmDroid: Please configure a relevant user agent; current value is: osmdroid

AndroidでOpen Street Mapを表示させるライブラリ、OsmDroid。

無料で地図を利用できる幸せ…。開発者の皆様には本当にありがとうございます。


osmdroid E/OsmDroid: Please configure a relevant user agent; current value is: osmdroid

というエラーが表示されて、地図が表示されなくなってしまいました。

下記に情報ありますが、

https://github.com/osmdroid/osmdroid/wiki/Important-notes-on-using-osmdroid-in-your-app

地図の画像をOSMのサーバーからダウンロードする際に、HttpのユーザーエージェントにアプリのIDを入れなくてはいけなくなったようです。

方法は簡単でして地図を表示させるActivityのOnCreateに

Configuration.getInstance().setUserAgentValue(BuildConfig.APPLICATION_ID)

と入れるだけです。(Osmdroid5.6以降)

Android Gradleファイルの階層関係とsettings.gradleについて

Androidの開発をしていると、コードを書いているよりビルドに四苦八苦する時間が多い…ぐらいな気もしてしまいます。

Androidが利用しているビルドツールであるGradleのことについては、大体はAndroid Studioさんがやってくれるので、プログラマの日常業務としてはライブラリの読み込みを編集したり、SDKのバージョンを変更したり、Flavorごとの設定を変更したり…ぐらいなことをやっていて、あんまり理解が進んでいなかったなという気がします。

これにはきっかけがあって、Open Street MapのAndroid組み込み用のサンプルプログラムを自分で使ってみて参考にしようと思ったんですが、Gradle Furyというプラグインを使っていて、結局ビルドできなかったんですよね。Gradle Furyは「Gradleに怒っている人が使う」wwwらしく、POMでいろんなことを定義しちゃおうぜーという試みだったらしいです。

ただ、Gradleのことを全部わかろうというのもちょっと時間の無駄な気がしますね。なので、今回は階層関係と、settings.gradleについて書いておきます。詳しくは、下記の公式サイトで見てみてください。

ビルドの設定

https://developer.android.com/studio/build?hl=JA

Android Studioでプロジェクトを作ると、図のように階層やフォルダができていると思います。(私はWindows 10で開発しています。)


Android StudioでSampleAppというアプリを作ったところ

こんな風に表示されてないよー、という場合は、赤丸してあるところがAndroidになっていると思います。クリックして、「Project Files」にすると、ファイルシステムと同じビューで見れます。この方が、今回はわかりやすいので、この「Project Files」ビューで進めます。

さて、今回最初に話題にしたいのは、下記の水色でマルしたsettings.gradleとbuild.gradleです。

settings.gradleから。中身は下記の一文だけ。


include ':app'

appをつかってビルドしましょうね~って意味でして、これがないと何も始まらないw
今回、一個だけのアプリケーションを使ってビルドするので、一文だけですが、ほかのアプリケーションをモジュールとして利用したい場合、ここにincludeするものが増えていきます。

build.gradleは次の通り。

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
google()
jcenter()

}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()

}
}

task clean(type: Delete) {
delete rootProject.buildDir
}

ここでは、全部のアプリケーションに共通のビルドの設定を書いておきます。さっきも書きましたが、今回は一つのアプリケーションだけなので、あまり意味がありませんが、2つ、3つと増えてくると、一つ一つのアプリケーションのGradleファイルにbuildscriptとか書くのは「ええい、面倒!」と思ってくると思いますので、意味があります。

次に、図の紫で囲った、一個下のappフォルダ内のファイルbuild.gradleの説明です。中身は

apply plugin: 'com.android.application'

android {
compileSdkVersion 28
defaultConfig {
applicationId "smart.location.admin.sampleapp"
minSdkVersion 14
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

で、こっちは見慣れた感じだと思います。こっちで利用するライブラリやビルドタイプなどを決めていきます。

今回は本当に触りだけですが、以上です。