Minified JavaScript と Source Maps、とか

あっと言う間に 2015年が始まって 1ヶ月半が経過してしまいました。 本業がバタバタしているのもあってこれが今年初のエントリだったりします。

今回は PhpStorm を使った開発関連の小ネタを 2つほど。 PhpStorm といいつつ PHP には関係ない部分なので WebStorm でもオッケーなはずです。

Minified JavaScript とデバッグ

WordPress プラグインの開発に PhpStorm を使っているわけですが、いわゆる .min.js ファイルを作って圧縮しつつ、ソースファイルを使ってデバッグするための方法を探していました。 Source Maps ファイルを使えば良いということはわかっていたのですが、今一つうまく動かないのでちょっと気合を入れて調べてみました。

すると日本語で答えが見つかったので感動しました!

重要なのは Closure Compiler に以下のオプションを与える部分です。

--create_source_map $FileNameWithoutExtension$.min.js.map 
--output_wrapper "%output%//@ sourceMappingURL=$FileNameWithoutExtension$.min.js.map"

こちらの記事でも説明されていますが、圧縮して作った .min.js の最後に Source Maps ファイルの URL を埋め込まなければなりません。 以下のような内容を最後に入れるのです。

//@ sourceMappingURL=standard-widget-extensions.min.js.map

これを行うために –output_wrapper オプションを使って出力の最後にソースマップ用 URL を追加しています。

これで圧縮前の JavaScript ソースを使ってデバッグできるようになりました。 英語も含めて探したのですが、見つかったのは先の日本語記事のみ。 バシャログさん、有益な情報ありがとうございます。

ちなみに YUI Compressor では Source Maps 出力用オプションを見つけることができず、UglifyJS は調べてません。

Git merge と PhpStorm

WordPress プラグインは一人で開発しているので、なるべくマージが発生しないようにしてきましたし、やむを得ない場合はできるだけコンフリクトが生じないようにしてきました。 ところが最近、開発を進めてだいぶコードをいじった後に、リリースしているバージョンの微修正版を出さなければならない状況が生じました。 もう仕方ないのでブランチを切ってみました。 そして、恐る恐る PhpStorm 上で git merge をしてみました。

そしたら、思ったより簡単。 PhpStorm (WebStorm) はマージツールとしてとても扱いやすいです。 下の画面の様にマージ結果を中心に 3つ並べて「×」や「>>」、「< <」を使って操作することができます。 merge (phpstorm)

以下の記事に従えばコマンドライン git のマージツールとして PhpStorm (WebStrom) を登録することもできます。

結び

今年も相変わらずマイペースにブログを続けていこうと思いますので、よろしくお願いします。

git-svn と GitHub を使ったワークフロー

WordPress のプラグイン開発で WordPress.org の Subversion リポジトリと GitHub を使っているのですが、最近ようやく git-svn を使ったワークフローをどうやったら良いかがわかってきたので要点をまとめておきます。

git-svn のワークフローのポイント

基本的なワークフローはここに書いてある通りです。 ポイントは以下の点です。

  • git svn dcommit は master ブランチで行う
  • リリース時に master、remotes/origin/master、remotes/trunk が同じコミットを指すように心がける
  • そのためには、リリース時は git svn dcommit してから git push する
  • Subversion リポジトリへのコミット回数を減らすには git merge –noff を使う。

リンク先記事は英語ですが、コマンドを自分で打ってみれば何をやっているかわかると思います。 –no-ff や –ff オプションについてはこちらの記事がとてもわかりやすいです。 私が WordPress プラグイン開発で使用している具体的なコマンド例についてはこちらの記事をご覧ください。

どこでつまづくのか

git svn dcommit を実行したときに新たなコミットがつくられてしまうので、git のリモートブランチ感覚で remotes/trunk を扱うとまずいのです。 git commit –amend と似た動作と言えばわかるでしょうか。

次の図のようにブランチ master と work が同じコミットを指した状態で master 上で git svn dcommit をすると master と work は分岐した異なるコミットを指すようになります。

