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…」

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

やったね⊂(^-^)⊃

NumPy.add.atなどのユニバーサル関数+at

NumPyについて書くシリーズの続きです。

ユニバーサル関数(ufunc)とは、ベクトル化演算です。いくつもの要素がある中で、一つ一つ処理するよりも、一度に処理したほうが早いですよね。そういうことをやってくれる関数です。

たい焼きを焼くときに、一つ一つ焼いていると大変です。しかし、たい焼き屋さんでは、いくつものたい焼きの穴が開いている鉄板で一度にたくさんのたい焼きをバシッ!!と作りますよね。あんこを足すときも、一度にできて早いですよね。あれのイメージです。

で、今回は、特にそのユニバーサル関数を at と組み合わせた時の動作がちょっとわかりづらかったので書いておきます。

下記の公式サイトにある
https://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.at.html
例なのですが

import numpy as np

a = np.array([1, 2, 3, 4])
np.add.at(a, [0, 1], 1)
print(a)
#下記が出力されます。
array([2, 3, 3, 4])

これを例にとって説明するとadd.atの

・1番目の引数は処理する配列

・2番目の引数は処理したいインデックス

・3番目の引数は、addしたい数

です。

私はPHPとかJavaとかが長いので、こういう「1を加算する」的な処理はついついfor文とかでループで書いてしまいがちなのですが、速さが違うので、NumPyのユニバーサル関数を使いこなしていきたいと思います!!

Python assertの使い方

Pythonにassertという宣言があり、こんな使い方ができますという紹介です。

めっちゃ簡単な話ではありますが…。

Pythonのコードを見ていると、ちょいちょいassert出てきて、ほげー と思ってたんですよね。

なんというか、assert はテストコード内で使うというイメージ。

しかし、Pythonでは、致命的なエラーなどを起こした場合、プログラムを止めることができ、しかも、それはデバッグ版だけで起こせるので、開発に便利だよ~ という感じです。

print("before")

a = 1
assert a == 2, "2じゃない"

print("after")

上記を実行すると

before
Traceback (most recent call last):
File "G:/ai_delivery/study12.py", line 4, in
assert a == 2, "2じゃない"
AssertionError: 2じゃない

Process finished with exit code 1


ってなります。

assertのところで終了しているので、print(“after”)は実行されません。

んで、開発の時にデバッグするためのものだよ~ という話なのですが、本番の時にこんなエラー起きたら大変!とか、理由を解明するのも「ええい、面倒!!」ということがあれば、次のようにコマンドラインオプション -Oをつけて実行すればAssertionErrorが出ません。

G:\ai_delivery>python -O study12.py
before
after

これは、大文字のO(オー)です。ゼロじゃないよ。

MySQL CASE文でNULL判定

前回

MySQL SELECT時にCASE文で値をわかりやすく出力するサンプル 

でCASE文の話をしましたが、これでNULL判定するときは気を付けましょう。

サンプルは前回と同じく下記のようなデータですが、4番目の null だけ追加しています。下記のテーブルをcallsとします。

id | driver_id | created
1 | 13 | 2018-11-19 11:23:25
2 | 15 | 2018-11-19 11:25:30
3 | 16 | 2018-11-19 11:26:30
4 | null | 2018-11-19 11:26:30

このテーブルからnullでないドライバーIDの場合は、1、そうでない場合は0を返したい場合、いかにも、下記のように判定できそうですが

SELECT
   id, 
CASE
   driver_id WHEN NULL THEN 0 ELSE 1 
END
FROM
calls

なんとこれではダメです。全部、1が返ってきます。

NULL判定は、CASE文の中でしないといけないそうです。

SELECT 
    id, 
CASE 
    WHEN driver_id IS NULL THEN 0 ELSE 1 
END 
FROM 
calls 

これで、ちゃんと driver_id がNULLの時、0になります。

 

MySQL SELECT時にCASE文で値をわかりやすく出力するサンプル 

MySQLにCASE文やIF文があるのを知っていても、使うシチュエーションがわからない、なんだか使いづらい…と感じている方も多いのではないでしょうか。

ここでは、SELECTするときに、CASEを使う方法を書いておきます。
私、思うにフラグを立てるような処理とかに使うといいと思います。(๑•̀ㅂ•́)و✧

calls というテーブルの中に、下記のようなデータがあったとして

id | driver_id | created
1 | 13 | 2018-11-19 11:23:25
2 | 15 | 2018-11-19 11:25:30
3 | 16 | 2018-11-19 11:26:30

ドライバーIDが “15” の時だけフラグを立てる的にわかりやすく出力したい、という場合があったとするとCASE文を使って次のように書けます。

SELECT
   id, 
CASE
   driver_id WHEN 15 THEN 1 ELSE 0 
END
FROM
calls

 

結果は

id | CASE driver_id WHEN 15 THEN 1 ELSE 0 END 
1 | 0
2 | 1
3 | 0

となります。
フィールドの名前がいやなので、エイリアスつけておきます。

SELECT
   id, 
CASE
   driver_id WHEN 15 THEN 1 ELSE 0 
END
 as driver_himself
FROM
calls

結果は

id | driver_himself
1 | 0
2 | 1
3 | 0

となります。