Subversion

2012年8月21日 (火)

TortoiseSVNでの変更ファイル等をcopyするwsf

TortoiseSVNでの変更ファイル等をcopyするバッチファイル
使っていましたが、ファイルやフォルダ名にスペース文字があったときなど
対応ができないので、困ることが多くなり、wsfで作り直しました。

以下がそれです。

<copytsvn.wsf>

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
<job id="copytsvn">
<?job error="True" debug="True" ?>
<object id="objFs" progid="Scripting.FileSystemObject" />
<script language="JavaScript">
<![CDATA[

LISTTXT = "list.txt";
SRC_FOLDER = "AAA";
DST_FOLDER = "AAA_bk";

var strCurrentFolder = objFs.GetParentFolderName(WScript.ScriptFullName);
//WScript.Echo ("CurrentFolder : " + strCurrentFolder);

var strSourceFolder = strCurrentFolder + "\\" + SRC_FOLDER;
var strDestinationFolder = strCurrentFolder + "\\" + DST_FOLDER;
var strListText = strCurrentFolder + "\\" + LISTTXT;
var strTemp;

if(!objFs.FolderExists(strCurrentFolder))
{
WScript.Echo ("SourceFolderがありません");
}
else if(!objFs.FileExists(strListText))
{
WScript.Echo (LISTTXT + "がありません");
}
else if(objFs.FolderExists(strDestinationFolder))
{
WScript.Echo ("DestinationFolderが既に存在します");
}
else
{
objFs.CreateFolder(strDestinationFolder);//DestinationFolder作成
var objTs = objFs.OpenTextFile(strListText,1,false);//ReadOnlyでLISTTXTを開く

do{
  strLine = objTs.ReadLine();//1line読み出し
  //WScript.Echo ("> " + strLine);
  splitData = strLine.split("/");//'/'で区切る
  //WScript.Echo ("num: " + splitData.length);
  if(splitData.length == 0)
  {
   //処理しない
  }
  else
  {
   if(splitData.length == 1)//file copyのみ
   {
    //for file copy
    strTemp = splitData[splitData.length-1];//file pathの後半部分
   }
   else
   {
    //mkdir
    //strDestinationFolder;
    for(i=0; i<(splitData.length-1); i++)//最後の文字列はファイルであるとみなす
    {
     //WScript.Echo ("str: " + splitData[i]);
     if(i == 0)
     {
      strTemp = splitData[i];
     }
     else
     {
      strTemp = strTemp + "\\" + splitData[i];
     }
     if(!objFs.FolderExists(strDestinationFolder + "\\" + strTemp))
     {
      objFs.CreateFolder(strDestinationFolder + "\\" + strTemp);//Folder作成
     }
    }
   
    //for file copy
    strTemp = strTemp + "\\" + splitData[splitData.length-1];//file pathの後半部分
   }
   //file copy
   if(!objFs.FileExists(strSourceFolder + "\\" + strTemp))
   {
    WScript.Echo ("ファイル:" + splitData[splitData.length-1] + "がありません");
   }
   else
   {
    objFs.CopyFile(strSourceFolder + "\\" + strTemp, strDestinationFolder + "\\" + strTemp);//from,toの順
   }
  }
}while(!objTs.AtEndOfStream);

objTs.Close();
}

]]>
</script>
</job>
</package>

<このスクリプトの使い方>
copytsvn.batとほとんど変わりません。
作業フォルダで右クリック→tortoiseSVN→「変更をチェック」
として変更ファイル等を表示、copyしたいものをマウスでアクティブにして
右クリックで「クリップボードにパスをコピー」。
これを「パス」などファイル名以外がある行は削ってlist.txtとして保存、
作業フォルダが入っているフォルダに置く。
このスクリプトファイルを、作業フォルダが入っているフォルダに置き、スクリプト中の
SRC_FOLDERに元のフォルダ(上記のままなら"AAA")を、DST_FOLDERに出力フォルダ(上記のままなら"AAA_bk")を記述して保存する。
あとは実行(このスクリプトをクリック)するだけ。
(必要なフォルダを作りながらファイルをコピーします。)

| | コメント (0) | トラックバック (0)

2012年8月15日 (水)

svnのpre-lockスクリプト(windows)

pre-lockスクリプトではまったのでメモ。

ほかのhookではバッチファイルの実行結果が出ないのに、
何故かpre-lockではそのまま出てしまう
。これが災いしてエラーになる。
たとえば以下のように。

@echo off
rem "@echo off"は先頭に必要です。
set PATH=C:\Windows;C:\Windows\system32;

cscript //nologo %~dp0_pre-lock.wsf %1 %2 %3 %4 %5
if ERRORLEVEL 1 goto fail