git-svn-dcommit
git svn dcommit 時の動作

このような動作なので、Subversion 追跡ブランチを作ってその上で git svn dcommit を行うと master と remotes/trunk が平行する状態になって困ります。 ですので、必ず master ブランチ上で git svn dcommit を行い、その後に git push origin master を行います。 このあたりを意識できないと git-svn をうまく使えません。

既にぐじゃぐじゃなんですけど

では、頑張って直してみましょう。 master ブランチでは Subversion trunk の最新版に更に修正が加わっているものとします。 git svn dcommit 時に reset されてしまうので、差異がないとうまく行かないと思います。

work ブランチを作って master をマージします。 -s オプションでとにかく master を正としてマージします。

$ git checkout -b work trunk
$ git merge -s recursive -Xtheirs --no-ff master

work ブランチ上で作業するのもポイントで、逆に最初 master 上で work ブランチをマージしてしまうと git svn dcommit を実行したときに ‘Transaction is out of date’ と怒られたりします。

必要であれば次のコマンドでメッセージを変更したコミットを作っておきます。 merge の時に –edit オプションを指定しても良いです。

$ git commit --amend

さて、master ブランチを使って git svn dcommit を実行しましょう。

$ git checkout master
$ git merge --ff work
$ git svn dcommit
$ git push origin master

この後 work ブランチは消去してしまっても構いませんし、以下のようにリセットしておいて次のマージ時に使ってもよいでしょう。

$ git checkout work
$ git reset trunk

いかがでしょうか? これでやっと git-svn に悩まされることなく WordPress プラグイン開発に専念できそうです。 この手順は Subversion と Git で平行管理していたソースを統合するときにも使えるように思います。

最後にお約束の宣伝ですが、Standard Widget ExtensionsThin Out Revisions をよろしくお願いします! (まだまだこれからですが、) 着々とユーザーも増えております (SWETOR)。

git diff で無視したい行があるとき

比較時に特定の文字列を含む行を無視したい

最近 Cisco 機器の設定を git で管理しているのですが、diff を取ると設定をいじっていなくても ntp clock-period の行が表示されてしまいます。 この値は機器が動いている間に自動調整されるものなので変わっていても問題ありません。


-ntp clock-period 36027555
+ntp clock-period 36027579

何とか無視できないかと調べたところ git-diff には -G オプションというものがあり、正規表現にマッチしたものだけ表示することができるのがわかりました。 しかし、今回は特定の文字列を含む行を除外したいので文字列の否定ルールを表現しなければなりません。 一般的にこのような場合は「否定の先読み」と呼ばれるパターンを使います。 今回のケースだと以下のようになります。


^(?!ntp clock-period)

しかし残念なことに git-diff は先読み表現に対応していないようで、エラーとなってしまいました。 なので、強引にルールを書いてみます。 以下のようにオプションをつけて git diff を実行すると ntp clock-period の行は消えます。


-G "^([^n]|n[^t]|nt[^p]|ntp[^ ]|ntp [^c])"

ちょっと不格好ですが、これで何とかなります。 ntp 関連で c から始まるコマンドは ntp clock-period のみなので、「ntp c」までを除外すれば十分です。

diff を外部ツールとして登録してみる

ところで通常の diff には -I オプションというのがありこちらはマッチしたものを無視するのですんなり書けます。

-I "^ntp clock-period"

なのでこのオプション付きで diff を外部ツールとして登録し git difftool コマンドから呼び出すという手もあります。


[diff]
        tool = diffcisco
[difftool "diffcisco"]
        cmd = \"diff\" -u -I \"^ntp clock-period\" \"$LOCAL\" \"$REMOTE\"

上のように config ファイルに書いて git difftool を実行するのです。 プロンプトがわずらわしいので -y をつけて抑止すると良いです。


$ git difftool -y

ただし、-I オプションは差分となる固まりの全てが正規表現にマッチしている時に出力が抑止されるという動作なので、前後に変更があれば ntp clock-period の行も出力されることになります。 例えば ntp master コマンドが追加された時は ntp clock-period も出力されることになるでしょう。

