はじめに
どのブランチがどのブランチの上に乗っかるか,というルールが複数定義されたファイルを読んでひたすら git rebase を行うためのツール「git-rebase-matsuri」というのを書いてみたので,本エントリで軽く紹介します.
※ とあるコミットポイントにおいてちょっとした主要なコミットが発生したおかげで,そこから派生していたすべてのブランチに対して git rebaase する作業が発生することを,私は勝手に「rebase祭り」などと呼んでおります.
背景
「この機能の実装を進めて」「ちょっとあれを直してほしい」先方からそんな要求がくるたびに,その数だけトピックブランチを,公開状態のコミットポイントから生やして作業しています.で,こちらが作業を完了して報告,公開向けの準備の指示を仰ぐのですが,そこから返信がこなくなります.(まぁお忙しいのでしょうね.)その結果,「公開待ち」な状態のブランチが増えてきます.
コミットツリーは次のような感じになります:
そこで飛び込んでくる「これ,あのお客さんにどうしても対応したいから,すぐに実装して反映してほしい」といった要求.私の少量メモリな脳内ではスワップを起こしていますが,対応しなければなりません.そしてその修正を先に公開します.
(本エントリを書いている最中にも,何か1件飛び込んできましたw)
コミットツリーは次のような感じになります:
さて,本来の開発作業に戻りますか.しかし,安心して開発を再開するには,コミットツリーを次のようにしておきたいところですね:
まぁ git rebase しまくればよいだけですが,いかんせんメンドイ!
使い方
インストール
...というタイトルで,Perl Advent Calendar 2011 の Casual Track に,13日目のエントリを書かせていただきました.
今回の皆既月食,雲だらの名古屋でこのUstを見ていました:
幸い名古屋でも皆既のあたりから雲が切れ始め,お仕事場前の道路から見上げたら,肉眼ではっきりと見ることができました.
そんなわけで,手持ちのカメラで撮ったものをざっとまとめてみました.
他にも重複してるっぽい写真を含め,Flickrに上がってますのでよろしければ:
PHPでシリアライズしたデータをPerlで復元したり,その逆を行うったりするためのモジュール PHP::Serialization を使ってみたメモ.
なお,Perl は 5.12.2,PHP は 5.3.4.
簡単なデータいくつか(Perl側でシリアライズ)
% perl -M5.12.0 -MPHP::Serialization=serialize -le 'say serialize($_) for 1, [1], [1 => 2], +{1 => 2}'
i:1;
a:1:{i:0;i:1;}
a:2:{i:0;i:1;i:1;i:2;}
a:1:{i:1;i:2;}% perl -M5.12.0 -MPHP::Serialization=unserialize -MData::Dump=dump -le 'say dump(unserialize($_)) for qw/ i:1; a:1:{i:0;i:1;} a:2:{i:0;i:1;i:1;i:2;} a:1:{i:1;i:2;} /'
1
[1]
[1, 2]
{ 1 => 2 }簡単なデータいくつか(PHP側でシリアライズ)
% echo '<?php print serialize(array()) ?>' | php
a:0:{}
% echo '<?php print serialize(array( 1, 2 )) ?>' | php
a:2:{i:0;i:1;i:1;i:2;}
% echo '<?php print serialize(array( 1 => 2 )) ?>' | php
a:1:{i:1;i:2;}
% echo '<?php print serialize(array( '1' => 2 )) ?>' | php
a:1:{i:1;i:2;}
% echo '<?php print serialize(array( 'a' => 2 )) ?>' | php
a:1:{s:1:"a";i:2;}% perl -M5.12.0 -MPHP::Serialization=unserialize -MData::Dump=dump -le 'say dump(unserialize($_)) for qw/ a:0:{} a:2:{i:0;i:1;i:1;i:2;} a:1:{i:1;i:2;} a:1:{s:1:"a";i:2;} /'
[]
[1, 2]
{ 1 => 2 }
{ a => 2 }空のリストリファレンス・空のハッシュリファレンス(Perl側でシリアライズ)
空のリストリファレンス,空のハッシュリファレンスを,それぞれ Perl側でシリアライズしてみる:
% perl -M5.12.0 -MPHP::Serialization=serialize -le 'say serialize([]); say serialize(+{})'
a:0:{}
a:0:{}% perl -M5.12.0 -MPHP::Serialization=unserialize -MData::Dump=dump -le 'print dump(unserialize($_)) for qw/ a:0:{} /'
[]ハマる予感しまくりなので,何らかのダミーデータを入れておくのがよさげっぽい.
NULL(PHP側でシリアライズ)
% echo '<?php print serialize(NULL) ?>' | php
N;
% echo '<?php print serialize(array(NULL)) ?>' | php
a:1:{i:0;N;}
% echo '<?php print serialize(array(NULL, NULL)) ?>' | php
a:2:{i:0;N;i:1;N;}
% echo '<?php print serialize(array(NULL => NULL)) ?>' | php
a:1:{s:0:"";N;}% perl -M5.12.0 -MPHP::Serialization=unserialize -MData::Dump=dump -le 'say dump(unserialize($_)) for qw/ N; a:1:{i:0;N;} a:2:{i:0;N;i:1;N;} a:1:{s:0:"";N;} /'
undef
[undef]
[undef, undef]
{ "" => undef }undef(Perl側でシリアライズ)
% perl -M5.12.0 -MPHP::Serialization=serialize -le 'say serialize($_) for undef, [undef], [undef => undef], +{undef => undef}'
N;
a:1:{i:0;N;}
a:2:{i:0;s:5:"undef";i:1;N;}
a:1:{s:5:"undef";N;}% perl -M5.12.0 -MPHP::Serialization=unserialize -MData::Dump=dump -le 'say dump(unserialize($_)) for qw/ N; a:1:{i:0;N;} a:2:{i:0;s:5:"undef";i:1;N;} a:1:{s:5:"undef";N;} /'
undef
[undef]
["undef", undef]
{ undef => undef }Can't locate object が出る件に追記しました.
はじめに
Cache::FileCache が保存するデータの中身を,外部のPerlスクリプトから参照するためのちょっとした実験のメモ.
事前準備
キャッシュを2パタンセットするためのスクリプト set.pl,キャッシュデータが保存されているファイルを見つけてダンプ出力するスクリプト find.pl の2つを順に実行して,それを確認してみます.
コードの内容は後述しますが,次でも参照できます:
構成としては次のような感じ.どこかのディレクトリに2つのスクリプトが置いてあるだけです:
% tree . . ├── find.pl └── set.pl 0 directories, 2 files
set.pl を実行する
set.pl は次のような感じです:
use 5.12.0; use warnings; use FindBin; use Cache::FileCache; my $cache = Cache::FileCache->new({ cache_root => "${FindBin::Bin}/cache", namespace => 'mycache', }); # 600秒後にexpire $cache->set( 'hogehoge', { foo => 1, bar => 2, baz => [ 3, 4, 5 ] }, 600, ); # expireしない $cache->set( 'fugafuga', [qw/ a b c d e /], );
これを実行すると,ファイル構成は次のようになります:
% perl set.pl % tree . . ├── cache │ └── mycache │ └── 3 │ ├── 9 │ │ └── 9 │ │ └── 39975bb0ba31825c4fdd3de775dd468081b3522b │ └── b │ └── 2 │ └── 3b2c6c10d0e78072d14e02cc4c587814d0f10f3a ├── find.pl └── set.pl 7 directories, 4 files
find.pl を実行する
use 5.12.0; use warnings; use FindBin; use File::Find; use Storable qw/thaw/; use Data::Dumper; my $target = "${FindBin::Bin}/cache"; sub _do_something { my ($f) = @_; my ($raw, $data); $raw = do { my $a; local $/; open my $fh, '<', $f or die $!; $a = <$fh>; close $fh; $a; }; $data = thaw($raw); say Dumper $data; } sub _handle_found { my $f = $File::Find::name; return if -d $f; return _do_something($f); } find \&_handle_found, $target;
実行結果は次のようになります:
% perl find.pl
$VAR1 = [
'fugafuga',
bless( {
'_Expires_At' => 'never',
'_Size' => undef,
'_Created_At' => '1323249367',
'_Key' => undef,
'_Data' => [
'a',
'b',
'c',
'd',
'e'
],
'_Accessed_At' => '1323249367'
}, 'Cache::Object' )
];
$VAR1 = [
'hogehoge',
bless( {
'_Expires_At' => '1323249967',
'_Size' => undef,
'_Created_At' => '1323249367',
'_Key' => undef,
'_Data' => {
'bar' => 2,
'baz' => [
3,
4,
5
],
'foo' => 1
},
'_Accessed_At' => '1323249367'
}, 'Cache::Object' )
];復元できているようですね.
簡単なまとめ
Cache::FileCache でファイルとして保存されるデータは,次の要素:
- キャシュのキー
- Cache::Object オブジェクト
が順に入っているリストリファレンスを Storable でシリアライズしたもの,ということがわかった感じです.(Storable::thaw で復元できた,という結果からに拠ります.今のところソースコードを確認していません><)
また,「無期限」なキャッシュオブジェクトには,_Expires_At の値として never が付いているので,判別に利用できますね.
あと,上記のように復元したら,Cache::Object のメソッドが使えないのは私の行いが悪いからでしょうか?
Can't locate object method "get_acceced_at" via package "Cache::Object" at (ry
2011-12-08 11:25 追記
スクリプト中で use Cache::Object すれば使えました><
おわりに
以上,Cache::FileCache が保存するデータの中身を,外部のスクリプトから参照するちょっとした実験のメモ,でした.
おまけ: Storableはどこで使われている?
上記スクリプトでは,当然のように Storable::thaw を使いましたが,Cache::FileCache が Storable を利用しているかどうかは,次のような順でソースコードをさかのぼっていった結果,確認することができました.
最終的に,Cache::CacheUtils の中で,次の記述を見つけました:
19 | use Storable qw( nfreeze thaw dclone ); |
また,さかのぼった順序は,つぎのような感じです.
Cache::FileCache:96 (Cache::Cache 1.06)
96 97 98 99 100 101 102 | sub _Get_Backend { my ( $p_optional_cache_root ) = Static_Params( @_ ); return new Cache::FileBackend( _Build_Cache_Root( $p_optional_cache_root ) ); } |
Cache::FileBackend:646 (Cache::Cache 1.06)
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 | sub _read_data { my ( $self, $p_path ) = @_; Assert_Defined( $p_path ); my $frozen_data_ref = _Read_File_Without_Time_Modification( $p_path ) or return [ undef, undef ]; my $data_ref = eval{ Thaw_Data( $$frozen_data_ref ) }; if ( $@ || ( ref( $data_ref ) ne 'ARRAY' ) ) { unlink _Untaint_Path( $p_path ); return [ undef, undef ]; } else { return $data_ref; } } |
Cache::CacheUtils:114 (Cache::Cache 1.06)
114 115 116 117 118 119 | sub Thaw_Data { my ( $p_frozen_object ) = @_; return defined $p_frozen_object ? thaw( $p_frozen_object ) : undef; } |















