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