百科創(chuàng)建
41.4K
8495

CVS

CVS是一個(gè)C/S系統(tǒng),是一個(gè)常用的代碼版本控制軟件。主要在開(kāi)源軟件管理中使用。與它相類似的代碼版本控制軟件有subversion。多個(gè)開(kāi)發(fā)人員通過(guò)一個(gè)中心版本控制系統(tǒng)來(lái)記錄文件版本,從而達(dá)到保證文件同步的目的。CVS版本控制系統(tǒng)是一種GNU軟件包,主要用于在多人開(kāi)發(fā)環(huán)境下的源碼的維護(hù)。但是由于之前CVS編碼的問(wèn)題,大多數(shù)軟件開(kāi)發(fā)公司都使用SVN替代了CVS。

工作模式

CVS服務(wù)器(文件版本庫(kù))

CVS(Concurrent Versions System)版本控制系統(tǒng)是一種GNU軟件包,主要用于在多人開(kāi)發(fā)環(huán)境下源碼的維護(hù)。Concurrent有并發(fā)的、協(xié)作的、一致的等含義。實(shí)際上CVS可以維護(hù)任意文檔的開(kāi)發(fā)和使用,例如共享文件的編輯修改,而不僅僅局限于程序設(shè)計(jì)。CVS維護(hù)的文件類型可以是文本類型也可以是二進(jìn)制類型。CVS用Copy-Modify-Merge(拷貝、修改、合并)變化表支持對(duì)文件的同時(shí)訪問(wèn)和修改。它明確地將源文件的存儲(chǔ)和用戶的工作空間獨(dú)立開(kāi)來(lái),并使其并行操作。CVS基于客戶端/服務(wù)器的行為使其可容納多個(gè)用戶。這一特性使得CVS成為位于不同地點(diǎn)的人同時(shí)處理數(shù)據(jù)文件(特別是程序的源代碼)時(shí)的首選。

所有重要的免費(fèi)軟件項(xiàng)目都使用CVS作為其程序員之間的中心點(diǎn),以便能夠綜合各程序員的改進(jìn)和更改。這些項(xiàng)目包括GNOME、KDE、THE?GIMP和Wine等。

工作思路

在一臺(tái)服務(wù)器上建立一個(gè)源代碼庫(kù),庫(kù)里可以存放許多不同項(xiàng)目的源程序。由源代碼庫(kù)管理員統(tǒng)一管理這些源程序。每個(gè)用戶在使用源代碼庫(kù)之前,首先要把源代碼庫(kù)里的項(xiàng)目文件下載到本地,然后用戶可以在本地任意修改,最后用CVS命令進(jìn)行提交,由CVS源代碼庫(kù)統(tǒng)一管理修改。這樣,就好像只有一個(gè)人在修改文件一樣,既避免了沖突,又可以做到跟蹤文件變化等。

CVS是并發(fā)版本系統(tǒng)(Concurrent Versions System)的意思,主流的開(kāi)放源碼網(wǎng)絡(luò)透明的版本控制系統(tǒng)。CVS對(duì)于從個(gè)人開(kāi)發(fā)者到大型、分布團(tuán)隊(duì)都是有用的。

它的客戶機(jī)/服務(wù)器存取方法使得開(kāi)發(fā)者可以從任何因特網(wǎng)的接入點(diǎn)存取最新的代碼。它的無(wú)限制的版本管理檢出(check out:注1)的模式避免了通常的因?yàn)榕潘鼨z出模式而引起的人工沖突。它的客戶端工具可以在絕大多數(shù)的平臺(tái)上使用。

CVS被應(yīng)用于流行的開(kāi)放源碼工程中,像Mozilla,GIMP,XEmacs,KDE和GNOME等。那么它到底怎么樣。

你可能會(huì)說(shuō),它非常棒,但是對(duì)于"我"來(lái)說(shuō)它能做什么。首先,基本的 :一個(gè)版本控制系統(tǒng)保持了對(duì)一系列文件所作改變的歷史記錄。對(duì)于一個(gè)開(kāi)發(fā)者來(lái)說(shuō),那就意味著在你對(duì)一個(gè)程序所進(jìn)行開(kāi)發(fā)的整個(gè)期間,能夠跟蹤對(duì)其所作的所有改動(dòng)的痕跡。對(duì)你來(lái)說(shuō),有沒(méi)有出現(xiàn)過(guò)由于在命令行上按錯(cuò)鍵而導(dǎo)致一天的工作都白費(fèi)的情況呢。版本控制系統(tǒng)給了你一個(gè)安全的網(wǎng)絡(luò)。

版本控制系統(tǒng)對(duì)任何人都有用,真的。(畢竟,誰(shuí)不愿意使用一個(gè)安全的網(wǎng)絡(luò)呢。)它們經(jīng)常被軟件開(kāi)發(fā)團(tuán)隊(duì)使用。在團(tuán)隊(duì)中工作的開(kāi)發(fā)者需要能夠調(diào)整他們的各自的修改;一個(gè)集中式版本控制系統(tǒng)允許那樣做。

代碼配置

個(gè)人開(kāi)發(fā)者希望一個(gè)版本控制系統(tǒng)的安全網(wǎng)絡(luò)能夠運(yùn)行在他們的本地的一臺(tái)機(jī)器上。然而,開(kāi)發(fā)團(tuán)隊(duì)需要一個(gè)集中的服務(wù)器,所有的成員可以將服務(wù)器作為倉(cāng)庫(kù)來(lái)訪問(wèn)他們的代碼。在一個(gè)辦公室中,沒(méi)有問(wèn)題 --只是將倉(cāng)庫(kù)連到本地網(wǎng)絡(luò)上的一臺(tái)服務(wù)器上就行了。對(duì)于開(kāi)放源碼項(xiàng)目…噢, 還是沒(méi)有問(wèn)題,這要感謝因特網(wǎng)。CVS內(nèi)建了客戶機(jī)/服務(wù)器存取方法,所以任何一個(gè)可以連到因特網(wǎng)上的開(kāi)發(fā)者都可以存取在一臺(tái)CVS服務(wù)器上的文件。

代碼調(diào)整

