萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 作業系統 >  >> Linux 教學

CVS/RCS 版本控制系統實戰指南 (二):Korn Shell 封裝腳本完整原始碼

Shell Scripts 簡介

以下提供一組基於 CVS 基本指令的 Korn Shell (ksh) 腳本,放入 /usr/local/bin 並加入 PATH 即可使用。它們展示如何將 CVS 指令封裝為更彈性的操作介面(如檔案鎖定提示),您可依需求移植至 Bash 或 Perl。

腳本清單

腳本功能
sget [-r rev] <FILE|DIR>取出唯讀檔案或目錄
sedit [-r rev] <FILE>取出可寫入檔案並自動鎖定(防止他人提交)
scommit [-r rev] <FILE|DIR>提交修改
supdate <FILE|DIR>更新至最新版本
sunlock [-r rev] <FILE>釋放 sedit 加的鎖
slist列出正被編輯的檔案
sinfo <FILE|DIR>顯示版本資訊
slog <FILE>顯示版本歷史
sdif [-r rev1 -r rev2] <FILE>比較版本差異(避開系統 sdiff)
sadd <FILE>新增檔案到版本庫
sdelete <FILE>從版本庫刪除檔案
sfreeze <TAG> <DIR>凍結原始碼樹並打標籤(發布用)
saddtree <TAG> <DIR>將整個目錄樹納入版控

sfreeze 使用範例

cd $HOME
sfreeze REVISION_1_0 srctree
# 之後可用標籤名稱 checkout 整個樹

4.1 sget 腳本原始碼

#!/bin/ksh
# CVS program sget - check out read-only
cmdname=$(basename $0)
Usage() {
  print "\nUsage: $cmdname [-r revision/tag] "
  print "Example: $cmdname -r 1.1 foo.cpp"
  print "         $cmdname some_dir"
  print "         $cmdname -r REVISION_1 some_dir"
  exit 1
}
while getopts r: opt; do
  case $opt in
    r) FLAG1=$opt; OARG1=$OPTARG ;;
    ?) Usage ;;
  esac
done
shift $((OPTIND-1))
[ $# -lt 1 ] && Usage

bkextn=sget_bak
hme=$(echo $HOME | cut -f1 -d';')
[ -z "$hme" ] && { print "ERROR: \$HOME not set"; exit 1; }

# 若檔案已存在且可寫,中止
if [ -f "$1" ]; then
  perms=$(ls -l "$1" | awk '{print $1}' | cut -b3,6,9)
  case $perms in *w*) print "ERROR: File writable. Backup/commit/delete first."; exit ;; esac
fi

cur_dir=$(pwd)
len=${#hme}
len=$((len+2))
subdir=$(echo $cur_dir | cut -b $len-2000)
fdname=${subdir:+$subdir/}$1

touch "$1" 2>/dev/null
mv -f "$1" "$1.$bkextn"

( cd $hme
  if [ -z "$FLAG1" ]; then
    cvs -r checkout -A "$fdname"
  else
    cvs -r checkout -A -"$FLAG1" "$OARG1" "$fdname"
  fi
)
[ -f "$1" ] && { print "\nREAD-ONLY copy of $fdname obtained."; print "Done $cmdname"; }

4.2 sedit 腳本原始碼(含檔案鎖定)

#!/bin/ksh
# CVS program sedit - check out read/write with locking
cmdname=$(basename $0)
Usage() {
  print "\nUsage: $cmdname [-r revision] "
  print "Example: $cmdname -r 1.1 foo.cpp"
  exit 1
}
while getopts r: opt; do
  case $opt in
    r) FLAG1=$opt; OARG1=$OPTARG ;;
    ?) Usage ;;
  esac
done
shift $((OPTIND-1))
[ $# -lt 1 ] && Usage

hme=$(echo $HOME | cut -f1 -d';')
[ -z "$hme" ] && { print "ERROR: \$HOME not set"; exit 1; }
bkextn=sedit_bak
cur_dir=$(pwd)
len=${#hme}
len=$((len+2))
subdir=$(echo $cur_dir | cut -b $len-2000)
fdname=${subdir:+$subdir/}$1

cvs_root=$(echo $CVSROOT | cut -f1 -d';')
[ -z "$cvs_root" ] && { print "ERROR: \$CVSROOT not set"; exit 1; }
cldir=$CVSROOT/$subdir/Locks
mkdir -p "$cldir" 2>/dev/null
rcsfile=$CVSROOT/$subdir/$1,v
[ ! -e "$rcsfile" ] && { print "ERROR: $1 not in CVS repository"; exit 1; }

# 取得最新版本號
tmpfile=$hme/sedit-lock.tmp
rm -f "$tmpfile" 2>/dev/null
if [ -z "$FLAG1" ]; then
  ( cd $hme; cvs log "$fdname" | head -6 | grep head: | awk '{print $2}' > "$tmpfile" )
  OARG1=$(cat "$tmpfile")
  rm -f "$tmpfile" 2>/dev/null
fi

lockfile=$cldir/$1-$OARG1
if [ -e "$lockfile" ]; then
  print "\nERROR: File $1 Revision $OARG1 already locked."
  exit 1
fi
# ...(後續建立鎖定、checkout -r 等邏輯)
完整腳本請參考原始文件;此處節錄核心邏輯。安裝 pdksh*.rpm 即可獲得 /bin/ksh。
copyright © 萬盛學電腦網 all rights reserved