git gui で動作させる

Windows 環境で GUI 操作をすることの多い私としては git gui でこれらを実行させたいところです。 git-gui のオプション画面に「Additional Diff Parameters」(config パラメータとしては gui.diffopts) というのがあるので、ここに以下のように入れてみます。


"-G" "^([^n]|n[^t]|nt[^p]|ntp[^ ]|ntp [^c])"

クォーテーションの付け方は試行錯誤の結果なのですが、config ファイルには以下の様に「\"」と記録されます。


[gui]
        diffopts = \"-G\" \"^([^n]|n[^t]|nt[^p]|ntp[^ ]|ntp [^c])\"

すると確かに diff では差分無しと処理されているようですが、「コミット予定に入っていない変更」のリストからファイルを消すことはできず、内容を確認しようとしてファイル名をクリックするたびに変更が無い旨のポップアップが表示される動作となり、残念ながら使い勝手は今一つです。

git diff はそんな状況なので変更有無の確認には git difftool を使うのが良いようです。 「ツール」-「追加」で git difftool -y を呼び出せるようにしておきます。 config には以下のように出力されます。


[guitool "git-diff"]
        cmd = git difftool -y

こうしておくことで git gui 上から git difftool を実行して変更を確認することができるようになります。


2012.10.4
正規表現に誤りがあったため、記事を修正しました。

Windows 環境での git ベストプラクティス

10年以上前は CVS や Visual Source Safe を使っていたのですが、仕事の内容が変わって長いことバージョン管理システムには縁がない状態でした。 しかし、最近また仕事の内容が変わったのを機に (Subversion をスキップして!) git を導入してみました。 仕事環境は Windows がメインなので git も Windows 上に導入しましたが、使ってわかったのは Windows 環境でも全く問題なく使うことができるということです。 Web 検索すると古い情報が多くて Windows で動かすには苦労話が多いように見えますが、現状全く問題ありません。 といってもやはりノウハウが必要な部分もあるわけで、ここまでの自分の経験をまとめてみます。

クライアントは Git for Windows で決まり

ちょっと古い記事だと Cygwin と msysGit のどちらを選択するかという問題を取り上げていると思いますが、現状 msysGit で決まりだと思います。 git を使うだけのために Cygwin を導入するのは大掛かり過ぎます。 まあ、私は必要とすることがあるので Cygwin も導入してはいますが。

ところで現在の msysGit ですが、一般利用者向けパッケージは「Git for Windows」と名付けられており、「msysGit」は開発者向けパッケージの名前となっています。 ですので、git をバージョン管理に使いたいだけならば msysGit ホームページから「Git for Windows」の方をダウンロードしましょう。 現在のバージョンは Git-1.7.11-preview 版です。 古い記事で msysGit と言っているものは大抵の場合 Git for Windows を指しています。 この記事でも以降 Git for Windows という名前を使います。

GUI については TortoiseGit が良いよという記事が多いですが、今のところ私は Git for Windows パッケージに含まれている git-gui と gitk で間に合っています。 確かに一部の操作は GUI から実行できず、コマンドライン上で git を使う場面もありますが、私が日々の作業で使う主要な操作のほとんどは GUI 上で出来るので個人的には許容の範囲です。 会社によってはソフトウェアを入れるために IT 管理部門の説得に苦労するようなこともあると思いますが、そのような場合を考えるといろいろなものをあれこれ導入するより「公式の Windows 版 Git です!」といって Git for Windows だけを入れるのが苦労が少ないと思います。

Windows ファイルサーバーをそのまま利用しよう

同様にサーバーにソフトウェアを入れるのに困難が伴う会社は多いと思いますが、Git for Windows ならば問題ありません。 Windows サーバー上の共有フォルダをそのままベアリポジトリとして使えるからです。 以前書いたように Git for Windows では Windows の \\servername\folder\sub_folder\repository.git を以下の書式で参照できます。

//servername/folder/sub_folder/repository.git