在傳統(tǒng)的版本控制系統(tǒng)中,一個(gè)開(kāi)發(fā)者檢出一個(gè)文件,修改它,然后將其登記回去。檢出文件的開(kāi)發(fā)者擁有對(duì)這個(gè)文件修改的排它權(quán)。沒(méi)有其它的開(kāi)發(fā)者可以檢出這個(gè)文件-- 并且只有檢出那個(gè)文件的開(kāi)發(fā)者可以登記(check in:注2)所做的修改。(當(dāng)然對(duì)于管理員有很多方法可以超越這個(gè)限制。)

想一下排它的檢出可能會(huì)如何工作:Bob的兄弟檢出 foo.java以便加入注釋,寫(xiě)好代碼后他什么也沒(méi)做。然后他去吃午飯了。Bob吃完午飯后,發(fā)現(xiàn)他的老板所指給他的一個(gè)bug在 foo.java里。他試圖簽出 foo.java … 但是版本控制系統(tǒng)不允許他這樣做,因?yàn)樗男值芤呀?jīng)把它簽出了。Bob不得不等著他的兄弟吃完午飯回來(lái)(在這個(gè)"好"日子用了兩個(gè)小時(shí)),他才可以修正bug。

在一個(gè)大型的開(kāi)放源碼工程中,因?yàn)殚_(kāi)發(fā)者可能在任意的時(shí)區(qū)工作得很晚,給予一個(gè)開(kāi)發(fā)者阻止任意地方的其它開(kāi)發(fā)者繼續(xù)處理任意文件的能力很明顯無(wú)法運(yùn)轉(zhuǎn)。他們最終將因?yàn)椴荒軌蛟谒麄兿胍臅r(shí)候開(kāi)展項(xiàng)目而感到厭煩。

CVS通過(guò)它的無(wú)限制的簽出模式解決了這個(gè)問(wèn)題。簽出一個(gè)文件并不給定開(kāi)發(fā)者對(duì)那個(gè)文件的排它權(quán)。其它的開(kāi)發(fā)者也可以對(duì)其檢出,進(jìn)行他們自己的修改,并且將其登記回去。

"等一下"你可能會(huì)說(shuō)。"但是后面的登記不是會(huì)覆蓋前面的嗎"回答是不會(huì)。詳細(xì)地回答就是當(dāng)多個(gè)開(kāi)發(fā)者對(duì)同一個(gè)文件作了修改CVS會(huì)檢測(cè),并且自動(dòng)合并那些改變。

哇噢。自動(dòng)的,不用擔(dān)心 -- CVS 會(huì)很小心,并且將會(huì)自動(dòng)合并那些只要不是對(duì)代碼的同一行所作的改動(dòng)。如果CVS不能安全的處理這些改動(dòng),開(kāi)發(fā)者將不得不手工合并它們。從此去往何處。

有大量在許多平臺(tái)上可用的CVS附加工具,它們給CVS增加了功能或使得CVS更容易使用。

使用好處

·修改軟件時(shí)可能會(huì)不知不覺(jué)混進(jìn)一些bug,而且可能過(guò)了很久你才會(huì)察覺(jué)到它們的存在。有了 cvs,你可以很容易地恢復(fù)舊版本,并從中看出到底是哪個(gè)修改導(dǎo)致了這個(gè)bug。有時(shí)這是很有用的。

·cvs 用一種聰明的辦法把一個(gè)文件的所有版本保存在一個(gè)文件里,僅僅保存不同版本之間的差異。

·cvs 最初由 Dick Grune 在 1986 年 12 月以 shell腳本的形式發(fā)布在 comp.sources.unix?的新聞組第 6 卷里;1989 年 4 月,Brian Berliner 設(shè)計(jì)了 cvs 并編寫(xiě)了代碼。之后 Jeff Polk 幫助 Brian 設(shè)計(jì)了 cvs 模塊和銷售商分支支持。

·cvs 不能指導(dǎo)你如何構(gòu)造什么。它只是將你所設(shè)計(jì)的一種樹(shù)結(jié)構(gòu)文件保存下來(lái)以備恢復(fù)之用。

·cvs 不能決定如何在一個(gè)檢出工作目錄使用磁盤空間。如果你在每一個(gè)目錄中都寫(xiě)下 Makefile 或腳本,且必須知道其它一切的相對(duì)位置,有時(shí)不得不檢出整個(gè)倉(cāng)庫(kù)。

·如果你將你的工作模塊化,并且建立了一個(gè)共享文件的 build 系統(tǒng)(通過(guò)links,mounts,Makefiles 里的 VPATH 等),你就可以隨意安排磁盤的使用。

·你應(yīng)該在 cvs 下放一個(gè)工具來(lái)支持這樣一個(gè)構(gòu)造系統(tǒng)(腳本、Makefile 等等)。

·有些變化發(fā)生在 cvs 范圍之外時(shí),要想想什么文件需要重建。一個(gè)傳統(tǒng)的方法是用?make?來(lái)構(gòu)造,并用一些自動(dòng)化的工具來(lái)產(chǎn)生 make 所用的相關(guān)文件。

替代管理

你的經(jīng)理和項(xiàng)目負(fù)責(zé)人應(yīng)經(jīng)常與你交流以確保你時(shí)時(shí)記得進(jìn)度表、合并點(diǎn)、分支名和發(fā)布日期。如果他們不這樣做,cvs 也沒(méi)用。cvs 只是一個(gè)用來(lái)使你的資源與你的步調(diào)一致的工具。但你是風(fēng)笛手和作曲家,沒(méi)有哪種樂(lè)器會(huì)自己演奏或是作曲。

·cvs?不能代替開(kāi)發(fā)者之間的交流。

在單個(gè)文件內(nèi)遇到?jīng)_突時(shí),大多數(shù)開(kāi)發(fā)者不費(fèi)多大力氣就能解決它們。但更常見(jiàn)的"沖突(conflict)",是那些難度較大、不在開(kāi)發(fā)者之間進(jìn)行交流就沒(méi)法解決的問(wèn)題。

當(dāng)在一個(gè)文件內(nèi)或多個(gè)文件中同時(shí)發(fā)生變化時(shí),cvs 并不知道何時(shí)它們會(huì)在邏輯上發(fā)生沖突。它的沖突(conflict)概念是純粹文本意義上的,這種沖突會(huì)在同一個(gè)文件的兩種變化十分接近以致于會(huì)破壞合并命令(如diff3)。