:success
exit 0

:fail
exit 1

さらに上記では、wsfを呼び出している。そこももし表示するようにしていればエラーになるので注意。以下はその_pre-lock.wsfの内容。

<?xml version="1.0" encoding="Shift_JIS" standalone="yes" ?>
<package>
<job id="SvnPreLock">
<?job error="True" debug="True" ?>
<object id="objFs" progid="Scripting.FileSystemObject" />
<script language="jscript">
<![CDATA[

//WScript.echo("OK!");//pre-lockではechoを出してはいけない
//WScript.Quit(1);//異常終了
WScript.Quit(0);//正常終了

]]>
</script>
</job>
</package>

追記:
上記にエラー処理も入れた場合、エラーのとき「ロックが pre-lock フックによって妨げられました (終了コード: 99)。出力はありません。」と出てしまいます。

何のエラーかわかるようにしたいと思い、無理やりバッチファイルでメッセージを標準エラーに出力。

@echo off
rem "@echo off"は先頭に必要です。
set PATH=C:\Windows;C:\Windows\system32;

cscript //nologo %~dp0_pre-lock.wsf %1 %2 %3 %4 %5
if ERRORLEVEL 2 goto fail
if ERRORLEVEL 1 goto fail1

:success
exit 0

:fail1
@echo on
echo コメントを入力してください。>&2
exit 99

:fail
exit 1

標準エラーに出力してもいいのかよくわかってませんが、とりあえず思惑通りの動き。
「ロックが pre-lock フックによって妨げられました (終了コード: 99)。出力:
コメントを入力してください。」のように表示されます。

| | コメント (0) | トラックバック (0)

2012年8月13日 (月)

Subversionでのリビジョン削除

今までSubversion1.5(TortoiseSVN1.5)を利用していました。
時々コミットをミスったとき、「直接」リポジトリのDBフォルダを
いじっていました。(だって時間がかからないし)

しかし、つい最近、1.7にアップデートし、
それでリポジトリを作成、そのうちコミットをミスってしまいました。

いつもの調子で上記のとおり削除。
すると、いくつかコミットしてチェックアウトする時にエラーが出るようになりました。
もうこの方法は使えないのかも。

TortoiseSVNログを表示、右クリックこのリビジョンにおける変更を取り消すのようにする方が無難でしょう。履歴残るけど。

しかし、もうおかしくなったのでdumpでもどすしか。
やり方を忘れてたので、ついでにここにメモ。

まず、指定リビジョン(今回12)までdump。リポジトリはxxx、aaa.dumpに保存。

svnadmin.exe dump -r 0:12 "c:\repos\xxx" > c:\aaa.dump

次にリポジトリ作成。名前はyyyとする。これは、

svnadmin.exe create "c:\repos\yyy"

のようにコマンドラインで作成すると、リポジトリフォルダにアイコンが出ません。ので、ここはTortoiseSVNで作成(フォルダ構成は作らない)。

最後にload。

svnadmin.exe load "c:\repos\yyy" < c:\aaa.dump

| | コメント (0) | トラックバック (0)

2010年9月 2日 (木)

subversionのコミットログを検索して置換

subversionのコミットログにメーラのメッセージを
ちょっと加工してのせていたのですが、送信日時が
「xx年xx月xx日xx曜日 xx:xx…」となってました。
これの「xx曜日 」が前から気になっていて、
ついに削ることにしました。

それで以前作ったpythonのプログラムをモディファイし、
コミットログを取り出して文字列を見つけたら置換して書き込むのを
繰り返すものを作りました。

以下がそれです。無理やりなところや無意味な宣言もありますが。

# -*- coding: utf-8 -*-

import os
import time
import sys, string
from svn import core, fs, delta, repos
import codecs

#argvs[1]:repository path
argvs = sys.argv  #コマンドライン引数リスト
argc = len(argvs) #引数の個数
if (argc != 2):   #2でなければ出る
    exit(1)

path = argvs[1]
path = core.svn_path_canonicalize(path)
repos_ptr = repos.open(path)
fs_ptr = repos.fs(repos_ptr)

rev = fs.youngest_rev(fs_ptr)
start_rev = 1
end_rev = rev

for current_rev in range(start_rev,end_rev+1):
    #get comment log
    log = fs.revision_prop(fs_ptr, current_rev, core.SVN_PROP_REVISION_LOG) or ''
    if log.count('曜日 '):
        print "rev:%d log change" % current_rev
        log = log.replace('月曜日 ', '')
        log = log.replace('火曜日 ', '')
        log = log.replace('水曜日 ', '')
        log = log.replace('木曜日 ', '')
        log = log.replace('金曜日 ', '')
        log = log.replace('土曜日 ', '')
        log = log.replace('日曜日 ', '')
       
        #set comment log
        fs.change_rev_prop(fs_ptr, current_rev, core.SVN_PROP_REVISION_LOG ,log)

