カンテラの光の下で

dNaga392's memorandom

【Git】 コマンドを間違えたとき git reflog が便利だった

導入

コミットをしたものの止めたくなったとき、 git reset HEAD^ をすることがあるでしょう。
あの日の私もそんな思いで git reset HEAD^ を叩いていました。

ところが思ったより一回多く git reset HEAD^ を叩いてしまいました。
これでは本来含めたかったコミットを消してしまい、ブランチとも齟齬が発生してしまします。

どうにか元に戻せないかと調べると、ちょうどその方法が見つかりました。
今回の記事はそんなお話です。

要点

気取った導入を書きましたが、要点は次の通りです:

  1. git reflog で戻したい状態を示す SHA(ハッシュ) を確認する。
  2. git reset でその状態に復帰する。

詳しく

やってしまった~ って思ったその時に git reflog を実行します。 すると、次のようにコマンドに対応するログが表示されます(画像はぼかしています):

f:id:dNaga392:20181116132003p:plain

今回は最後のコマンドを打ち消したいので、上から2番目の ff8ab38 までリセットします。

git reset ff8ab38

これで消してしまったコミットが復活しました。 よかったよかった。

参考資料

【Qt】Qt 5.11.2 を MinGW 64 bit 向けにビルドした

Qt は Qt Online Installer により複数の環境に対応したライブラリがインストールできます。しかし、Windows 向け g++ が利用できる MinGW の 64bit 環境に対応するものはなく、該当の環境での開発を望む場合、開発者自身の手でQtのソースからビルドする必要があります(少なくとも本記事の執筆時点には存在しませんでした)。

本記事では、前述のようなケースにある開発者を対象に、 Qt5.11.2 を MinGW 7.3.0 64 bit 対応の開発環境の構築手順を示します。

開発環境構築

構築手順は次のとおりです:

  1. Qt のソースを準備する
  2. ビルドのためのツールをインストールする
  3. Qt をビルドする
  4. Qt 開発環境を整える

1. Qt のソースを準備する

Qt Online Installer を利用して Qt をインストールします。 Qt Online Installer は次のダウンロードページから取得できます:

今回は Open Source 版を選択して、 Online Installer をダウンロードします。

参考:Online Installer のバージョンによる差は小さいと思いますが、本記事では qt-unified-windows-x86-3.0.5-online.exe を使用しています。

Qt Online Installer を実行します。 本記事では、次のようにインストールしました。

  • Open Source 版を利用するため、 Qt Account は Skip しました。
  • インストール先フォルダは、既定の C:\Qt としました。
  • インストール項目の選択は次のとおりです:
    • Qt
      • Qt 5.11.2
        • [x] MinGW 5.3.0 32 bit
        • [x] Sources
      • Tools
        • Qt Creater 4.7.1
        • [x] MinGW 5.3.0 32 bit
        • [x] MinGW 7.3.0 64 bit
  • ライセンス条項は同意しました。
  • スタートメニューは、既定の Qt としました。

参考:本記事では比較のため、 Qt/MinGW 5.3.0 32 bit および Tools/MinGW 5.3.0 32 bit を選択しています。必要がなければ、これらは未選択でも影響はありません。

2. ビルドのためのツールをインストールする

Qt のソースを準備できたら、ビルドのためのツールをインストールします。 ビルドの必要要件は次のとおりです:

ツール バージョン
MinGW gcc 4.9 以降
Perl 5.12 以降
Python 2.7 以降
Ruby 1.9.3 以降

参考:ビルドの必要要件は Qt/5.11.2/Src/README に記載があります。

MinGW は Online Installer によりインストールされているので、 Perl, Python, Ruby のインストール方法を示します。

Perl をインストールする

Perl は次のダウンロードページからインストーラーが取得できます:

取得したインストーラーを実行してインストールします。

参考: ダウンロードページは Qt/5.11.2/Src/README に記載があったものです。 本記事作成時は、ダウンロードページに次の2バージョンありました。

  • 5.24.3.2404
  • 5.26.1.2601

本記事では最新の 5.26.1 をインストールしました。

Python をインストールする

Python は次のダウンロードページから取得できます:

取得したインストーラーを実行してインストールします。

参考: ダウンロードページは Qt/5.11.2/Src/README に記載があったものです。

