bzrで変更がかかったファイルをディレクトリ構造を保ったまま取り出す方法

本番環境に上書きするだけで必要ファイルがリリースできるような用途を想定して、 変更したファイルのみを取り出す方法の説明。
まず結果から言ってしまうが、以下のようにやれば取り出せる。

bzr missing --this --gnu-changelog -v | grep "^\t\*" | tr "*: " "" > workfile
dirname < workfile | sort | uniq | awk "mkdir -p ./out/$0" | sh
sort < workfile | uniq | awk "cp ./$0 ./out/$0"  | sh

ポイントを説明をすると、
・ bzr missing --this --gnu-changelog -v
bzr missingで親ブランチにマージしていない修正=自ブランチで変更がかかった修正を取り出す。このとき、-vオプションでファイル一覧も出るようにするのだがデフォルト形式だとgrepでファイル一覧だけ抜き出せないので、gnu-changelog形式を指定して変更ファイルがgrepで抜き出せるようにする。
bzr missing の代わりに bzr log --gru-changelog -v -r111..222 を利用してもいける。
・ ... > workfile
ここまでで、変更ファイル一覧を邪魔なもじを取り除いた状態で取得できている。
あとはファイル一覧からディレクトリ作成とファイルコピーの2作業を行うため、一旦workfileに内容を退避させておく。
・ dirname < workfile
dirnameはファイルパスからディレクトリ部分のみを取得するプログラム。
awk "mkdir -p ./out/$0"

  • pオプションは、ディレクトリを目的階層まで一気に掘るオプション。

……こんなとこだろうか。

ちなみに実際はwindows環境だったんで、以下のようなwshスクリプトを組んで

bzr missing --this --gnu-changelog -v | cscript //nologo filter.js | cmd

ってやった。

filter.js ファイル

extendsArray();
var lines = [];

// 標準入力
while(!WScript.StdIn.atEndOfStream) {
	lines.push(WScript.StdIn.ReadLine());
}
WScript.StdIn.Close();

// linesの加工
var cmd_mkdir = lines.grep(/^\t\*/).toWinDir().dirname().sort().uniq().awk("mkdir       .\\_change\\$0").toString();
var cmd_copy  = lines.grep(/^\t\*/).toWinDir()          .sort().uniq().awk("copy  .\\$0 .\\_change\\$0").toString();

// 標準出力
WScript.StdOut.WriteLine(cmd_mkdir);
WScript.StdOut.WriteLine(cmd_copy);
WScript.StdOut.Close();


function extendsArray() {
	Array.prototype.grep = function(regexp) {
		var newArray = [];
		for (var i=0; i<this.length; i++) {
			if (this[i].match(regexp)) {
				newArray.push(this[i]);
			}
		}
		return newArray;
	}
	Array.prototype.uniq = function() {
		var newArray = [];
		var oldValue = "";
		for (var i=0; i<this.length; i++) {
			if (this[i] != oldValue) {
				oldValue = this[i];
				newArray.push(this[i]);
			}
		}
		return newArray;
	}
	Array.prototype.toWinDir = function() {
		for (var i=0; i<this.length; i++) {
			this[i] = this[i].replace(/[\t\*: ]/g, "");
			this[i] = this[i].replace(/\//g, "\\");
		}
		return this;
	}
	Array.prototype.dirname = function() {
		for (var i=0; i<this.length; i++) {
			this[i] = this[i].replace(/[^/\\]+$/, "");
		}
		return this;
	}
	Array.prototype.awk = function(format) {
		for (var i=0; i<this.length; i++) {
			this[i] = format.replace(/\$0/g, this[i]);
		}
		return this;
	}
	Array.prototype.toString = function(format) {
		var str = "";
		for (var i=0; i<this.length; i++) {
			str += this[i] + "\n";
		}
		return str;
	}
}



ちなみに bzr missing --this --gnu-changelog -v の代わりにbzr status -r111..222 を使った方がよいかもしれない。こっちだとどれが変更ファイルでどれが削除ファイルかも判断がつく。
bazzarスレで教えてもらった。

231 :デフォルトの名無しさん:2010/06/24(木) 00:53:53
>>227
もしかしたら

bzr status -r111..222 | なんとかかんとか

http://pc12.2ch.net/test/read.cgi/tech/1265951333/231