UTF-8で保存して、editlog.pyのように名前をつけたとすると

python editlog.py C:\TracLight\projects\svn\aaa

でaaaというリポジトリのコメント置換を行います。
(C:\TracLight\projects\svn\aaaがリポジトリのパス)

| | コメント (0) | トラックバック (0)

2009年10月22日 (木)

subversionリポジトリを別のPC/サーバに移すときやること

書いてたつもりだったけど、見つからなかったので
書いておきます。

リポジトリのDBフォルダの下に、
transactions、txn-protorevsフォルダがないと
コミットができません。なかったら作ってやればよいです。

コピー/バックアップするときに
空のフォルダということでコピーされないのかも。

| | コメント (0) | トラックバック (0)

2009年10月 6日 (火)

TortoiseSVNでの変更ファイル等をcopyするバッチファイル

subversionでいくつもフォルダがあったり、階層になってたり
するようなものを管理してて、作業フォルダの変更分を
必要なフォルダ付きでどこかにcopyしたいと思ったこと、ないですか?

私はそんな作業が頻繁に発生するので、バッチファイルとかで
できないかと、ついに作ることにしました。
以下がそれです。まあ、これだって少しの手間はあるのですが、
今までに比べればましなレベルです。

<copytsvn.bat>

set LISTTXT=list.txt
set SRC_FOLDER=c:\xx\AAA
set DST_FOLDER=c:\xx\BBB

IF NOT EXIST %SRC_FOLDER%\CON EXIT
IF NOT EXIST %DST_FOLDER%\CON mkdir %DST_FOLDER%

for /f %%i in (%LISTTXT%) do @call :SUB_1 %%i
exit /b

:SUB_1
set FOLDER1=%1
set FOLDER1=%FOLDER1:/= %
set PATH1=\
for %%i in (%FOLDER1%) do @call :SUB_2 %%i
exit /b

:SUB_2
set FOLDER2=%1
IF %PATH1%==\ (set PATH1=%FOLDER2%) else (set PATH1=%PATH1%\%FOLDER2%)
set SRC_FOLDER1=%SRC_FOLDER%\%PATH1%
set DST_FOLDER1=%DST_FOLDER%\%PATH1%
IF NOT EXIST %SRC_FOLDER1%\CON (copy %SRC_FOLDER1% %DST_FOLDER1%) else (IF NOT EXIST %DST_FOLDER1%\CON mkdir %DST_FOLDER1%)
exit /b

<copytsvn.bat使い方>
作業フォルダで右クリック→tortoiseSVN→「変更をチェック」
として変更ファイル等を表示、copyしたいものをマウスでアクティブにして
右クリックで「クリップボードにパスをコピー」とする
これを「パス」の行は削ってlist.txtとして保存、
作業フォルダが入っているフォルダに置く。
後はこのバッチファイルを、作業フォルダが入っているフォルダに置き、
SRC_FOLDERに作業フォルダを、DST_FOLDERに出力フォルダを記述して保存する。
あとは実行するだけ。必要なフォルダを作りながらファイルをコピーします。

| | コメント (1) | トラックバック (0)

2009年1月26日 (月)

trac hotcopyのわな

TracLightning-2.0.9でふとバックアップをやってみました。
そして、バックアップのものもリネームしたら普通に使える
かなと確認していたときに気づきました。
添付ファイルがない、と。
全部ないわけじゃなかったのですが、
日本語のwiki名になってるものはほとんど。

で、google。
「trac hotcopy 添付ファイル」。
akihiroxさんの
Tracのhotcopyが失敗していた話 - 負けないように頑張る日記
がトップにきた。

なるほど、フォルダ名もファイル名も
「UTF-8の%hex形式名で保存」されるのか、
確かにそうなってます。

とりあえずhotcopyの後にattachmentsフォルダだけ
XCOPYでバックアップするようにbackup.batを修正。無理やりです。
※この方法、お勧めできません。下に記述あり。

つまり
TracLightning-2.0.9のbackup.batの場合

bash.exe "%TRAC_LIGHT_HOME%\bin\backup.sh"

の後に

for /d %%i in (%TL_PROJECT_HOME%\trac\*) do (
xcopy "%TL_PROJECT_HOME%\trac\%%~ni\attachments" "%TL_BACKUP_DIR%\trac\%%~ni\attachments" /i /y /e /c /h
)

を追加。