サーバー上にリポジトリを置くとアクセス制御が必要となりますが、私の環境ではリポジトリ単位のアクセス制御で十分なので、共有フォルダのアクセス権設定によるアクセス制御で間に合っています。

エンコードの指定

Git for Windows 付属の GUI ツールを使っている限り、日本語の扱いも問題ないです。 最近は軟弱になって commit や diff などほとんどの操作を GUI でやっているのが幸いして日本語で困ったことはありません。 とりあえず言語関連について git-gui でやったことは「ファイル」-「編集」で 「ファイル内容のデフォールトエンコーディング」(原文ママ) を utf-8 にすることぐらいです。 (ひょっとしたらデフォルトだったかも)

また、EUC や SJIS のファイルも扱うことがあると思いますが、.gitattributes を適切に記述すれば git-gui や gitk 上できちんと日本語表示されます。 詳細は gitk の設定と合わせて記事にまとめていますので参照してみてください。

まあ、コマンドラインツールだとエディタやら less やら bash やらの日本語の扱いの話になってしまうので、どうしてもコマンドラインを使いたければ頑張ってハックしましょう。 私は GUI があるからいいや。

コマンドラインのお世話になるとき

そんな軟弱な私ですが、GUI で操作できない処理もあるのでコマンドラインを使うこともあります。 身近なところでは git fetch はできるのに git pull はできなかったりするのでコマンドラインを使います。 「fetch して修正して push して」という流れであれば git-gui の上で済ませられるのですけどね。

それとファイルの変更を取り消して、前回コミットの状態に戻す操作もそこそこ使います。 GUI だと「コミットから降ろす」+「変更を元に戻す」操作になるので。

$ git checkout HEAD paths

他にもいくつかコマンドライン上で操作するものはありますが、git-gui には外部ツールを登録することができるので頻繁に使うものは登録してしまうというのも手です。 「git pull origin master」とか登録しておいた方が便利です。 この登録機能は次の Excel 差分比較のところでも使います。

Word や Excel の管理

Word にも対応していますが、特に Excel のファイル差分確認には WinMerge がお勧めです。 この WinMerge を差分確認ツールとして使用してみましょう。 なお、ここでは C:\WinMerge の下に WinMergeU.exe が置かれているものとします。 ちなみに WinMergeU.exe は Unicode 版、WinMerge.exe は ANSI 版 (Windows 9x や ME 用) です。

コマンドラインで使用する

外部コマンドを使う場合は git diff コマンドを使用するよりも git difftool コマンドを使って比較するのがお勧めです。 git diff で使うためには簡単なシェルスクリプトを用意しなければなりませんが、git difftool であればコンフィグファイルの設定のみで行けます。 以下のようにコンフィグファイル (例えばリポジトリの .git/config) に書いておきます。

[diff]
        tool = WinMerge
[difftool "WinMerge"]
        cmd = \"/c/WinMerge/WinMergeU.exe\" -u -wl -wr \"$LOCAL\" \"$REMOTE\"

あとは git diff の代わりにコマンドラインで git difftool と打つだけです。 1点注意ですが、複数のファイルの差分を取るように git diff を呼び出したときでも WinMerge は複数起動せずシリアルに 1つずつ差分を確認していくことになります。 これは一時ファイルを作って差分を取っている仕組みのため仕方がありません。 どうしても複数ファイルの差分を平行して確認したい場合は、Git Bash を複数起動して、それぞれの bash から 1つのファイルだけ指定して git difftool を起動すればよいです。

設定についてはこちらの記事を参考にさせていただきました。 そちらにはマージ用ツールとしての設定もありますので参照してみてください。 ちなみに私が設定した WinMerge のオプションは MRU リストへの追加抑止と Read-Only のためのものです。 WinMerge のオプションの詳細については公式マニュアルを参照ください。

git-guiで使用する

git-gui で使用したいときは「ツール」の「追加」で git difftool を登録するだけです。 起動も「ツール」メニューより行います。

git-gui

gitk で使用する

「編集」「設定」で「外部diffツール」に以下のように入力します。 ちなみに「全体に追加」のチェック/アンチェックで global に設定するか local に設定するかを選ぶことができます。