本記事作成時、ダウンロードページには次の3バージョンありました。

  • 3.5.4.3504
  • 2.7.14.2717
  • 3.6.0.3600

本記事では 2.7.4 をインストールしました。

注意: ビルドでは Python 2.x 系が要求されます。

Ruby をインストールする

Ruby は次のダウンロードページからインストーラーが取得できます:

取得したインストーラーを実行してインストールします。

参考: ダウンロードページは Qt/5.11.2/Src/README に記載があったものです。 本記事では 2.4.4-2(x64) without devkit をインストールしました。

3. Qt をビルドする

いよいよ Qt5.11.2 を MinGW 7.3.0 64 bit 向けにビルドします。

管理者権限でコマンドプロンプトを立ち上げ、Qt 5.11.2 のフォルダに移動します。

>cd C:\Qt\5.11.2

続けて、次の2つのフォルダを作成します:

  • インストール用のフォルダ mingw73_64
  • ビルド用のフォルダ mingw73_64_build
>mkdir mingw73_64
>mkdir mingw73_64_build

作成したビルド用のフォルダ mingw73_64_build に移動して、ビルド用のツールのPATHを通します。

>cd mingw73_64_build
>set PATH=C:\Qt\Tools\mingw730_64\bin;C:\Qt\Tools\QtCreator\bin;%PATH%

上のコマンドは、各ビルド用ツール(PerlPythonRuby)のインストーラーでPATHを通してある状態のものです。 PATHを通さなかった場合は次のコマンドで PATH を通します:

>set PATH=C:\Qt\Tools\mingw730_64\bin;C:\Qt\Tools\QtCreator\bin;C:\Ruby24-x64\bin;C:\Python27\;C:\Python27\Scripts\;C:\Perl64\site\bin;C:\Perl64\bin;%PATH%

echo %PATH% を実行し、PATHが通っていることを確認します。

>echo %PATH%
C:\Qt\Tools\mingw730_64\bin;C:\Qt\Tools\QtCreator\bin;C:\Python27\;C:\Python27\Scripts\;C:\Perl64\site\bin;C:\Perl64\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Ruby24-x64\bin;C:\Users\dev\AppData\Local\Microsoft\WindowsApps

問題がなければ、configure を実行し、ビルド設定をします(時間がかかることがあります)。

>..\Src\configure -developer-build -opensource -confirm-license -opengl desktop -nomake examples -nomake tests -prefix C:\Qt\5.11.2\mingw73_64

コマンドの意味は次のとおりです。

コマンドとオプション 説明 コメント
..\Src\configure Src ディレクトリにある configure 本体。
-developer-build Qtをコンパイルしてリンクする。
-opensource OpenSource版でビルドする。
-confirm-license ライセンス条項に同意する(確認画面を表示しない)。
-opengl desktop デスクトップ OpenGL を使用する。 未指定だと QtGui でエラーが発生し、ビルド全体が失敗するため
-nomake examples 各モジュールの examples を作成しない。 ビルド時間短縮のため
-nomake tests 各モジュールの tests を作成しない。 qtwebglplugin のテストパートでエラーが発生し、ビルド全体が失敗するため
-prefix C:\Qt\5.11.2\mingw73_64 C:\Qt\5.11.2\mingw73_64 をインストール先とする。

その他のオプションは configure -h で確認できます。

mingw32-make を実行し、ビルドします(とても時間がかかることがあります)。

>mingw32-make

mingw32-make install を実行し、インストールします(時間がかかることがあります)。

>mingw32-make install

C:\Qt\5.11.2\mingw73_64 にインストールされていることを確認します。

以上でビルド&インストールが終了です。

4. Qt 開発環境を整える

Qt開発を始めるには、次の2つのPATHを通す必要があります。

  • C:\Qt\5.11.2\mingw73_64\bin
  • C:\Qt\Tools\mingw730_64\bin

インストーラーからインストールした場合はスタートメニューが作成されますが、 ビルド&インストールの場合は作成されません。

そのため、 MinGW 5.3.0 32 bit 版を参考に同様の開発用ショートカットを作成します。

MinGW 5.3.0 32 bit 版ショートカットは、リンク先が次のようになっています:

C:\Windows\System32\cmd.exe /A /Q /K C:\Qt\5.11.2\mingw53_32\bin\qtenv2.bat

