刚来公司时候看到前人写的python脚本用来生成比较报告, 心中技痒. 正好服务器端没有BC, 脚本用不了. 于是东施效颦, 也写了一个. 用的都是原生的svn命令, 自然效果是比不上用BC生成的报告(BC显示的是行内差异, svn只能比较行间差异), 而且由于服务器端转码问题, 中文注释乱码问题一直解决不掉.
所以这脚本其实是个半成品(回撤和统计能使用, 比较报告效果太美不敢看), 考虑到在写这脚本时我也学会了好几个函数(比如match()), 所以还是留做纪念.
邮箱发送邮件自动会在行尾添加空格, 如要使用脚本需拷贝出来在vim中搜索/\v.*\zs\s\ze$再替换:%s///g
1 #!/bin/bash 2 #created by h03566 2017.04.28 3 #diff func added by h03566 2017.06.03 4 5 WORK_COPY= 6 SVN_PATH= 7 8 BUGID= 9 AUTHOR= 10 BEGIN_REV= 11 END_REV= 12 13 NEED_LOCAL_DIR= 14 15 SVN_ROOT=http://10.220.3.241/UWARE_CODE/ 16 SVN_TRUNK=trunk/ 17 TOP_DIR=UWARE 18 19 SEARCH_BUGID= 20 SEARCH_AUTHOR= 21 22 get_svn_path() 23 { 24 TMP= 25 LIST= 26 IDX= 27 TEST= 28 DIR= 29 30 echo "please input svn fullpath or input directory as given. blank for default path: "$SVN_ROOT$SVN_TRUNK 31 while true 32 do 33 echo "current path: "$SVN_ROOT$DIR" sub directory list: " 34 LIST=$(svn list $SVN_ROOT$DIR) 35 IDX=0 36 for TMP in $LIST 37 do 38 let IDX=$IDX+1 39 echo $IDX". "$TMP 40 done 41 read SEL 42 if [ "$SEL" == "" -a "$DIR" == "" ]; then 43 DIR=$SVN_TRUNK 44 break 45 else 46 expr $SEL + 0 &>/dev/null 47 if [ $? -eq 0 ]; then 48 DIR=$DIR$(echo $LIST | awk -F\ -v idx=$SEL ‘{print $(idx)}‘) 49 else 50 svn info $SVN_ROOT$DIR$SEL > /dev/null 51 if [ $? -eq 0 ]; then 52 DIR=$DIR$SEL"/" 53 else 54 echo "wrong svn path. please check u input" 55 fi 56 fi 57 if [ ! -z $(echo $DIR | grep $TOP_DIR) ]; then 58 break 59 fi 60 fi 61 done 62 SVN_PATH=$SVN_ROOT$DIR 63 echo "======== svn path is " $SVN_PATH 64 } 65 66 get_work_copy() 67 { 68 echo "please input working copy directory. blank for no local directory" 69 echo "recommand use top level path i.e. xxx/UWARE/" 70 read WORK_COPY 71 if [ -z $WORK_COPY ]; then 72 if [ $NEED_LOCAL_DIR -eq 1 ]; then 73 echo "get param [working copy directory] fail!" 74 exit 1 75 else 76 echo "no [working copy directory] input. try get svn path instead" 77 get_svn_path; 78 return 79 fi 80 fi 81 #fixme: confused why need change "~" to $HOME otherwise excute svn up in shellscript will fail(while success in command mode) 82 HOME_PREFIX=$(echo $WORK_COPY | awk -F\~ ‘{if ($1~/*/){print $0}else{print $2}}‘) 83 if [ ! -z $HOME_PREFIX ]; then 84 WORK_COPY=$HOME$HOME_PREFIX 85 fi 86 SVN_PATH=$(svn info $WORK_COPY | awk -F\ ‘{if($1=="URL:"){print $2}}‘) 87 if [ -z $SVN_PATH ]; then 88 echo "get wrong svn path. please check working copy dir" 89 exit 1 90 fi 91 echo "======== working copy is " $WORK_COPY 92 echo "======== svn path is " $SVN_PATH 93 } 94 95 get_param() 96 { 97 STOP_FLAG= 98 99 get_work_copy; 100 101 echo "please input search range or keyword: begin & end revision or bug id / author" 102 echo "if u want every commit between begin & end revision just input revision number otherwise input bug id or author" 103 echo "please input begin revision and end revision. leave blank will automatic search latest 2000 revision" 104 read BEGIN_REV 105 if [ -z $BEGIN_REV ]; then 106 echo "no begin revision given" 107 else 108 echo "svn revision begin with "$BEGIN_REV 109 fi 110 read END_REV 111 if [ -z $END_REV ]; then 112 echo "no end revision given" 113 else 114 echo "svn revision end with "$END_REV 115 fi 116 if [ "$BEGIN_REV" != "" -a "$END_REV" != "" ]; then 117 #as we all stop on copy this flag is unused for now 118 STOP_FLAG=--stop-on-copy 119 elif [ "$BEGIN_REV" != "" -o "$END_REV" != "" ]; then 120 expr $BEGIN_REV + $END_REV &>/dev/null 121 if [ $? -ne 0 ]; then 122 echo "wrong revision input. begin "$BEGIN_REV"end "$END_REV 123 exit 1 124 fi 125 fi 126 127 echo "please input bug trece id i.e. IVSD00000" 128 read BUGID 129 if [ -z $BUGID ]; then 130 echo "caution no trace id limited" 131 else 132 echo "bug trace id is" $BUGID 133 fi 134 135 echo "please input author id i.e. h03566" 136 read AUTHOR 137 if [ -z $AUTHOR ]; then 138 echo "caution no author limited" 139 else 140 echo "author id is" $AUTHOR 141 fi 142 143 if [ "$BEGIN_REV" == "" -o "$END_REV" == "" ]; then 144 if [ "$BUGID" == "" -a "$AUTHOR" == "" ]; then 145 echo "required at least one param: [BUGID] or [AUTHOR] to search log!" 146 exit 1 147 fi 148 149 #only input BUGID or AUTHOR need add search option 150 SEARCH_PREFIX=--search 151 if [ ! -z $BUGID ]; then 152 SEARCH_BUGID=$SEARCH_PREFIX" "$BUGID 153 SEARCH_PREFIX=$SEARCH_PREFIX"-and" 154 fi 155 if [ ! -z $AUTHOR ]; then 156 SEARCH_AUTHOR=$SEARCH_PREFIX" "$AUTHOR 157 fi 158 159 #ugly: takes long time to search without limit log count 160 echo "no search range given.auto search least 2000 history" 161 END_REV=$(svn info $SVN_PATH | awk -F\ ‘{if ($1~/^Revision:$/){print $2}}‘) 162 BEGIN_REV=$END_REV 163 CONFIRM=n 164 while true 165 do 166 if [ "$CONFIRM" == "y" -o "$CONFIRM" == "Y" ]; then 167 break 168 else 169 BEGIN_REV=$(expr $BEGIN_REV - 2000) 170 CI_TIME=$(svn log -r $BEGIN_REV:$END_REV $SVN_PATH $SEARCH_BUGID $SEARCH_AUTHOR --stop-on-copy | awk -F\ ‘BEGIN{i=0}{if ($1~/r[0-9]+/){i++;}}END{print i}‘) 171 echo "get" $CI_TIME "commit times from" $BEGIN_REV "to" $END_REV 172 echo "print y to confirm or n to continue search" 173 fi 174 read CONFIRM 175 done 176 fi 177 178 echo "======== search history "$BEGIN_REV" to "$END_REV 179 echo "======== bug id is "$BUGID 180 echo "======== author is "$AUTHOR 181 } 182 183 revert() 184 { 185 TMP= 186 REV= 187 188 echo "begin to revert. update work dir first" 189 #clean working copy 190 svn up $WORK_COPY 191 #svn revert $WORK_COPY -R 192 193 if [ "$BUGID" != "" -o "$AUTHOR" != "" ]; then 194 REV=$(svn log -r $BEGIN_REV:$END_REV $SVN_PATH $SEARCH_BUGID $SEARCH_AUTHOR --stop-on-copy | awk -F\ ‘{if ($1~/r[0-9]+/){print $1;}}‘ | sed -n ‘s/r//p‘) 195 if [ "$REV" == "" ]; then 196 echo "can‘t get bug change history changed by "$AUTHOR" named by "$BUGID" svn path "$SVN_PATH 197 exit 1 198 fi 199 200 for TMP in $REV; do 201 echo "merge from rev "$TMP 202 svn log -r $TMP -v $SVN_PATH 203 svn merge -r $TMP:$(expr $TMP - 1) $SVN_PATH $WORK_COPY 204 done 205 else 206 svn merge -r $END_REV:$BEGIN_REV $SVN_PATH $WORK_COPY 207 fi 208 209 echo "svn revert completed" 210 svn st -q $WORK_COPY 211 } 212 213 count() 214 { 215 TMP= 216 REV= 217 CI_CNT=0 218 ADD_LINE= 219 DEL_LINE= 220 IDX=0 221 222 if [ -e ./svn.tmp ]; then 223 rm ./svn.tmp 224 fi 225 226 if [ "$BUGID" != "" -o "$AUTHOR" != "" ]; then 227 REV=$(svn log -r $BEGIN_REV:$END_REV $SVN_PATH $SEARCH_BUGID $SEARCH_AUTHOR --stop-on-copy | awk -F\ ‘{if ($1~/r[0-9]+/){print $1;}}‘ | sed -n ‘s/r//p‘) 228 if [ "$REV" == "" ]; then 229 echo "can‘t get bug change history changed by "$AUTHOR" named by "$BUGID" svn path "$SVN_PATH 230 exit 1 231 fi 232 233 for TMP in $REV; do 234 echo "counting change from rev " $TMP 235 CI_CNT=$[CI_CNT + 1] 236 svn diff $SVN_PATH -r $(expr $TMP - 1):$TMP -x --ignore-eol-style -x -w | awk -F "\n" -v file="./svn.tmp" ‘BEGIN{OFS="\n";al=0;dl=0;getline al < file;getline dl < file;}{if($1~/^+($|[^+]+.*)/){al++;}if($1~/^-($|[^-]+.*)/){dl++;}}END{print al, dl > file}‘ 237 done 238 else 239 CI_CNT=$(svn log -r $BEGIN_REV:$END_REV $SVN_PATH | awk -F\ ‘BEGIN{ci=0;}{if($1~/^r[0-9]+/){ci++;}}END{print ci}‘) 240 svn diff $SVN_PATH -r $BEGIN_REV:$END_REV -x --ignore-eol-style -x -w | awk -F "\n" -v file="./svn.tmp" ‘BEGIN{OFS="\n";al=0;dl=0;getline al < file;getline dl < file;}{if($1~/^+($|[^+]+.*)/){al++;}if($1~/^-($|[^-]+.*)/){dl++;}}END{print al, dl > file}‘ 241 fi 242 243 while read TMP 244 do 245 if [ $IDX -eq 0 ]; then 246 ADD_LINE=$TMP 247 IDX=1 248 else 249 DEL_LINE=$TMP 250 fi 251 done < ./svn.tmp 252 rm ./svn.tmp 253 254 echo "========================================" 255 echo "svn commit log for BUGID " $BUGID "AUTHOR " $AUTHOR 256 echo "commit count: " $CI_CNT 257 echo "add line: " $ADD_LINE 258 echo "del line: " $DEL_LINE 259 echo "========================================" 260 } 261 262 report() 263 { 264 TMP= 265 REV= 266 267 if [ -e ./output.tmp ]; then 268 rm ./output.tmp 269 fi 270 271 if [ -e ./svn.tmp ]; then 272 rm ./svn.tmp 273 fi 274 275 if [ -z $BUGID ]; then 276 echo "no BUGID given. exit!" 277 exit 1 278 fi 279 280 #svn log print revision from latest to oldest so swap BEGIN_REV & END_REV to ensure commit order 281 REV=$(svn log -r $END_REV:$BEGIN_REV $SVN_PATH $SEARCH_BUGID $SEARCH_AUTHOR --stop-on-copy | awk -F\ ‘{if ($1~/r[0-9]+/){print $1;}}‘ | sed -n ‘s/r//p‘) 282 if [ "$REV" == "" ]; then 283 echo "can‘t get bug change history changed by "$AUTHOR" named by "$BUGID" svn path "$SVN_PATH 284 exit 1 285 fi 286 287 for TMP in $REV; do 288 echo "counting change from rev " $TMP 289 svn diff $SVN_PATH -r $(expr $TMP - 1):$TMP -x --ignore-eol-style -x -w > ./svn.tmp 290 done 291 292 #convert GB2312 to UTF8 293 iconv -f GBK -t UTF-8 ./svn.tmp -o ./svn.tmp.conv 294 #added by h03566 2017.8.29 for get rid of "\r" 295 dos2unix svn.tmp.conv 296 297 OUTPUT=$BUGID"_Report.html" 298 299 #change utf-8 nobom to utf-8 to avoid unicode problem and clean(if exist) or create(if not) file 300 echo -e -n "\xef\xbb\xbf" > $OUTPUT 301 302 echo "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">" >> $OUTPUT 303 echo "<html>" >> $OUTPUT 304 echo "<head>" >> $OUTPUT 305 echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">" >> $OUTPUT 306 echo "<style>" >> $OUTPUT 307 echo ".AlignLeft { text-align: left; }" >> $OUTPUT 308 echo ".AlignCenter { text-align: center; }" >> $OUTPUT 309 echo ".AlignRight { text-align: right; }" >> $OUTPUT 310 echo ".Wrap { white-space: nowrap; }" >> $OUTPUT 311 echo "body { font-family: sans-serif; font-size: 11pt; }" >> $OUTPUT 312 echo "td { vertical-align: top; padding-left: 4px; padding-right: 4px; }" >> $OUTPUT 313 314 echo "tr.SectionGap td { font-size: 4px; border-left: none; border-top: none; border-bottom: 1px solid Black; border-right: 1px solid Black; }" >> $OUTPUT 315 echo "tr.SectionAll td { border-left: none; border-top: none; border-bottom: 1px solid Black; border-right: 1px solid Black; }" >> $OUTPUT 316 echo "tr.SectionBegin td { border-left: none; border-top: none; border-right: 1px solid Black; }" >> $OUTPUT 317 echo "tr.SectionEnd td { border-left: none; border-top: none; border-bottom: 1px solid Black; border-right: 1px solid Black; }" >> $OUTPUT 318 echo "tr.SectionMiddle td { border-left: none; border-top: none; border-right: 1px solid Black; }" >> $OUTPUT 319 echo "tr.SubsectionAll td { border-left: none; border-top: none; border-bottom: 1px solid Gray; border-right: 1px solid Black; }" >> $OUTPUT 320 echo "tr.SubsectionEnd td { border-left: none; border-top: none; border-bottom: 1px solid Gray; border-right: 1px solid Black; }" >> $OUTPUT 321 echo "table.fc { border-top: 1px solid Black; border-left: 1px solid Black; width: 100%; font-family: monospace; font-size: 10pt; }" >> $OUTPUT 322 echo "td.TextItemInsigAdd { color: #000000; background-color: #EFEFFF; }" >> $OUTPUT 323 echo "td.TextItemInsigDel { color: #000000; background-color: #EFEFFF; text-decoration: line-through; }" >> $OUTPUT 324 echo "td.TextItemInsigDiffMod { color: #000000; background-color: #EFEFFF; }" >> $OUTPUT 325 echo "td.TextItemInsigLeftMod { color: #000000; background-color: #EFEFFF; }" >> $OUTPUT 326 echo "td.TextItemInsigRightMod { color: #000000; background-color: #EFEFFF; }" >> $OUTPUT 327 echo "td.TextItemNum { color: #827357; background-color: #F2F2F2; }" >> $OUTPUT 328 echo "td.TextItemSame { color: #000000; background-color: #FFFFFF; }" >> $OUTPUT 329 echo "td.TextItemSigAdd { color: #000000; background-color: #FFE3E3; }" >> $OUTPUT 330 echo "td.TextItemSigDel { color: #000000; background-color: #FFE3E3; text-decoration: line-through; }" >> $OUTPUT 331 echo "td.TextItemSigDiffMod { color: #000000; background-color: #FFE3E3; }" >> $OUTPUT 332 echo "td.TextItemSigLeftMod { color: #000000; background-color: #FFE3E3; }" >> $OUTPUT 333 echo "td.TextItemSigRightMod { color: #000000; background-color: #FFE3E3; }" >> $OUTPUT 334 echo ".TextSegInsigDiff { color: #0000FF; }" >> $OUTPUT 335 echo ".TextSegReplacedDiff { color: #0000FF; font-style: italic; }" >> $OUTPUT 336 echo ".TextSegSigDiff { color: #FF0000; }" >> $OUTPUT 337 echo ".TextSegElement_229_133_179_233_148_174_229_173_151 { font-weight: bold; }" >> $OUTPUT 338 echo ".TextSegElement_230_160_135_232_175_134_231_172_166 { }" >> $OUTPUT 339 echo ".TextSegElement_230_149_176_229_173_151 { color: #2E9269; }" >> $OUTPUT 340 echo ".TextSegElement_230_179_168_233_135_138 { color: #786A41; }" >> $OUTPUT 341 echo ".TextSegElement_232_191_144_231_174_151_231_172_166 { }" >> $OUTPUT 342 echo "</style>" >> $OUTPUT 343 echo "<title>文本比较</title>" >> $OUTPUT 344 echo "</head>" >> $OUTPUT 345 echo "</head>" >> $OUTPUT 346 echo "<body>文本比较<br/>" >> $OUTPUT 347 echo "<br/>" >> $OUTPUT 348 date >> $OUTPUT 349 echo "<br/>" >> $OUTPUT 350 echo "<br/>模式: 差异, 有上下文 <br/>" >> $OUTPUT 351 352 awk -F "\n" ‘BEGIN { 353 OUTPUT = "./output.tmp"; templine[6] = 0; step = 0; leftlines[2]; rightlines[2]; 354 samesection = 0; prevline = 0; thisline[2] = 0; prevlineonleft = 0; thislineonleft = 0; 355 prev2lineisdiff = 0; prevlineisdiff = 0; thislineisdiff = 0; comparesymbol = 0; deblank[2] = 0; 356 } { 357 switch (step) { 358 case 0: 359 if ($1 ~ /^Index:.*/) { 360 step = 1; 361 } 362 break; 363 case 1: 364 if ($1 ~ /^Cannot.*/) { 365 step = 0; 366 } else if ($1 ~ /^---.*/) { 367 match($1, /^---(.*)/, templine); 368 print "<br/>Left: " templine[1] > OUTPUT; 369 } else if ($1 ~ /^+++.*/) { 370 match($1, /^+++(.*)/, templine); 371 print "<br/>Right: " templine[1] "<br/>" > OUTPUT; 372 step = 2; 373 374 prevline = 0; 375 thisline[0] = 0; 376 prev2lineisdiff = -1; 377 prevlineisdiff = -1; 378 thislineisdiff = -1; 379 print "<table class=\"fc\" cellspacing=\"0\" cellpadding=\"0\">" > OUTPUT; 380 } 381 break; 382 case 2: 383 if ($1 ~ /^Index:.*/) { 384 step = 1; 385 print "<tr class=\"SectionEnd\">" > OUTPUT; 386 } 387 else { 388 if ($1 ~ /^@@.*@@$/) { 389 match($1, /@@ -(.*),(.*) +(.*),(.*) @@$/, templine); 390 leftlines[0] = templine[1]; 391 leftlines[1] = templine[2]; 392 rightlines[0] = templine[3]; 393 rightlines[1] = templine[4]; 394 if (leftlines[0] == rightlines[0] && leftlines[1] == rightlines[1]) { 395 samesection = 1; 396 } else { 397 samesection = 0; 398 } 399 if (prevline == 0) { 400 break; 401 } else { 402 thisline[0] = 0; 403 thisline[1] = 0; 404 thislineisdiff = prevlineisdiff; 405 } 406 } else if ($1 ~ /^##.*##/) { 407 step = 0; 408 break; 409 } else if ($1 ~ /^[-+].*/) { 410 match($1, /^[-+](.*)/, thisline); 411 thislineisdiff = 1; 412 if ($1 ~ /^-.*/) { 413 thislineonleft = 1; 414 } else { 415 thislineonleft = 0; 416 } 417 } else { 418 match($1, /^\s(.*)/, thisline); 419 thislineisdiff = 0; 420 } 421 422 if (prevline == 0) { 423 prevline = thisline[1]; 424 prevlineisdiff = thislineisdiff; 425 prevlineonleft = thislineonleft; 426 break; 427 } else if (prev2lineisdiff == -1) { 428 print "<tr class=\"SectionBegin\">" > OUTPUT; 429 if (prevlineisdiff) { 430 comparesymbol = "-+"; 431 } else { 432 comparesymbol = "="; 433 } 434 } else if (prev2lineisdiff != prevlineisdiff) { 435 if (prevlineisdiff != thislineisdiff) { 436 print "<tr class=\"SectionAll\">" > OUTPUT; 437 comparesymbol = " "; 438 } else { 439 print "<tr class=\"SectionBegin\">" > OUTPUT; 440 if (prevlineisdiff) { 441 comparesymbol = "-+"; 442 } else { 443 comparesymbol = "="; 444 } 445 } 446 } else { 447 if (prevlineisdiff != thislineisdiff) { 448 print "<tr class=\"SectionEnd\">" > OUTPUT; 449 comparesymbol = " "; 450 } else { 451 print "<tr class=\"SectionMiddle\">" > OUTPUT; 452 comparesymbol = " "; 453 } 454 } 455 } 456 457 deblank[0] = prevline; 458 deblank[1] = prevline; 459 prevline = ""; 460 while (deblank[1]~/^\t|^\s{4}/) { 461 match(deblank[1], /^\t{1}(.*)|^\s{4}(.*)/, deblank); 462 if (deblank[1] == "") { 463 deblank[1] = deblank[2]; 464 } else { 465 prevline = " " prevline; 466 } 467 } 468 prevline = prevline deblank[1]; 469 470 if (prevlineisdiff) { 471 if (prevlineonleft) { 472 print "<td class=\"TextItemNum AlignRight Wrap\">" leftlines[1] "</td>" > OUTPUT; 473 leftlines[1]++; 474 print "<td class=\"TextItemSigRightMod Wrap\"><span class=\"TextSegSigDiff\">" prevline "</span></td>" > OUTPUT; 475 } else { 476 print "<td class=\"TextItemNum AlignRight Wrap\"> </td>" > OUTPUT; 477 print "<td class=\"TextItemNum AlignRight Wrap\"> </td>" > OUTPUT; 478 } 479 } else { 480 print "<td class=\"TextItemNum AlignRight Wrap\">" leftlines[1] "</td>" > OUTPUT; 481 leftlines[1]++; 482 print "<td class=\"TextItemSame Wrap\">" prevline "</td>" > OUTPUT; 483 } 484 print "<td class=\"AlignCenter Wrap\">" comparesymbol "</td>" > OUTPUT 485 if (prevlineisdiff) { 486 if (prevlineonleft) { 487 print "<td class=\"TextItemNum AlignRight Wrap\"> </td>" > OUTPUT; 488 print "<td class=\"TextItemNum AlignRight Wrap\"> </td>" > OUTPUT; 489 } else { 490 print "<td class=\"TextItemNum AlignRight Wrap\">" rightlines[1] "</td>" > OUTPUT; 491 rightlines[1]++; 492 print "<td class=\"TextItemSigRightMod Wrap\"><span class=\"TextSegSigDiff\">" prevline "</span></td>" > OUTPUT; 493 } 494 } else { 495 print "<td class=\"TextItemNum AlignRight Wrap\">" rightlines[1] "</td>" > OUTPUT; 496 rightlines[1]++; 497 print "<td class=\"TextItemSame Wrap\">" prevline "</td>" > OUTPUT; 498 } 499 print "</tr>" > OUTPUT; 500 501 if (step == 2) { 502 prevline = thisline[1]; 503 prev2lineisdiff = prevlineisdiff; 504 prevlineisdiff = thislineisdiff; 505 prevlineonleft = thislineonleft; 506 } else { 507 print "</table>" > OUTPUT; 508 } 509 break; 510 default: 511 break; 512 } 513 } END { 514 print "<tr class=\"SectionEnd\">" > OUTPUT; 515 deblank[0] = prevline; 516 deblank[1] = prevline; 517 prevline = ""; 518 while (deblank[1]~/^[\t| ]/) { 519 match(deblank[1], /^[\t| ](.*)/, deblank); 520 prevline = " " prevline; 521 } 522 prevline = prevline deblank[1]; 523 524 print "<td class=\"TextItemNum AlignRight Wrap\"> "leftlines[1] "</td>" > OUTPUT; 525 leftlines[1]++; 526 if (prevlineisdiff) { 527 if (prevlineonleft) { 528 print "<td class=\"TextItemSigRightMod Wrap\"><span class=\"TextSegSigDiff\">" prevline "</span></td>" > OUTPUT; 529 } else { 530 print "<td class=\"TextItemNum AlignRight Wrap\"> </td>" > OUTPUT; 531 } 532 } else { 533 print "<td class=\"TextItemSame Wrap\">" prevline "</td>" > OUTPUT; 534 } 535 print "<td class=\"AlignCenter Wrap\">" comparesymbol "</td>" > OUTPUT 536 print "<td class=\"TextItemNum AlignRight Wrap\">" rightlines[1] "</td>" > OUTPUT; 537 rightlines[1]++; 538 if (prevlineisdiff) { 539 if (prevlineonleft) { 540 print "<td class=\"TextItemNum AlignRight Wrap\"> </td>" > OUTPUT; 541 } else { 542 print "<td class=\"TextItemSigRightMod Wrap\"><span class=\"TextSegSigDiff\">" prevline "</span></td>" > OUTPUT; 543 } 544 } else { 545 print "<td class=\"TextItemSame Wrap\">" prevline "</td>" > OUTPUT; 546 } 547 print "</tr>" > OUTPUT; 548 print "</table>" > OUTPUT; 549 print "</body>" > OUTPUT; 550 print "</html>" > OUTPUT; 551 print "complete!" 552 }‘ ./svn.tmp.conv 553 554 cat ./output.tmp >> $OUTPUT 555 } 556 557 case $1 in 558 revert) 559 echo "./svn.sh revert: revert commit history" 560 echo "================================" 561 NEED_LOCAL_DIR=1; 562 get_param; 563 revert; 564 ;; 565 count) 566 echo "./svn.sh count: count commit code" 567 echo "================================" 568 NEED_LOCAL_DIR=0; 569 get_param; 570 count; 571 ;; 572 report) 573 echo "./svn.sh report: output diff report" 574 echo "================================" 575 NEED_LOCAL_DIR=0; 576 get_param; 577 report; 578 ;; 579 *) 580 echo "usage: ./svn.sh [action]" 581 echo "[action] - revert / count / report ..." 582 echo "revert: revert commit history by [begin, end] range or bugid / author" 583 echo "count: count commit lines and times by [begin, end] range or bugid / author" 584 echo "report: diff commit and make report by bugid" 585 echo "================================" 586 exit 1 587 ;; 588 esac