作者:Linuxaid sunmoon
3.在管理中的相關技術
3.1 在管理源文件的一種技術叫"關鍵字替換".在每次執行"cvs commit"操作后源文件的某些關鍵字會被替換為可用的詞
$AUTHOR$ 用戶名
$Data$ 登記時的時間
$Header$ 標準的首部,包含RCS的完整路徑名,日期,作者
$Id$ 除RCS文件名不完整外與$Header$同.
$Log$ 包含RCS的完整路徑名,版本號,日期,作者和在提交時提供的日誌信息.
$RCSfile$ 包含RCS的文件名,不包括路徑名
$Revision$ 分配的版本號
$Source$ RCS文件的完整名
$State$ 分配的版本的狀態,由 cvs admin -s 分配.
例: 在cvs commit之前,main.c里有
static char *rcsid="$Id$";
執行cvs commit后
main.c的改行變為:
static char *rcsid="$Id: main.c,v 1.2 1999/04/29 15:10:14 trimblef Exp$";
當然,這裡只是一個演示.在實際的程序開發中,這種技術有非常有用的作用,在此不多贅述.有興趣的朋友可參考相關書籍.
3.2 創建分支可以使用戶對一些文件使用命令commit進行修改時不會影響主幹. 創建分支應首先為擬作修改的那些文件創建一個標籤(tag).
標籤是賦於一個文件或一組文件的符號.在源代碼的生命周期里,組成一組模塊的文件被賦於相同的標籤.在工作目錄中執行
~usr/teat/$cvs tag release-1-0
標籤創建后, 就可以為其創建一個分支:
~usr/teat/$cvs rtag -b -r release-1-0 release-1-0-path print
-b :創建分支
-r release-1-0 :指定存在的標籤
releas-1-0-patch:分支
print: 模塊名
使用cvs update -j 選項可以將分支上的改變與本地文件拷貝合併.
~usr/teat/$cvs update -j release-1-0 print.c
對源文件作必要修改後, 可以用cvs release 刪除本地工作拷貝
並通知其他開發者這個模塊不再使用.
~use/$cvs release -d test
3.3 衝突解決
在有多個用戶對同一個文件進行修改時,如果修改了其中的相同部分,而修改後的內容如果有不同的話,出現衝突是不可避免的.
例如在CVS 文件倉庫中有一個文件 test.c ,它的版本是 1.4, 用戶A 先檢出該文件進行修改,而稍後有用戶B 檢出該文件進行修改,並提前提交成 1.5,這樣在用戶A再提交時就會出現衝突,這時CVS會提示需要手工解決.
例如,文件倉庫中的版本1.4:內容為:
#include
main()
{
int i;
for(i = 0; i < 100; i )
printf(「Count: %d
」, i);
}
用戶B 1.5:
#include
main()
{
int i;
for(i = 0; i < 10; i )
printf(「Count: %d
」, i);
printf(「Over
」);
}
用戶A :
#include
main()
{
int i;
for(i = 0; i < 50; i )
printf(「Count: %d
」, i);
return;
}
提交時會提示有衝突,這樣需要手工編輯,這時如果用戶A運行了$cvs update 之後,再編輯test.c, 會看到test.c 的內容是這樣的:
#include
main()
{
int i;
<<<<<<< test.c
for(i = 0; i < 50; i )
=======
for(i = 0; i < 10; i )
>>>>>>> 1.5
printf("Count: %d
", i);
<<<<<<< test.c
return;
=======
printf("Over
");
>>>>>>> 1.5
}
這樣就需要,根據任務的不同,來手工修改,這是比較麻煩的,
在真正的協作開發中,很少,對同一個文件給與,很多人相同的提交許可權.
3.4 文件版本管理
版本管理系統,最重要的莫過於對文件版本的管理,系統默認的版本升級使用的版本號是一定的.如果由於特殊需要,要自己定義出文件的版本號時,你可以用一下命令:
cvs log [-lR][-r rev][-d date][-w login][files…]
其中,參數的意義如下:
-l 不處理子目錄
-R 對子目錄做同樣處理
-r 指定版本號
-d 指定時間
-w 指定登錄名
使用下面的命令可以參看當前模塊的版本號或指定文件的所有歷史版本信息.
cvs annotate [-lR][-r rev|-D date] files
其中,參數的意義如下:
-l 不處理子目錄
-R 對子目錄做同樣處理
-r 指定版本號
使用下面的命令可以參看指定文件(檢出之後)的所有修改信息.
$cvs annotate cvstest/c/test.c
輸出依次為:版本 修改人 修改時間 源代碼
1.1 (tang 18-Jan-00): #include
1.1 (tang 18-Jan-00): #include
1.1 (tang 18-Jan-00):
1.1 (tang 18-Jan-00): main()
1.1 (tang 18-Jan-00): {
1.1 (tang 18-Jan-00): int i = 0 ;
1.1 (tang 18-Jan-00):
1.1 (tang 18-Jan-00): for(i = 0; i < 20; i )
1.1 (tang 18-Jan-00): printf("Count: %d
", i);
1.1 (tang 18-Jan-00):
1.3 (tang 18-Jan-00): printf("222222
");
1.4 (tang 18-Jan-00): printf("333333
");
1.1 (tang 18-Jan-00): }
使用下面的命令可以生成相對於一個指定主版本的分支版本:
cvs rtag –b –r rev_root rev_branch file_name
其中,參數的意義如下:
-b 指定生成一個分支版本
-r 指定該分支的主幹節點版本號
rev_root 主幹版本號
rev_branch 分支版本號
file_name 指定文件,使用「.」表示當前目錄下所有文件
使用下面的命令可以生成一個對應版本號的分支版本,由於CVS 版本號是用數字錶示的,
在同一個模塊下不同文件的版本完全可能是不同的,
使用標識會更方便.
例:
$cvs rtag –b –r 1.2 tlb-1 SOURCE
以後要訪問該分支版本,可以使用「-r」 選項
$cvs checkout –r tlb-1 SOURCE
從當前檢出的版本切換到一個分支版本:
$cvs update –r tlb-1 SOURCE
使用下面的命令可以看版本信息:
cvs status [–vlR] files
其中,參數的意義如下:
-v 顯示所有信息
-l 不顯示子目錄信息
-R 顯示子目錄信息
命令:cvs update –j rev module 把當前所做的修改與指定版本的文件進行合併.
如:主幹 1.1 1.2 1.3 1.4 1.5 1.6 ↓
分支tlb-1 1.2.2.1 1.2.2.2 1.2.2.3
如果要合併分支tlb-1上的版本:
$cvs update –j 1.2.2.3 –j tlb-1 test.c
其中1.2.2.3可以通過tag命令生成一個容易記憶的標識.
如果要合併分支tlb-1到主幹上1.2 :
$cvs update –j tlb-1 test.c
如果要合併主幹上的不同版本(注意順序很重要,同時在指定版本之間的所有修改將被丟棄):
$cvs update –j 1.5 –j 1.2 test.c
如果在不同版本之間模塊的文件有增減,則可以:
$cvs update –A
$cvs updata –jbranch_name
四、命令集
在本章的例子中,介紹了很多,命令的詳細用法,其大多數是以應用的角度,來分析的.實際上.cvs 擁有,大量的命令.如gcc 一樣cvs 常用的命令也不是很多,在本節中,我們列出了一些常用的命令.力圖不和以上各節中介紹的相重複.當然,限於時間和水平,在此也不可能列出cvs 所有的命令.有興趣的朋友.可以,參考,cvs的說明文檔,與linux 的man文檔,詳細學習,也可來此做出指導
1.檢出源文件
cvs checkout [-r rev][-D date][-d dir][-j merg1] [-j merg2] modules
其中,參數的意義如下:
-r 檢出指定版本的模塊
-D 檢出指定日期的模塊
-d 檢出指定目錄而不是模塊
-j 合併當前版本和指定版本
使用下面的命令會檢出剛才生成的模塊,並在當前目錄下生成與文件倉庫中完全一樣的目錄結構:
usr$ cvs checkout project
usr$ cvs checkout project/src/main
cvs checkout的詳細用法見cvs -H checkout的輸出.
2.CVS commit 命令 在對文件的修改完成後,用cvs commit提交到倉庫.
cvs commit -m "Update by xxxxx" project
cvs commit -m "Update main.c" main.c
提交完成後,當前的版本號會更新,如原來為1.1,現為1.2. 這兩個版本都在倉庫的主幹(maintrunk)上.
-m選項可以記錄有關提交的註釋.如果沒有指定-m選項,在環境變數CVSEDITOR中指定的編輯器被調用(vi是預設的),提示鍵入文本,修改記錄註釋.
3.刪除、增加、重命名文件和目錄
cvs add [-k kflags][-m message] files...
其中,參數的意義如下:
-k 指定以後該文件的預設檢出目錄
-m 對文件的描述
上述命令會加入一個新的文件到文件倉庫里,但直到使用了提交命令它才會真正更新文件倉庫.
cvs remove [options] files
上述命令會從文件倉庫中刪除文件,但也要到提交之後才有作用.
例1:增加文件
$cvs checkout SOURCE
$cd cvstest/c
$touch test.c
$cvs add test.c
$cvs commit –m 「add test.c」
例2:刪除文件
$cvs checkout SOURCE
$cd cvstest/c
$rm test.c
$cvs remove test.c
使用 –f 選項能上面兩步合做一步.
$cvs remove –f test.c
如果在提交之前想恢復剛才刪除的文件,可以如下:
$cvs add test.c
如果只執行了第一步刪除(rm),則可以用下面的方法恢復:
$cvs update test.c
對於重命名的文件,可以先刪除再添加.
對於目錄的修改(重命名),可能需要修改cvs 管理文件,一般應該遵循以下步驟:假設tom正在修改文件的一部分,現想合併更新自己的本地拷貝(checkout)和另一個人所做的修改(已經放在倉庫里),可用
~usr/test/$cvs update
確認所有有關的修改都已經提交;
進入文件倉庫中要修改的模塊目錄,對相應的目錄進行修改(重命名或刪除)
$cd $CVSROOT/modules
$mv old_dir new_dir
如果有必要,修改管理文件,比如modules 文件,如果要刪除目錄,則應該先對目錄中每個文件都進行了刪除(包括使用cvs remove )處理之後再執行上面的第2步.
4.提交源文件
cvs commit [-Rl][-m mesg] files
-R 連子目錄一起提交
-l 只提交本地目錄(不提交子目錄)
-m 註釋信息
在檢出源文件之後,在工作目錄中對源文件進行的所有修改都必須在提交之後才能使文件倉庫中的源文件起作用,並且新的文件才能夠被分配一個新的版本號.
5.釋放工作目錄
cvs release –d SOURCE
這個命令會刪除工作目錄 cvstest/c (建議在提交了修改的模塊后執行這一步), 它比使用 rm –rf cvstest 要好.
在此介紹了,使用cvs 伺服器進行.并行開發中常用的.命令.希望能起一個拋磚引玉的作用
五、小結
本章,介紹了一些版本控制的知識.與幾種辦控制系統.並從易用的角度,講述了在linux機器上,構架cvs伺服器的過程,與cvs 簡單的使用方法
cvs 也可以說是一種網路應用程序.它的功能在於,他能提供在并行的條件下,對多用戶同時開發,便利,安全的源碼.管理模式.個人認為,cvs的出現是自由的linux的必然產物.
他也會在linux這片熱土下,得到更有前途的發展.
本章,旨在易於入手.對於cvs複雜的應用,管理過程.筆者也不是很熟悉.這需要在實際的應用中,積累經驗.學習提高.
如果對這部分,有什麼見解.歡迎來信指導