cvs 決不會(huì)指出程序邏輯上非文本或分布式的沖突。例如:假如你改變了在文件A 中定義的函數(shù)X 的參數(shù)。同時(shí),別人在編輯文件B,仍用舊參數(shù)調(diào)用 X 這個(gè)函數(shù)。此時(shí)產(chǎn)生的沖突 cvs 可就無(wú)能為力了。

變化控制

變化控制可以指許多事情。首先它的意思可以是 BUG 跟蹤bug-tracking,就是說(shuō)它能維持一個(gè)數(shù)據(jù)庫(kù),其中包括已報(bào)告的 BUG 和每一個(gè) BUG 狀態(tài) (是否已更正。在哪一個(gè)版本中,提交這個(gè) BUG 的人是否認(rèn)為已經(jīng)更正)。為了使 cvs 和一個(gè)外部的跟蹤 BUG 系統(tǒng)協(xié)調(diào)一致,請(qǐng)參考 rcsinfo 和 verifymsg文件(參閱 Administrative files)。

變化控制的另一個(gè)方面指跟蹤這樣的情況,即對(duì)好幾個(gè)文件的改變實(shí)際上只是同一個(gè)邏輯變動(dòng)。如果你在一次 cvs commit 操作中檢入幾個(gè)文件,cvs 會(huì)忘掉它們是一起檢入的,它們共用一個(gè) LOG 信息的事實(shí)只是把它們綁在一起而已。做一個(gè) gnu 風(fēng)格的 ChangeLog 可能會(huì)有點(diǎn)用。在一些系統(tǒng)中,變化控制的另一個(gè)方面是跟蹤每個(gè)變化的狀態(tài)的能力。一些變化由一個(gè)開(kāi)發(fā)者寫(xiě)出,而另一些變化則由另一個(gè)開(kāi)發(fā)者來(lái)作出評(píng)論,等等。一般來(lái)講,用 cvs 來(lái)做,是產(chǎn)生一個(gè) diff(用 cvs diff 或 diff),并且用電子郵件寄給某人,此人就可以用 patch 來(lái)應(yīng)用它。這是非常靈活的,但依賴于 cvs 之外的機(jī)制以保證事情不會(huì)崩潰。

自動(dòng)測(cè)試

強(qiáng)制利用 commitinfo文件測(cè)試套件應(yīng)該是可能的。不過(guò)我沒(méi)有聽(tīng)說(shuō)過(guò)多少項(xiàng)目試圖那樣做或那里有微妙的陷阱。

內(nèi)置處理

有些系統(tǒng)提供一些方法確保變更或發(fā)布通過(guò)不同的步驟,以及各種所需的批準(zhǔn)過(guò)程。一般地,你可以用 cvs 來(lái)完成它,但是可能要多做點(diǎn)工作。有些情況下你想用 commitinfo、loginfo、rcsinfo 或 verifymsg文件,要求在 CVS 提交之前完成某些操作。你也會(huì)考慮諸如 branches 和tags等特性是否能用在一個(gè)開(kāi)發(fā)樹(shù)中執(zhí)行任務(wù),然后僅當(dāng)它們被證實(shí)就把某些修改合并到一棵穩(wěn)定的樹(shù)中。

CVS 還有一個(gè)更加重要的特性:能記下每個(gè)文件的每次修改,以及如何被修改…對(duì)于基于 Internet 的合作方式來(lái)說(shuō),這些特性太重要了。一個(gè)地域上分散的自愿者組織顯然不可能投入很多的時(shí)間來(lái)訓(xùn)練其成員彼此合作。因?yàn)檫@樣的話,當(dāng)該組織有成員變更的時(shí)候,為此付出的投資將損失殆盡。所以需要指定一套基本的項(xiàng)目分配方案,以確保新成員能較容易的適應(yīng)工作,同時(shí)也需要設(shè)置一個(gè)自動(dòng)的系統(tǒng)來(lái)接受外來(lái)代碼,并使每個(gè)成員能及時(shí)得到最新修改的代碼。

術(shù)語(yǔ)

Revision (修訂版本)--文件歷史記錄中的被開(kāi)發(fā)者提交的變化。一個(gè)修訂版本就是一個(gè)時(shí)常變化的項(xiàng)目的?snapshot?(瞬態(tài)圖)。

Repository (源代碼庫(kù))--CVS 存儲(chǔ)所有修訂版本歷史記錄的地方。每個(gè)項(xiàng)目都有自己的一個(gè)確定的源代碼庫(kù)。

Working copy (工作拷貝)--開(kāi)發(fā)者對(duì)文件作出修改時(shí)文件所在的拷貝。Check out (檢驗(yàn))--從源代碼庫(kù)中申請(qǐng)一份工作拷貝。

該工作拷貝反映的是取出時(shí)項(xiàng)目的瞬時(shí)狀態(tài)。當(dāng)開(kāi)發(fā)者對(duì)拷貝作出修改時(shí),必須運(yùn)用 commit (提交)和 update (更新) 命令來(lái) “發(fā)布”變化和查看其他開(kāi)發(fā)者所作的修改。

Commit (提交)--將工作拷貝中的變化輸入中央源代碼庫(kù)。

Log message (日志信息)--提交修訂版本的時(shí)候,附帶描述變化的注解。通過(guò)查閱記錄信息,人們可以獲得一個(gè)當(dāng)前項(xiàng)目進(jìn)程的總結(jié)。

Update (更新)--從源代碼庫(kù)中取出別人的修改數(shù)據(jù),將其輸入自己的工作拷貝,并顯示自己的工作拷貝是否有未提交的修改。注意,不要和 commit (提交)混淆,更新和提交是一對(duì)互補(bǔ)的指令。記住: Update 將使工作拷貝和源代碼庫(kù)拷貝保持同步更新。

Conflicts (沖突)--兩個(gè)開(kāi)發(fā)者對(duì)同一個(gè)區(qū)域所做的改動(dòng)都提交給主版本時(shí)出現(xiàn)的情況,在 CVS 覺(jué)察并指出這個(gè)沖突后,開(kāi)發(fā)者必須解決該沖突。