qtenv2.bat は 64 bit 版に存在しないため、これを C:\Qt\5.11.2\mingw73_64\bin に作成します。

作成する qtenv2.bat の内容は次のとおりです:

@echo off
echo Setting up environment for Qt usage...
set PATH=C:\Qt\5.11.2\mingw73_64\bin;C:\Qt\Tools\mingw730_64\bin;%PATH%
cd /D C:\Qt\5.11.2\mingw73_64

参考: 本質的な部分は3行目のみです。3行目以外はインストール版と同様の挙動にするためのコマンドです。

スタートメニューに次のリンク先でショートカットを作成します:

C:\Windows\System32\cmd.exe /A /Q /K C:\Qt\5.11.2\mingw73_64\bin\qtenv2.bat

以上で、開発用ショートカットの作成は終了です。

【Hyper-V】VMのディスク領域を増やす

Hyper-VVMのディスク領域を拡張しました。

要点

  1. 「ディスクの編集」で仮想ハードディスクを拡張します。
  2. VMで「ボリュームの拡張」をします。
  3. 回復パーティションがある場合、ツール「AOMEI Partition Assistant」を使います。

内容

VMでライブラリをビルドしていると、ディスク領域不足によるエラー(No space left on device)が発生しました。 確認すると、既定のディスク領域(50GB)を使い切り、空き容量がゼロになっています。

これを解決するため、VMのディスク領域を拡張する方法を調べると、次の記事が見つかりました:

この記事によると、次の2つの手順で実現できるようです:

  1. Hyper-V マネージャーで仮想ハードディスクを拡張
  2. VMで「ボリュームの拡張」

1. Hyper-V マネージャーで仮想ハードディスクを拡張

仮想ハードディスクの拡張では、関連付けられているチェックポイントがあると、 拡張後にはうまく関連付けられないという警告が出ます。

該当のVMは初期に作成したチェックポイントがあったため、 このチェックポイントを適用したのち、全てのチェックポイントを削除して拡張しました。

2. VMで「ボリュームの拡張」

続けて、VMを起動してボリュームの拡張を実行しようとすると、 右クリックメニューから「ボリュームの拡張」が選べませんでした。

これを調べると次の記事に説明がありました:

どうやら拡張するには連続した領域が必要で、今回は「回復パーティション」が未割当て領域との間に挟まっているためできなかったようです。

とはいえ、回復パーティションを削除するのも怖いので、次の記事を参考にしました。

AOMEI Partition Assistant というツールをインストールし、 これを実行することでパーティションの移動および拡張ができました。

余談ですが、とても使いやすかったのでパーティション管理をされる方におすすめです。

【Hyper-V】「一般のアクセスが拒否されました」

概要

Hyper-Vの仮想ハードディスク(Virtual hard disks)を移動して戻したら、「一般のアクセスが拒否されました」と出るようになった。

そもそもなんでそんな事したのかと言うと、チェックポイントがハードディスクを圧迫して削除すらできなっていたためです。 一旦別のストレージに移して、作業領域を空けて、チェックポイントの削除が終わって戻したらこうなった。

この問題は次の記事がとても役に立った。

blog.tpc.jp

対応

原因は、エラーメッセージの通り、実行権限が不足しているためのようだ。

対処法には仮想ハードディスクの再割当てが示されている。 仮想ハードディスクの再割当てをすることで、起動のために必要な権限が割り当てられるらしい。

手順

参考の記事のとおりなのだが、気になったことも含めて自分なりに残す。

  1. Hyper-Vマネージャーの仮想マシン一覧から、(右クリックメニューで)問題を起こしている仮想マシンの設定を開く。
  2. 「ハード ドライブ」設定から現在の仮想ドライブを削除して適用する。
    • 「ハード ドライブ」設定下部の「削除」を押して、「適用」を押す。
      • 注意書きにもある通り、ファイルは削除されないので安心して「削除」して良い。
    • 後ほど再度選択するため、現在の仮想ハードディスク(ファイル)を覚えておく。
  3. ディスクコントローラーにハードドライブを追加しなおす。
    • リストから「ハード ドライブ」を選び、「追加」を押す。
  4. 2 で削除した仮想ハードディスクを再割り当てして適用する。
    • 「参照」を押し、削除した仮想ハードディスクを再度選び、「適用」を押す。

参考資料

バッチファイルを実行ファイルにする