「hotcopy先のパスを短くする」のがいいのかもしれないけど。

そういえばsubversionのhotcopyも0byteのファイルはバックアップされなかったような。
それで使っても特に問題なかったように思いますけど。

---

後日この方法でバックアップをやってみると再びバックアップされないものが。
「メモリが不足」とか出てたような
別のPCでこの方法でいけると試したのが誤りでした。
結局、akihiroxさんのいうように、
「hotcopy先のディレクトリを短く変更」で対応。

| | コメント (0) | トラックバック (0)

2009年1月22日 (木)

UnifiedDiffファイル

最近のTortoiseSVN、というかTortoiseMergeではsubversionリポジトリから
チェックアウトしたものでないファイル2つからでも
UnifiedDiffファイルが作れるようになってます。昨日気づきました。
(TortoiseSVN-1.5.6.14908-win32-svn-1.5.5.msiで確認。)→いつのまにか作成できなくなっていました、注意!

多分インストールのとき「Register diff/patch files」を
有効にしてたらできるようになるんだと思います。

Diffをとりたいファイル2つ、
仮にこれをxxx.aとxxx.a.new(こちらの日時が新しい)として話を進めます。

2つのファイルをアクティブにし、
右クリック→[TortoiseSVN]→[差分]
でTortoiseMergeが起動します。
そこで
TortoiseMergeの[編集]→[UnifiedDiffファイルを作成]
として、保存ファイル名と保存場所を指定するだけ。
日時が古いファイルに対する新しいファイルにするための
パッチが生成されます。
(TortoiseSVN-1.5.6でない、以前のTortoiseSVN-1.5では
ファイル生成されても中身がからになってました。)
拡張子をpatchにしておけば
右クリック→[TortoiseSVN]→[パッチを適用]
で適用フォルダを指定(どうせパッチを作ったときのパスにしか適用されないので
この指定はどこでもよい)、
TortoiseMergeが起動し
ファイルパッチと書かれたwindow(パッチ対象ファイルの一覧?xxx.aしかでないけど)
から選ぶことで
patch適用前と後を並べて見せてくれます。
そこで「保存」ボタンを押すだけ。

別のパスにも適用できたらもっと便利そうだけど、
まあ、今までからしたらより簡単にpatchが作れますね。

パスに日本語が入るとパッチ適用のほうで失敗するので注意。

※でもWinMergeを使ってるならそちらでやるほうがやっぱり楽。

| | コメント (0) | トラックバック (0)

2008年10月30日 (木)

windowsのSubversionでコミット時に名前をつけかえる(その3)

今日、subversionのリポジトリにコミットしようとしたら
またauthorが名前に付け換わらず、IDのままになってました。

よく考えたらちょっと前にsubversion1.4から1.5に
乗り換えたのでした。tortoiseSVNも同様。

どうもネットワークドライブをサーバ名やIPアドレスにしたとき
そうなってる様子。
で、調べたらリポジトリパスとして渡される文字列が

\\srevername\…

となってました。

よって
windowsのSubversionでコミット時に名前をつけかえる(その2)をちょっと修正しました。

| | コメント (0) | トラックバック (0)

2008年9月18日 (木)

windowsのSubversionでコミット時に名前をつけかえる(その2)

ネットワークドライブをドライブ割付しない場合でも
使えるよう修正してみました。
あとは「windowsのSubversionでコミット時に名前をつけかえる」
と変わりないです。

<post-commitフックスクリプト(post-commit.bat)中身>

SET REPOS=%1
SET REV=%2

if "%REPOS:~0,2%"=="/\" goto LABEL1
if "%REPOS:~0,2%"=="\\" goto LABEL1
if "%REPOS:~0,2%"=="//" goto LABEL2
if "%REPOS:~1,2%"==":\" goto LABEL3
if "%REPOS:~1,2%"==":/" goto LABEL3
goto LABEL_END

:LABEL1
rem /\servername/…のような場合を想定
SET REPOS1=%REPOS:\=/%
SET REPOS="file:%REPOS1%"
goto LABEL4

:LABEL2
rem //servername/…のような場合を想定
SET REPOS="file:%REPOS%"
goto LABEL4

:LABEL3
rem c:\aaa\…のような場合を想定
SET REPOS1=%REPOS:\=/%
SET REPOS="file:///%REPOS1%"

:LABEL4
FOR /f %%A IN ('svn propget svn:author --revprop -r %REV% %REPOS%') DO SET USER=%%A
if "%USER%"=="Anohito" (
    svn propset svn:author --revprop -r %REV% Konohito %REPOS%
    exit 0
)
:LABEL_END
exit 0

| | コメント (0) | トラックバック (0)

より以前の記事一覧