環(huán)境設(shè)置

tcsh

setenv CVSROOT /path/to/cvsroot

bash

CVSROOT=/path/to/cvsroot ;?export CVSROOT

后面還提到遠(yuǎn)程CVS服務(wù)器的設(shè)置:

CVSROOT=:ext:$USER@test.server.address#port:/path/to/cvsroot CVS_RSH=ssh; export CVSROOT CVS_RSH

初始化:CVS版本庫(kù)的初始化。

cvs init

一個(gè)項(xiàng)目的首次導(dǎo)入

cvs import -m "write some comments here" project_name?vendor_tag release_tag

執(zhí)行后:會(huì)將所有源文件及目錄導(dǎo)入到/path/to/cvsroot/project_name目錄下

vender_tag: 開(kāi)發(fā)商標(biāo)記

release_tag: 版本發(fā)布標(biāo)記

項(xiàng)目導(dǎo)出:將代碼從CVS庫(kù)里導(dǎo)出

cvs checkout project_name

cvs 將創(chuàng)建project_name目錄,并將最新版本的源代碼導(dǎo)出到相應(yīng)目錄中。這個(gè)checkout和Virvual SourceSafe中的check out不是一個(gè)概念,相對(duì)于Virvual SourceSafe的check out是cvs update, check in是cvs commit。

日常使用

注意:第一次導(dǎo)出以后,就不是通過(guò)cvs checkout來(lái)同步文件了,而是要進(jìn)入剛才cvs checkout project_name導(dǎo)出的project_name目錄下進(jìn)行具體文件的版本同步(添加,修改,刪除)操作。

將文件同步到最新的版本cvs update

不制定文件名,cvs將同步所有子目錄下的文件,也可以制定某個(gè)文件名/目錄進(jìn)行同步

cvs update file_name

最好每天開(kāi)始工作前或?qū)⒆约旱墓ぷ鲗?dǎo)入到CVS庫(kù)里前都要做一次,并養(yǎng)成“先同步 后修改”的習(xí)慣,和Virvual SourceSafe不同,CVS里沒(méi)有文件鎖定的概念,所有的沖突是在commit之前解決,如果你修改過(guò)程中,有其他人修改并commit到了CVS 庫(kù)中,CVS會(huì)通知你文件沖突,并自動(dòng)將沖突部分用

content on cvs server

content in your file

標(biāo)記出來(lái),由你確認(rèn)沖突內(nèi)容的取舍。

版本沖突一般是在多個(gè)人修改一個(gè)文件造成的,但這種項(xiàng)目管理上的問(wèn)題不應(yīng)該指望由CVS來(lái)解決。

確認(rèn)修改寫(xiě)入到CVS庫(kù)里

cvs commit -m "write some comments here" file_name

注意:CVS的很多動(dòng)作都是通過(guò)cvs commit進(jìn)行最后確認(rèn)并修改的,最好每次只修改一個(gè)文件。在確認(rèn)的前,還需要用戶填寫(xiě)修改注釋,以幫助其他開(kāi)發(fā)人員了解修改的原因。如果不用寫(xiě)-m "comments"而直接確認(rèn)`cvs commit file_name` 的話,cvs會(huì)自動(dòng)調(diào)用系統(tǒng)缺省的文字編輯器(一般是vi)要求你寫(xiě)入注釋。


注釋的質(zhì)量很重要:所以不僅必須要寫(xiě),而且必須寫(xiě)一些比較有意義的內(nèi)容:以方便其他開(kāi)發(fā)人員能夠很好的理解

不好的注釋,很難讓其他的開(kāi)發(fā)人員快速的理解:比如:-m "bugfixed" 甚至 -m

好的注釋,甚至可以用中文: -m "在用戶注冊(cè)過(guò)程中加入了Email地址校驗(yàn)"

修改某個(gè)版本注釋:每次只確認(rèn)一個(gè)文件到CVS庫(kù)里是一個(gè)很好的習(xí)慣,但難免有時(shí)候忘了指定文件名,把多個(gè)文件以同樣注釋commit到CVS庫(kù)里了,以下命令可以允許你修改某個(gè)文件某個(gè)版本的注釋:

cvs?admin?-m 1.3:"write some comments here" file_name

添加文件

創(chuàng)建好新文件后,比如:touch new_file

cvs add new_file

注意:對(duì)于圖片,Word文檔等非純文本的項(xiàng)目,需要使用cvs add -kb選項(xiàng)按2進(jìn)制文件方式導(dǎo)入(k表示擴(kuò)展選項(xiàng),b表示binary),否則有可能出現(xiàn)文件被破壞的情況

比如:

cvs add -kb new_file.gif

cvs add -kb readme.doc

如果關(guān)鍵詞替換屬性在首次導(dǎo)入時(shí)設(shè)置錯(cuò)了怎么辦。

cvs admin -kkv new_file.css

然后確認(rèn)修改并注釋

cvs ci -m "write some comments here"

刪除文件

將某個(gè)源文件物理刪除后,比如:rm file_name

cvs rm file_name

然后確認(rèn)修改并注釋

cvs ci -m "write some comments here"

以上面前2步合并的方法為:

cvs rm -f file_name

cvs ci -m "why delete file"

注意:很多cvs命令都有縮寫(xiě)形式:commit=,ci; update=,up; checkout=,co/get;?remove=,rm;

添加目錄

cvs add dir_name

查看修改歷史

cvs log file_name

cvs history file_name

查看當(dāng)前文件不同版本的區(qū)別

cvs diff -r1.3 -r1.5 file_name

查看當(dāng)前文件(可能已經(jīng)修改了)和庫(kù)中相應(yīng)文件的區(qū)別

cvs diff file_name

cvs的web界面提供了更方便的定位文件修改和比較版本區(qū)別的方法,具體安裝設(shè)置請(qǐng)看后面的cvsweb使用

正確的通過(guò)CVS恢復(fù)舊版本的方法:

如果用cvs update -r1.2 file.nam e

這個(gè)命令是給file.n ame加一個(gè)STICK TAG:"1.2" ,雖然你的本意只是想將它恢復(fù)到1.2版本