c:/WinMerge/WinMergeU.exe

するとコンテキストメニューから「外部diffツール」を起動できるようになります。 先ほどの git difftool の場合と違って WinMerge へうまく動作制御のためのオプションを渡せなかったのですが、比較する 2つのファイル名は渡っているので実用上は問題ないでしょう。

gitk

以上で、一通りのツールから WinMerge を差分比較ツールとして起動できるようになりました。 これでかなり便利になると思います。

改行コードの処理

改行コード処理については、とりあえずインストール時はデフォルトの「Checkout Windows-style, commit Unix-Style line endings」(core.autocrlf = true) を選んでおけばよいでしょう。 しかし、場合によっては Linux から scp で取ってきたり、ルーターから Expect を使って取ってきたファイルを git リポジトリに突っ込むこともあると思うので、そんなときはリポジトリ単位で core.autocrlf = false に設定して、 CRLF の変換がされないようにした方が管理しやすいかも知れません。

$ git config --local core.autocrlf false

ファイル名の問題

日本語ファイル名も問題なく扱うことができます。 ただし、コマンドラインから git を使う可能性のある人は、ファイル名やフォルダ名に日本語を使う場合でも最初の何文字かは ASCII 文字でユニークに区別できる prefix をつけておいた方が良いでしょう。 そうしておけば日本語が入力できなくても bash の補完機能を使って苦労せず生きて行くことができます。

まとめ

CVS 等を使ってきた身としては、やはり「分散型」バージョン管理システムの概念を理解するのに時間を要しました。 しかし、実際に使ってみると、職業柄、出先での作業が多いので分散であるところに大いに助けられています。

ただ、課題もあって Excel のようにマージが難しいものについてはロック機構があればなあと思ってしまいます。 と言っても、そもそも MS Office 系のファイルについて共同作成をする際は章立てごとに担当を決めてファイルを分割して担当するような流れにしないと回らないような気もするので、試行錯誤しながらワークフローを決めていくことになるのでしょう。

それと「コミットを修正できるってどうよ」という感覚もありますが、その辺は頭を柔らかくして git を使って行きたいと思います。

最後に git について役に立った参考資料を挙げておきます。 この記事では git の基本的なところはすっとばして Windows での利用時に役立つ話ばかりしているので、使ったことがない人には辛い内容になっているかも知れませんが、もし興味があって「Windows 環境で動くなら手が出せるなあ」と思った人がいたらこれらを参考に是非 git を使い始めてみてください。

Pro Git
オンラインならばやはりここだと思います。
WEB+DB PRESS Vol.50
雑誌の特集記事ですが、Git について実践的にわかりやすく書かれていて読みやすいです。 今となっては総集編として購入するのが良いでしょう。
WEB+DB PRESS Vol.69
メインは GitHub の特集ですが、Git for Windows のインストールについても簡単に説明されています。

gitk で文字化けを防ぐ

さて、先日の記事で文字化けして諦め気味だった gitk (git リポジトリのコミット履歴を確認するための GUI ツール) ですが、きちんとエンコーディングを指定できることがわかりました。 同じディレクトリにエンコーディングの異なる euc.txt、sjis.txt、utf8.txt の3つのテキストファイルがある時、そのディレクトリに以下の内容で .gitattributes という名前のファイルを置いておけばオッケーです。ファイル名の頭のドットを忘れずに。

euc.txt         encoding=euc-jp
sjis.txt        encoding=shiftjis
utf8.txt        encoding=utf-8

おっと、gitk の「編集」-「設定」より、「ファイルごとのエンコーディングのサポート」を有効化しておきましょう (下図)。

Windows ファイルサーバーと Git

「Windows 環境に居ると Git を使いたくてもサーバーが無いし…」なんて思ってませんか? Windows の共有フォルダの環境でもちゃんと Git は動きます。 Windows サーバー上に使用可能な共有フォルダーがあればそれで十分使い始めることができます。 サーバー上でサービスやプログラム等を動かす必要はありません。 さっそく始めてみましょう。