概要

  • DOSのバッチファイル(*.bat)を実行ファイル(*.exe)にする
  • 「Bat To Exe Converter」というツールが便利
  • アイコンも指定できる

背景

普段はPythonを書いているのですが、Windows開発しているとバッチファイルを書くことがあります。

MS-DOSがあれば動くので、Windows環境であれば動作が期待できることがバッチファイルの良い点です。

いつもどおりバッチを作っていると、お客さんから次のような要望をされました。

「それEXEにしてよ」

エンジニアだったらバッチファイルを配布して終了ですが、 バッチファイルに馴染みがない一般ユーザーにはアプリに見えるのが良いとのこと。

そこで、どうやったらできるかなと調べると「Bat To Exe Converter」というものあるらしく、これを使ってみようとなりました。

「Bat To Exe Converter」とは

f:id:dNaga392:20180813012152p:plain

「Bat To Exe Converter」は、テキストエディタのようなGUIに変換設定が表示されているツールです。

左側のペインでバッチファイルを開きつつ、右側のペインでアイコン画像やコンソールを開くかどうかの設定ができます。

イコン画像は *.ico に限るようなので、そこは用意する必要があります。

この設定で実際に作ってみたのが、次のアプリです。

f:id:dNaga392:20180813012747p:plain

○macsですね

更新日時を見て納得してほしいのですが、アプリを実行してテキストを作成することができました。

UIが大変洗練されていて、とても使いやすくおすすめできるツールです。

参考資料

Excelのアドレス文字をPythonで組み立てた

概要

  • xlwings のAPIが遅いので、文字列処理でアドレス文字を求めました

動機

皆さんご存知の通り、Excelにはセルのアドレスを表すA1 とか C3 ってありますよね。

これってVBAだと、RangeオブジェクトのAddressプロパティで取得できて、 xlwingsでもxlwings.Range クラスの get_address メソッドで取得できるんです。

ただ、この処理がちょっと遅い。

一回の処理に0.02~0.04秒程度かかるので、頻繁に呼び出すと急激に処理時間が増えていきます。

そこで、多少のリスクはあってもより短い時間で取得できないかと文字列処理を試みました。

コード

作成したコードは次のとおりです:

列名は、A, B, ..., Z, AA, AB, .... というように記述されるため、26進数でも27進数でもありません(A0などはない)。 そのため、桁上げのとこには少し工夫を入れてあります。

速度的には、上述の処理でほぼゼロ秒まで抑えられました(計測時間では、小数点15桁目まで表示しても0が続くほど)。

感想

コードのコメントにもある通り、xlwings でも得られます。 ではこのコードは同等の処理かというと、サポートしていない機能もあります。

  • 引数チェックがない
    • 不正な値が渡されても処理が進む
  • 最大列数/行数を超えた場合も、アドレス文字列は得られる
    • xlwings だと、上限を超えた場合は例外が送出される

とはいえ、この処理の後にxlwings.Rangeクラスを使うならば、そこでエラーが出るので大きな問題はないかなと思ってます。

スマートではないかなと思いつつも、パフォーマンスが向上できたので個人的には満足です!

参考資料

Pythonのデフォルト引数で注意すること

概要

  • 引数のデフォルト値は 1 度だけしか評価されない
  • つまり、デフォルト引数で指定した値は、関数実行ごとには初期化されない
  • (list や dict のような)変更可能なオブジェクトを指定したい場合は、代わりに None を指定するとよい

現象

関数のデフォルト引数値に、list や dict のように、変更可能(ミュータブル)なオブジェクトを指定したとき、 これは1度しか評価されず、2回目以降はそれを繰り返し使用する。

def f(a, L=[]):
    L.append(a)
    return L

print(f(1))  # => [1]
print(f(2))  # => [1, 2]
print(f(3))  # => [1, 2, 3]

この現象は、 Python ドキュメントに 重要な警告 として記載されている。

これは奇妙な現象にも思えるが、オブジェクトに対して変数を割り当てるという Python の視点から解釈すれば納得することもできるだろう (とはいえ、期待する動作ではないのだが。。。)。

対策

一般的に、このような場合は変更可能(ミュータブル)なオブジェクトの代わりに None を使用する。

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L

print(f(1))  # => [1]
print(f(2))  # => [2]
print(f(3))  # => [3]

参考資料