正確的恢復(fù)版本的方法是:cvs update -p -r1.2 file_name ,file_name

如果不小心已經(jīng)加成STICK TAG的話:用cvs update -A?解決

動(dòng)文件/文件重命名

cvs里沒(méi)有cvs move或cvs rename,因?yàn)檫@兩個(gè)操作是可以由先cvs remove old_file_name,然后cvs add new_file_name實(shí)現(xiàn)的。

刪除/移動(dòng)目錄

最方便的方法是讓管理員直接移動(dòng),刪除CVSROOT里相應(yīng)目錄(因?yàn)镃VS一個(gè)項(xiàng)目下的子目錄都是獨(dú)立的,移動(dòng)到$CVSROOT目錄下都可以作為新的獨(dú)立項(xiàng)目:好比一顆樹(shù),其實(shí)砍下任意一枝都能獨(dú)立存活),對(duì)目錄進(jìn)行了修改后,要求其開(kāi)發(fā)人員重新導(dǎo)出項(xiàng)目cvs checkout project_name 或者用cvs update -dP同步。

項(xiàng)目發(fā)布導(dǎo)出不帶CVS目錄的源文件

做開(kāi)發(fā)的時(shí)候你可能注意到了,每個(gè)開(kāi)發(fā)目錄下,CVS都創(chuàng)建了一個(gè)CVS/目錄。里面有文件用于記錄當(dāng)前目錄和CVS庫(kù)之間的對(duì)應(yīng)信息。但項(xiàng)目發(fā)布的時(shí)候你一般不希望把文件目錄還帶著含有CVS信息的CVS目錄吧,這個(gè)一次性的導(dǎo)出過(guò)程使用cvs export命令,不過(guò)export只能針對(duì)一個(gè)TAG或者日期導(dǎo)出,比如:

cvs export -r release1 project_name

cvs export -D 20021023 project_name

cvs export -D now project_name

同步開(kāi)發(fā)

分支適用于什么情況

假定 tc 的發(fā)行版 1.0 已完成。你正在繼續(xù)開(kāi)發(fā) tc,計(jì)劃在 2 個(gè)月后創(chuàng)建發(fā)行 1.1 的版本。不久你的客戶開(kāi)始抱怨說(shuō)代碼有些問(wèn)題。你檢出了 1.0 的發(fā)行版(參閱Tags),找到了這個(gè)錯(cuò)誤(這將會(huì)有一個(gè)小小的更正)。但是,當(dāng)前代碼的版本是處在一個(gè)不穩(wěn)的狀態(tài), 并且在下一個(gè)月才能有希望穩(wěn)定下來(lái)。這樣就沒(méi)法基于最新源代碼去發(fā)行一個(gè)修復(fù)錯(cuò)誤的版本。這種情況下就可以去為所有構(gòu)成 tc 的 1.0 發(fā)行版文件創(chuàng)建版本樹(shù)的一個(gè)分支(branch)。然后你可以修改這分支而不影響到主干。當(dāng)修訂完成時(shí),你可以選定是否要把它同主干合并或繼續(xù)保留在這個(gè)分支里。

確認(rèn)版本里程碑:多個(gè)文件各自版本號(hào)不一樣,項(xiàng)目到一定階段,可以給所有文件統(tǒng)一指定一個(gè)階段里程碑版本號(hào),方便以后按照這個(gè)階段里程碑版本號(hào)導(dǎo)出項(xiàng)目,同時(shí)也是項(xiàng)目的多個(gè)分支開(kāi)發(fā)的基礎(chǔ)。

cvs tag release_1_0

開(kāi)始一個(gè)新的里程碑:

cvs commit -r 2 標(biāo)記所有文件開(kāi)始進(jìn)入2.x的開(kāi)發(fā)

注意:CVS里的revsion和軟件包的發(fā)布版本可以沒(méi)有直接的關(guān)系。但所有文件使用和發(fā)布版本一致的版本號(hào)比較有助于維護(hù)。

版本分支的建立

在開(kāi)發(fā)項(xiàng)目的2.x版本的時(shí)候發(fā)現(xiàn)1.x有問(wèn)題,但2.x又不敢用,則從先前標(biāo)記的里程碑:release_1_0導(dǎo)出一個(gè)分支 release_1_0_patch

cvs rtag -b -r release_1_0 release_1_0_patch proj_dir

一些人先在另外一個(gè)目錄下導(dǎo)出release_1_0_patch這個(gè)分支:解決1.0中的緊急問(wèn)題,

cvs checkout -r release_1_0_patch

而其他人員仍舊在項(xiàng)目的主干分支2.x上開(kāi)發(fā)

在release_1_0_patch上修正錯(cuò)誤后,標(biāo)記一個(gè)1.0的錯(cuò)誤修正版本號(hào)

cvs tag release_1_0_patch_1

如果2.0認(rèn)為這些錯(cuò)誤修改在2.0里也需要,也可以在2.0的開(kāi)發(fā)目錄下合并release_1_0_patch_1中的修改到當(dāng)前代碼中:

cvs update -j release_1_0_patch_1

遠(yuǎn)程訪問(wèn)

使用cvs本身基于pserver的遠(yuǎn)程認(rèn)證很麻煩,需要定義服務(wù)器和用戶組,用戶名,設(shè)置密碼等,

常見(jiàn)的登陸格式如下:

cvs -d :pserver:cvs_user_name@cvs.server.address:/path/to/cvsroot login

例子:

cvs -d :pserver:cvs@sam ba.or g:/cvsroot login

不是很安全,因此一般是作為匿名只讀CVS訪問(wèn)的方式。從安全考慮,通過(guò)系統(tǒng)本地賬號(hào)認(rèn)證并通過(guò)SSH傳輸是比較好的辦法,通過(guò)在客戶機(jī)的 /etc/profile里設(shè)置一下內(nèi)容:

CVSROOT=:ext:$USER@cvs.server.address#port:/path/to/cvsroot CVS_RSH=ssh; export CVSROOT CVS_RSH

有客戶機(jī)所有本地用戶都可以映射到CVS服務(wù)器相應(yīng)同名賬號(hào)了。

比如:

CVS服務(wù)器是192.168.0.3,上面CVSROOT路徑是/home/cvsroot,另外一臺(tái)開(kāi)發(fā)客戶機(jī)是192.168.0.4,如果 tom在2臺(tái)機(jī)器上都有同名的賬號(hào),那么從192.168.0.4上設(shè)置了:

export CVSROOT=:ext:tom@192.168.0.3:/home/cvsrootexport?

CVS_RSH=ssh

tom就可以直接在192.168.0.4上對(duì)192.168.0.3的cvsroot進(jìn)行訪問(wèn)了(如果有權(quán)限的話)

cvs checkout project_name

cd project_namecvs update

cvs commit

如果CVS所在服務(wù)器的SSH端口不在缺省的22,或者和客戶端與CVS服務(wù)器端SSH缺省端口不一致,有時(shí)候設(shè)置了:

:ext:$USER@test.server.address#port:/path/to/cvsroot

仍然不行,比如有以下錯(cuò)誤信息

ssh: test.server.address#port: Name or service not known

cvs [checkout aborted]: end of file from server (consult above messages if any)

解決的方法是做一個(gè)腳本指定端口轉(zhuǎn)向(不能使用alias,會(huì)出找不到文件錯(cuò)誤):

創(chuàng)建一個(gè)/usr/bin/ssh_cvs文件,假設(shè)遠(yuǎn)程服務(wù)器的SSH端口是非缺省端口:34567

#!/bin/sh

/usr/bin/ssh -p 34567 "$@"

后:chmod +x /usr/bin/ssh_cvs

并CVS_RSH=ssh_cvs; export CVS_RSH

注意:port是指相應(yīng)服務(wù)器SSH的端口,不是指cvs專用的pserver的端口

WEB

CVSWEB就是CVS的WEB界面,可以大大提高程序員定位修改的效率:

CVSWEB的下載:CVSWEB從最初的版本已經(jīng)演化出很多功能界面更豐富的版本,這個(gè)是我個(gè)人感覺(jué)安裝設(shè)置比較方便的:

下載解包:

tar zxf cvsweb.tgz

配置文件cvsweb.conf放到安全的地方(比如和apache的配置放在同一個(gè)目錄下),

修改:cvsweb.cgi讓CGI找到配置文件:

$config = $ENV{'CVSWEB_CONFIG'} || '/path/to/apache/conf/cvsweb.conf';

轉(zhuǎn)到/path/to/apache/conf下并修改cvsweb.conf:

修改CVSROOT路徑設(shè)置:%CVSROOT = ('Development' =,'/path/to/cvsroot',#<==修改指向本地的CVSROOT); 缺省不顯示已經(jīng)刪除的文檔:"hideattic" => "1",#,==缺省不顯示已經(jīng)刪除的文檔 在配置文件cvsweb.conf中還可以定制頁(yè)頭的描述信息,你可以修改$long_intro成你需要的文字 CVSWEB可不能隨便開(kāi)放給所有用戶,因此需要使用WEB用戶認(rèn)證:

先生成 passwd:

/path/to/apache/bin/htpasswd -c cvsweb.passwd user

修改httpd.conf: 增加

<Directory "/path/to/apache/cgi-bin/cvsweb/">

AuthName "CVS Authorization"

AuthType Basic

AuthUserFile /path/to/cvsweb.passwd

require valid-user

</Directory>

TAGS

將$Id: cvs_card.html,v 1.9 2003/11/09 07:57:11 chedong Exp $ 加在程序文件開(kāi)頭的注釋里是一個(gè)很好的習(xí)慣,cvs能夠自動(dòng)解釋更新其中的內(nèi)容成:file_name version time user_name 的格式,比如:cvs_card.txt,v 1.1 2002/04/05 04:24:12 chedong Exp,可以這些信息了解文件的最后修改人和修改時(shí)間

幾個(gè)常用的缺省文件:default.php<?php/* * Copyright (c) 2002 Company Name. * $Header: /home/cvsroot/tech/cvs_card.html,v 1.9 2003/11/09 07:57:11 chedong Exp $ */?

>====================================Default.java: 注意文件頭一般注釋用 /* 開(kāi)始 JAVADOC注釋用 /** 開(kāi)始的區(qū)別/* * Copyright (c) 2002 MyCompany Name. * $Header: /home/cvsroot/tech/cvs_card.html,v 1.9 2003/11/09 07:57:11 chedong Exp $ */package com.mycompany;import java.;/** * comments here */public class Default /** * Comments here * @param * @return */ public toString ====================================de fa ult. pl:#!/usr/bin/perl -w# Copyright (c) 2002 Company Name.# $Header: /home/cvsroot/tech/cvs_card.html,v 1.9 2003/11/09 07:57:11 chedong Exp $# file comments hereuse strict;CVS-CVS vs VSS CVS沒(méi)有文件鎖定模式,VSS在check out同時(shí),同時(shí)記錄了文件被導(dǎo)出者鎖定。

CVS的update和commit, VSS是get_lastest_version和check in

對(duì)應(yīng)VSS的check out/undo check out的CVS里是edit和unedit

在CVS中,標(biāo)記自動(dòng)更新功能缺省是打開(kāi)的,這樣也帶來(lái)一個(gè)潛在的問(wèn)題,就是不用-kb方式添加binary文件的話在cvs自動(dòng)更新時(shí)可能會(huì)導(dǎo)致文件失效。

$Header: /home/cvsroot/tech/cvs_card.html,v 1.5 2003/03/09 08:41:46 chedong Exp $ $Date: 2003/11/09 07:57:11 $這樣的標(biāo)記在Virsual?SourceSafe中稱之為Keyword Explaination,缺省是關(guān)閉的,需要通過(guò)OPITION打開(kāi),并指定需要進(jìn)行源文件關(guān)鍵詞掃描的文件類型:*.txt,*.java,*.html…

對(duì)于Virsual SourceSafe和CVS都通用的TAG有:

$Header: /home/cvsroot/tech/cvs_card.html,v 1.5 2003/03/09 08:41:46 chedong Exp $

$Author: chedong $

$Date: 2003/11/09 07:57:11 $

$Revision: 1.9 $

我建議盡量使用通用的關(guān)鍵詞保證代碼在CVS和VSS都能方便的跟蹤。

Win

下載

cvs Windows客戶端:穩(wěn)定版本為1.2

ssh Windows客戶端

安裝好以上2個(gè)軟件以后:

WinCVS客戶端的admin==,preference設(shè)置

1.在general選單里

設(shè)置CVSROOT:username@192.168.0.123:/home/cvsroot

設(shè)置Authorization: 選擇SSH?server

2.Port選單里

鉤上:check for alternate rsh name

并設(shè)置ssh.exe的路徑,缺省是裝在 C:\Program Files\NetworkSimplicity\ssh\ssh.exe

然后就可以使用WinCVS進(jìn)行cvs操作了,所有操作都會(huì)跳出命令行窗口要求你輸入服務(wù)器端的認(rèn)證密碼。

當(dāng)然,如果你覺(jué)得這樣很煩的話,還有一個(gè)辦法就是生成一個(gè)沒(méi)有密碼的公鑰/私鑰對(duì),并設(shè)置CVS使用基于公鑰/私鑰的SSH認(rèn)證(在general 選單里)。

可以選擇的diff工具:examdiff

還是在WinCVS菜單admin==,preference的WinCVS選單里

選上:Externel diff program

并設(shè)置diff工具的路徑,比如:C:\Program Files\ed16i\ExamDiff.exe

在對(duì)文件進(jìn)行版本diff時(shí),第一次需要將窗口右下角的use?externel diff選上。

環(huán)境搭建

作為一個(gè)小組級(jí)的開(kāi)發(fā)環(huán)境,版本控制系統(tǒng)和BUG跟蹤系統(tǒng)等都涉及到用戶認(rèn)證部分。如何方便的將這些系統(tǒng)集成起來(lái)是一個(gè)非常困難的事情,畢竟我們不能指望 Linux下有像Source Offsite那樣集成度很高的版本控制/BUG跟蹤集成系統(tǒng)。

我個(gè)人是很反對(duì)使用pserver模式的遠(yuǎn)程用戶認(rèn)證的,但如果大部分組員使用WINDOWS客戶端進(jìn)行開(kāi)發(fā)的話,總體來(lái)說(shuō)使用 CVSROOT/passwd認(rèn)證還是很難避免的,但CVS本身用戶的管理比較麻煩。本來(lái)我打算自己用perl寫(xiě)一個(gè)管理界面的,直到我發(fā)現(xiàn)了 CVSTrac:一個(gè)基于WEB界面的BUG跟蹤系統(tǒng),它外掛在CVS系統(tǒng)上的BUG跟蹤系統(tǒng),其中就包括了WEB界面的CVSROOT/passwd文件的管理,甚至還集成了WIKIWIKI討論組功能。這里首先說(shuō)一下CVS的pserver模式下的用戶認(rèn)證,CVS的用戶認(rèn)證服務(wù)是基于inetd中的:

cvspserver stream tcp nowait apache /usr/bin/cvs cvs --allow-root=/home/cvsroot pserver

一般在2401端口(這個(gè)端口號(hào)很好記:49的平方)

CVS用戶數(shù)據(jù)庫(kù)是基于CVSROOT/passwd文件,文件格式

[username]:[crypt_password]:[mapping_system_user]

由于密碼都用的是UNIX標(biāo)準(zhǔn)的CRYPT加密,這個(gè)passwd文件的格式基本上是apache的htpasswd格式的擴(kuò)展(比APACHE的 PASSWD文件多一個(gè)系統(tǒng)用戶映射字段),所以這個(gè)文件最簡(jiǎn)單的方法可以用

apache/bin/htpasswd -b myname mypassword

創(chuàng)建。注意:通過(guò)htpasswd創(chuàng)建出來(lái)的文件會(huì)沒(méi)有映射系統(tǒng)用戶的字段

例如:new:geBvosup/zKl2

setup:aISQuNAAoY3qw

test:hwEpz/BX.rEDU

映射系統(tǒng)用戶的目的在于:你可以創(chuàng)建一個(gè)專門的CVS服務(wù)賬號(hào),比如用apache的運(yùn)行用戶apache,并將/home/cvsroot目錄下的所有權(quán)限賦予這個(gè)用戶,然后在passwd文件里創(chuàng)建不同的開(kāi)發(fā)用戶賬號(hào),但開(kāi)發(fā)用戶賬號(hào)最后的文件讀寫(xiě)權(quán)限都映射為apache用戶,在SSH模式下多個(gè)系統(tǒng)開(kāi)發(fā)用戶需要在同一個(gè)組中才可以相互讀寫(xiě)CVS庫(kù)中的文件。

進(jìn)一步的,你可以將用戶分別映射到apache這個(gè)系統(tǒng)用戶上。

new:geBvosup/zKl2:apache

setup:aISQuNAAoY3qw:apache

test:hwEpz/BX.rEDU:apache

CVSTrac很好的解決了CVSROOT/passwd的管理問(wèn)題,而且包含了BUG跟蹤報(bào)告系統(tǒng)和集成WIKIWIKI交流功能等,使用的 CGI方式的安裝,并且基于GNU Public License:

在inetd里加入cvspserver服務(wù):

cvspserver stream tcp nowait apache /usr/bin/cvs cvs --allow-root=/home/cvsroot pserver

xietd的配置文件:%cat cvspserver

service cvspserver

disable?= no

socket_type = stream

wait = no

user = apache

server = /usr/bin/cvs

server_args = -f --allow-root=/home/cvsroot pserver

log_on_failure += USERID

注意:這里的用戶設(shè)置成apache目的是和/home/cvsroot的所有用戶一致,并且必須讓這個(gè)這個(gè)用戶對(duì)/home/cvsroot/下的 CVSROOT/passwd和cvstrac初始化生成的myproj.db有讀取權(quán)限。

安裝過(guò)程

假設(shè)數(shù)據(jù)庫(kù)名是 myproj在已經(jīng)裝好的CVS服務(wù)器上(CVS庫(kù)這時(shí)候應(yīng)該已經(jīng)是初始化好了,比如:cvs init初始化在/home/cvsroot里),運(yùn)行一下%cvstrac init /home/cvsroot myproj運(yùn)行后,/home/cvsroot里會(huì)有一個(gè)的myproj.db庫(kù),使用CVSTRAC服務(wù),/home/cvsroot/myproj.db /home/cvsroot/CVSROOT/readers /home/cvsroot/CVSROOT/writers /home/cvsroot/CVSROOT/passwd這幾個(gè)文件對(duì)于web服務(wù)的運(yùn)行用戶應(yīng)該是可寫(xiě)的,在RedHat8上,缺省就有一個(gè)叫 apache用戶和一個(gè)apache組,所以在httpd.conf文件中設(shè)置了用apache用戶運(yùn)行web服務(wù):User apacheGroup apache,然后設(shè)置屬于apache用戶和apache組#chown?-R apache:apache /home/cvsroot-rw-r--r-- 1 apache apache 55296 Jan 5 19:40 myproj.dbdrwxrwxr-x 3 apache apache 4096 Oct 24 13:04 CVSROOT/drwxrwxr-x 2 apache apache 4096 Aug 30 19:47 some_proj/此外還在/home/cvsroot/CVSROOT中設(shè)置了:chmod 664 readers writers passwd在apche/cgi-bin目錄中創(chuàng)建腳本cvstrac:#!/bin/sh/usr/bin/cvstrac cgi /home/cvsroot設(shè)置腳本可執(zhí)行:chmod +x /home/apache/cgi-bin/cvstrac從http://cvs.server.address/cgi-bin/cvstrac/myproj進(jìn)入管理界面缺省登錄名:setup 密碼 setup對(duì)于一般用戶可以從:http://cvs.server.address/cgi-bin/cvstrac/myproj在setup中重新設(shè)置了CVSROOT的路徑后,/home/cvsroot如果是初次使用需要在/home/cvsroot/CVSROOT下創(chuàng)建passwd,readers,writers文件touch passwd readers writers然后設(shè)置屬于apache用戶,chown apache.apache passwd readers writers這樣使用setup用戶創(chuàng)建新用戶后會(huì)同步更新CVSROOT/passwd下的賬號(hào)修改登錄密碼,進(jìn)行BUG報(bào)告等,

更多使用細(xì)節(jié)可以在使用中慢慢了解。

對(duì)于前面提到的WinCVS在perference里設(shè)置:

CVSROOT欄輸入:username@ip.address.of.cvs:/home/cvsroot

Authenitication選擇:use passwd file on server side

就可以了從服務(wù)器上進(jìn)行CVS操作了。

權(quán)限管理

CVS的權(quán)限管理分2種策略

基于系統(tǒng)文件權(quán)限的系統(tǒng)用戶管理:適合多個(gè)在Linux上使用系統(tǒng)賬號(hào)的開(kāi)發(fā)人員進(jìn)行開(kāi)發(fā)?;贑VSROOT/passwd的虛擬用戶管理:適合多個(gè)在Windows平臺(tái)上的開(kāi)發(fā)人員將賬號(hào)映射成系統(tǒng)賬號(hào)使用。為什么使用apache/apache用戶。首先RedHat8中缺省就有了,而且使用這個(gè)用戶可以方便通過(guò)cvstrac進(jìn)行WEB管理。

chown -R apache.apache /home/cvsroot

chmod 775 /home/cvsroot

Linux上通過(guò)ssh連接CVS服務(wù)器的多個(gè)開(kāi)發(fā)人員:通過(guò)都屬于apache組實(shí)現(xiàn)文件的共享讀寫(xiě)

開(kāi)發(fā)人員有開(kāi)發(fā)服務(wù)器上的系統(tǒng)賬號(hào):sysuser1 sysuser2,設(shè)置讓他們都屬于apache組,因?yàn)橥ㄟ^(guò)cvs新導(dǎo)入的項(xiàng)目都是對(duì)組開(kāi)放的:664權(quán)限的,這樣無(wú)論那個(gè)系統(tǒng)用戶導(dǎo)入的項(xiàng)目文件,只要文件的組宿主是apache,所有其他同組系統(tǒng)開(kāi)發(fā)用戶就都可以讀寫(xiě);基于ssh遠(yuǎn)程認(rèn)證的也是一樣。