Git for Windows を選択しよう

最近の状況だと、Windows で使用する Git と言えば msysGit なのですが、初心者には落とし穴があります。 msysGit の公式ページを見ると、「Git for Windows」と「msysGit」という 2つの配布パッケージがあります。 英語の説明なのでちゃんと見ない人もいるかも知れませんが (?)、一般ユーザー向けは「Git for Windows」と書かれた方なので、「Git for Windows」をダウンロードして使いましょう。 実際のところ、これまでに書かれているほとんどの記事で msysGit と説明されているものは「Git for Windows」のことを指していますが、公式ページ上で「msysGit」と説明されているものは、Git をハックしたい人向けのパッケージなので注意しましょう。

今回は家庭用 NAS を導入して個人で Git を使うために私のやったことをまとめていますが、パーミッション設定をきちんと行えば仕事で使う Windows サーバー上に複数人が使用する Git リポジトリを置くことは可能だと思います。

共有フォルダの参照の仕方

Git for Windows のインストールは簡単です。 デフォルト値の通り、PATH の設定は「Use Git Bash only」、改行コードについては「Checkout Windows-style, commit Unix-style line endings」を選んでおけばよいでしょう。 それと怒られる前にメールアドレスと名前を設定しておきます。

git config --global user.email "youraddress@example.com"
git config --global user.name "Your Name"

ここまで出来てしまえば、後は共有フォルダを以下の形式で参照してベアリポジトリを作るだけです。

//servername/folder/sub_folder/repository

コマンドラインなら以下のようになります。

ローカルのリポジトリを共有フォルダにおく:
$ git clone --bare myproj //server/disk/git/myproj.git

サーバ上に新たにリポジトリを作成:
$ git init --bare //server/disk/git/myproj.git

Git for Windows の GUI

Git for Windows の GUI もそれなりに使えるので、私は結構愛用しています。 リポジトリの複製では、「//server/folder」形式の文字列がローカルと判定されてしまうので、明示的に「全複写」を選んでおくと警告を避けることができます。 (以下、サーバ名は「dragon」です)

ちなみにコマンドラインを使っている分には git clone で特に警告やエラーとならないので、—-no-hardlinks オプションをつけたりする必要はなさそうです。

GUI を使って差分確認すると、改行コードの差は無視 (diff でいう —-strip-trailing-cr オプション) してくれるので手元に CRLF のファイルと LF のみのファイルが入り交じっていても何とかなりますし、エンコーディング指定で SJIS や EUC のファイルも差分確認できるので、特に外部コマンドを設定しなくてもテキストファイルの確認には十分な気がします。

ただし、リポジトリ履歴確認画面 (gitk) では、エンコーディングの指定ができないようです。  gitk でエンコーディングを指定する方法はこちら。

おまけ

本題とはずれますが、関連して実行した作業を簡単にまとめておきます。

CVS からの移行

私は Subversion をスキップして Git 環境に来たので、CVS リポジトリからのインポートが必要でした。 まずは必要なパッケージをインストールします。

# yum install git-cvs

以下のコマンドでカレントディレクトリの下に CVS のモジュール 1つ分の Git リポジトリ (module.git) を作成します。 CVS モジュールごとに実行しなければなりません。

$ git cvsimport -v -d /usr/local/cvsroot -C module.git modulename

まあ、今どきこの情報を必要としている人はいないかも知れませんが。

Windows 共有フォルダを Linux でも参照する

私の環境では I-O DATA の HDL2-A4.0 がファイルサーバーです。 これは Windows と AppleShare にしか対応していないのですが、Linux マシンからもマウントして使いたいので、/etc/fstab に以下のエントリを作成しました。

//dragon/disk    /mnt/dragon    cifs    password=,noauto    0 0

とりあえず今は買って来たままのパスワードなしの状態で使っています。 起動時の自動マウントはしないように noauto を付けていますが、NAS が 24時間稼働であればこれを外しても良いでしょう。 このように fstab に書いておけば mount コマンド実行が楽になります。

# mount /mnt/dragon