apache(system group)

/ | \

sysuser1 sysuser2 sysuser3

Windows上通過(guò)cvspserver連接CVS服務(wù)器的多個(gè)開(kāi)發(fā)人員:通過(guò)在passwd文件種映射成 apache用戶實(shí)現(xiàn)文件的共享讀寫(xiě)

他們的賬號(hào)通過(guò)CVSROOT/passwd和readers writers這幾個(gè)文件管理;通過(guò)cvstrac設(shè)置所有虛擬用戶都映射到apache用戶上即可。

apache(system user)

/ | \

windev1 windev2 windev3

利用CVS WinCVS/CVSWeb/CVSTrac 構(gòu)成了一個(gè)相對(duì)完善的跨平臺(tái)工作組開(kāi)發(fā)版本控制環(huán)境。

發(fā)展

20世紀(jì)90年代初期,Jim kingdon最終將CVs設(shè)計(jì)成基于網(wǎng)絡(luò)的平臺(tái),因此開(kāi)發(fā)者們能從因特網(wǎng)上的任何地方獲得程序源代碼。這使得基本代碼對(duì)所有感興趣的人開(kāi)放了。由于CVs能巧妙地對(duì)相同文件的變化進(jìn)行合并,開(kāi)發(fā)者也就無(wú)需為很多的人在同一套源代碼上工作而擔(dān)心。


8495

免責(zé)聲明:本站詞條系由網(wǎng)友創(chuàng)建、編輯和維護(hù),內(nèi)容僅供參考。

以上內(nèi)容均為商業(yè)內(nèi)容展示,僅供參考,不具備專業(yè)問(wèn)題解決服務(wù),

如果您需要解決具體問(wèn)題(尤其在法律、醫(yī)學(xué)等領(lǐng)域),建議您咨詢相關(guān)領(lǐng)域的專業(yè)人士。

如您發(fā)現(xiàn)詞條內(nèi)容涉嫌侵權(quán),請(qǐng)通過(guò) 948026894@qq.com 與我們聯(lián)系進(jìn)行刪除處理!

下一篇:波音
一秒推