代碼配置
個人開發者希望一個版本控制系統的安全網絡能夠運行在他們的本地的一台機器上。然而,開發團隊需要一個集中的服務器,所有的成員可以将服務器作為倉庫來訪問他們的代碼。在一個辦公室中,沒有問題 --隻是将倉庫連到本地網絡上的一台服務器上就行了。對于開放源碼項目…噢, 還是沒有問題,這要感謝因特網。CVS内建了客戶機/服務器存取方法,所以任何一個可以連到因特網上的開發者都可以存取在一台CVS服務器上的文件。n
代碼調整
在傳統的版本控制系統中,一個開發者檢出一個文件,修改它,然後将其登記回去。檢出文件的開發者擁有對這個文件修改的排它權。沒有其它的開發者可以檢出這個文件-- 并且隻有檢出那個文件的開發者可以登記(check in:注2)所做的修改。(當然對于管理員有很多方法可以超越這個限制。)n想一下排它的檢出可能會如何工作:Bob的兄弟檢出 foo.java以便加入注釋,寫好代碼後他什麼也沒做。然後他去吃午飯了。Bob吃完午飯後,發現他的老闆所指給他的一個bug在 foo.java裡。他試圖簽出 foo.java … 但是版本控制系統不允許他這樣做,因為他的兄弟已經把它簽出了。Bob不得不等着他的兄弟吃完午飯回來(在這個"好"日子用了兩個小時),他才可以修正bug。n在一個大型的開放源碼工程中,因為開發者可能在任意的時區工作得很晚,給予一個開發者阻止任意地方的其它開發者繼續處理任意文件的能力很明顯無法運轉。他們最終将因為不能夠在他們想要的時候開展項目而感到厭煩。nCVS通過它的無限制的簽出模式解決了這個問題。簽出一個文件并不給定開發者對那個文件的排它權。其它的開發者也可以對其檢出,進行他們自己的修改,并且将其登記回去。n"等一下"你可能會說。"但是後面的登記不是會覆蓋前面的嗎"回答是不會。詳細地回答就是當多個開發者對同一個文件作了修改CVS會檢測,并且自動合并那些改變。n哇噢。自動的,不用擔心 -- CVS 會很小心,并且将會自動合并那些隻要不是對代碼的同一行所作的改動。如果CVS不能安全的處理這些改動,開發者将不得不手工合并它們。從此去往何處。n有大量在許多平台上可用的CVS附加工具,它們給CVS增加了功能或使得CVS更容易使用。
曆史
CVS 誕生于 1986 年,當時作為一組 shell 腳本而出現;1989年3月,Brian Berlinor用C語言重新設計并編寫了CVS的代碼;1993年前後,Jim Kingdon最終将CVS設計成基于網絡的平台,開發者們能從Internet任何地方獲得程序源代碼。截至目前最新版本是2004年12月13日發布的1.12.11。
CVS 即 Concurrent Versions System
CVS是一個C/S系統,多個開發人員通過一個中心版本控制系統來記錄文件版本,從而達到保證文件同步的目的。工作模式如下:
CVS服務器(文件版本庫) / | (版 本 同 步) / | 開發者1 開發者2 開發者3
作為一般開發人員挑選2,6看就可以了,CVS的管理員則更需要懂的更多一些,最後還簡單介紹了一些Windows下的cvs客戶端使用,CVS遠程用戶認證的選擇及與BUG跟蹤系統等開發環境的集成問題。
- CVS環境初始化:CVS環境的搭建 管理員 CVS的日常使用:日常開發中最常用的CVS命令, 開發人員 管理員 CVS的分支開發:項目按照不同進度和目标并發進行 管理員 CVS的用戶認證:通過SSH的遠程用戶認證,安全,簡單 管理員 CVSWEB:CVS的WEB訪問界面大大提高代碼版本比較的效率 管理員 CVS TAG:将$Id$ 加入代碼注釋中,方便開發過程的跟蹤開發人員 CVS vs VSS: CVS和Virsual SourceSafe的比較 開發人員 管理員 WinCVS: 通過SSH認證的wincvs認證設置 基于CVSTrac的小組開發環境搭建:通過CVSTrac實現web界面的CVS用戶管理,集成的BUG跟蹤和WIKI交流 CVS中的用戶權限管理:基于系統用戶的CVS權限管理和基于CVSROOT/passwd的虛拟用戶管理
一個系統20%的功能往往能夠滿足80%的需求,CVS也不例外,以下是CVS最常用的功能,可能還不到它全部命令選項的20%,作為一般開發人員平時會用cvs update和cvs commit就夠了,更多的需求在實際應用過程中自然會出現,不時回頭看看相關文檔經常有意外的收獲。
環境設置:指定CVS庫的路徑CVSROOT
tcshsetenv CVSROOT /path/to/cvsroot
bashCVSROOT=/path/to/cvsroot ; export CVSROOT
後面還提到遠程CVS服務器的設置:
CVSROOT=:ext:[email protected]#port:/path/to/cvsroot CVS_RSH=ssh; export CVSROOT CVS_RSH
初始化:CVS版本庫的初始化。
cvs init
一個項目的首次導入
cvs import -m "write some comments here" project_name vendor_tag release_tag
執行後:會将所有源文件及目錄導入到/path/to/cvsroot/project_name目錄下
vender_tag: 開發商标記
release_tag: 版本發布标記
項目導出:将代碼從CVS庫裡導出
cvs checkout project_name
cvs 将創建project_name目錄,并将最新版本的源代碼導出到相應目錄中。這個checkout和Virvual SourceSafe中的check out不是一個概念,相對于Virvual SourceSafe的check out是cvs update, check in是cvs commit。
CVS的日常使用
注意:第一次導出以後,就不是通過cvs checkout來同步文件了,而是要進入剛才cvs checkout project_name導出的project_name目錄下進行具體文件的版本同步(添加,修改,删除)操作。
将文件同步到最新的版本
cvs update
不制定文件名,cvs将同步所有子目錄下的文件,也可以制定某個文件名/目錄進行同步
cvs update file_name
最好每天開始工作前或将自己的工作導入到CVS庫裡前都要做一次,并養成“先同步 後修改”的習慣,和Virvual SourceSafe不同,CVS裡沒有文件鎖定的概念,所有的沖突是在commit之前解決,如果你修改過程中,有其他人修改并commit到了CVS 庫中,CVS會通知你文件沖突,并自動将沖突部分用
>>>>>>
content on cvs server
<<<<<<
content in your file
>>>>>>
标記出來,由你确認沖突内容的取舍。
版本沖突一般是在多個人修改一個文件造成的,但這種項目管理上的問題不應該指望由CVS來解決。
确認修改寫入到CVS庫裡
cvs commit -m "write some comments here" file_name
注意:CVS的很多動作都是通過cvs commit進行最後确認并修改的,最好每次隻修改一個文件。在确認的前,還需要用戶填寫修改注釋,以幫助其他開發人員了解修改的原因。如果不用寫-m "comments"而直接确認`cvs commit file_name` 的話,cvs會自動調用系統缺省的文字編輯器(一般是vi)要求你寫入注釋。
注釋的質量很重要:所以不僅必須要寫,而且必須寫一些比較有意義的内容:以方便其他開發人員能夠很好的理解
不好的注釋,很難讓其他的開發人員快速的理解:比如: -m "bug fixed" 甚至 -m ""
好的注釋,甚至可以用中文: -m "在用戶注冊過程中加入了Email地址校驗"
修改某個版本注釋:每次隻确認一個文件到CVS庫裡是一個很好的習慣,但難免有時候忘了指定文件名,把多個文件以同樣注釋commit到CVS庫裡了,以下命令可以允許你修改某個文件某個版本的注釋:
cvs admin -m 1.3:"write some comments here" file_name
添加文件
創建好新文件後,比如:touch new_file
cvs add new_file
注意:對于圖片,Word文檔等非純文本的項目,需要使用cvs add -kb選項按2進制文件方式導入(k表示擴展選項,b表示binary),否則有可能出現文件被破壞的情況
比如:
cvs add -kb new_file.gif
cvs add -kb readme.doc
如果關鍵詞替換屬性在首次導入時設置錯了怎麼辦?
cvs admin -kkv new_file.css
然後确認修改并注釋
cvs ci -m "write some comments here"
删除文件
将某個源文件物理删除後,比如:rm file_name
cvs rm file_name
然後确認修改并注釋
cvs ci -m "write some comments here"
以上面前2步合并的方法為:
cvs rm -f file_name
cvs ci -m "why delete file"
注意:很多cvs命令都有縮寫形式:commit=>ci; update=>up; checkout=>co/get; remove=>rm;
添加目錄
cvs add dir_name
查看修改曆史
cvs log file_name
cvs history file_name
查看當前文件不同版本的區别
cvs diff -r1.3 -r1.5 file_name
查看當前文件(可能已經修改了)和庫中相應文件的區别
cvs diff file_name
cvs的web界面提供了更方便的定位文件修改和比較版本區别的方法,具體安裝設置請看後面的cvsweb使用
正确的通過CVS恢複舊版本的方法:
如果用cvs update -r1.2 file.name
這個命令是給file.name加一個STICK TAG: "1.2" ,雖然你的本意隻是想将它恢複到1.2版本
正确的恢複版本的方法是:cvs update -p -r1.2 file_name >file_name
如果不小心已經加成STICK TAG的話:用cvs update -A 解決
移動文件/文件重命名
cvs裡沒有cvs move或cvs rename,因為這兩個操作是可以由先cvs remove old_file_name,然後cvs add new_file_name實現的。
删除/移動目錄
最方便的方法是讓管理員直接移動,删除CVSROOT裡相應目錄(因為CVS一個項目下的子目錄都是獨立的,移動到$CVSROOT目錄下都可以作為新的獨立項目:好比一顆樹,其實砍下任意一枝都能獨立存活),對目錄進行了修改後,要求其開發人員重新導出項目cvs checkout project_name 或者用cvs update -dP同步。
項目發布導出不帶CVS目錄的源文件
做開發的時候你可能注意到了,每個開發目錄下,CVS都創建了一個CVS/目錄。裡面有文件用于記錄當前目錄和CVS庫之間的對應信息。但項目發布的時候你一般不希望把文件目錄還帶着含有CVS信息的CVS目錄吧,這個一次性的導出過程使用cvs export命令,不過export隻能針對一個TAG或者日期導出,比如:
cvs export -r release1 project_name
cvs export -D 20021023 project_name
cvs export -D now project_name
确認版本裡程碑:多個文件各自版本号不一樣,項目到一定階段,可以給所有文件統一指定一個階段裡程碑版本号,方便以後按照這個階段裡程碑版本号導出項目,同時也是項目的多個分支開發的基礎。
cvs tag release_1_0
開始一個新的裡程碑:
cvs commit -r 2 标記所有文件開始進入2.x的開發
注意:CVS裡的revsion和軟件包的發布版本可以沒有直接的關系。但所有文件使用和發布版本一緻的版本号比較有助于維護。
版本分支的建
在開發項目的2.x版本的時候發現1.x有問題,但2.x又不敢用,則從先前标記的裡程碑:release_1_0導出一個分支 release_1_0_patch
cvs rtag -b -r release_1_0 release_1_0_patch proj_dir
一些人先在另外一個目錄下導出release_1_0_patch這個分支:解決1.0中的緊急問題,
cvs checkout -r release_1_0_patch
而其他人員仍舊在項目的主幹分支2.x上開發
在release_1_0_patch上修正錯誤後,标記一個1.0的錯誤修正版本号
cvs tag release_1_0_patch_1
如果2.0認為這些錯誤修改在2.0裡也需要,也可以在2.0的開發目錄下合并release_1_0_patch_1中的修改到當前代碼中:
cvs update -j release_1_0_patch_1
CVSWEB:提高文件浏覽效率
CVSWEB就是CVS的WEB界面,可以大大提高程序員定位修改的效率:
使用的樣例可以看:http://www.freebsd.org/cgi/cvsweb.cgi
CVSWEB的下載:CVSWEB從最初的版本已經演化出很多功能界面更豐富的版本,這個是我個人感覺安裝設置比較方便的:
原先在:http://www.spaghetti-code.de/software/linux/cvsweb/,但目前已經删除,目前仍可以在本站下載CVSWEB,其實最近2年FreeBSD的CVSWeb項目已經有了更好的發展吧,而當初沒有用FreeBSD那個版本主要就是因為沒有彩色的文件Diff功能。
下載解包:
tar zxf cvsweb.tgz
把配置文件cvsweb.conf放到安全的地方(比如和apache的配置放在同一個目錄下),
修改:cvsweb.cgi讓CGI找到配置文件:
$config = $ENV{'CVSWEB_CONFIG'} || '/path/to/apache/conf/cvsweb.conf';
轉到/path/to/apache/conf下并修改cvsweb.conf:
修改CVSROOT路徑設置:缺省不顯示已經删除的文檔:在配置文件cvsweb.conf中還可以定制頁頭的描述信息,你可以修改$long_intro成你需要的文字CVSWEB可不能随便開放給所有用戶,因此需要使用WEB用戶認證:
先生成 passwd:
/path/to/apache/bin/htpasswd -c cvsweb.passwd user
修改httpd.conf: 增加
AuthName "CVS Authorization"
AuthType Basic
AuthUserFile /path/to/cvsweb.passwd
require valid-user
CVS TAGS
CVS TAGS: $Id: cvs_card.html,v 1.5 2003/03/09 08:41:46 chedong Exp $
将$Id: cvs_card.html,v 1.9 2003/11/09 07:57:11 chedong Exp $ 加在程序文件開頭的注釋裡是一個很好的習慣,cvs能夠自動解釋更新其中的内容成:file_name version time user_name 的格式,比如:cvs_card.txt,v 1.1 2002/04/05 04:24:12 chedong Exp,可以這些信息了解文件的最後修改人和修改時間
幾個常用的缺省文件:
default.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: 注意文件頭一般注釋用 /* 開始 javadoc注釋用 /** 開始的區别
/*
* 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() {
}
}
====================================
default.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 here
use strict;
日常使用:
注意:第一次導出以後,就不是通過cvs checkout來同步文件了,而是要進入剛才cvs checkout project_name導出的project_name目錄下進行具體文件的版本同步(添加,修改,删除)操作。
将文件同步到最新的版本cvs update
不制定文件名,cvs将同步所有子目錄下的文件,也可以制定某個文件名/目錄進行同步
cvs update file_name
最好每天開始工作前或将自己的工作導入到CVS庫裡前都要做一次,并養成“先同步 後修改”的習慣,和Virvual SourceSafe不同,CVS裡沒有文件鎖定的概念,所有的沖突是在commit之前解決,如果你修改過程中,有其他人修改并commit到了CVS 庫中,CVS會通知你文件沖突,并自動将沖突部分用
>>>>>>
content on cvs server
<<<<<<
content in your file
>>>>>>
标記出來,由你确認沖突内容的取舍。
版本沖突一般是在多個人修改一個文件造成的,但這種項目管理上的問題不應該指望由CVS來解決。
确認修改寫入到CVS庫裡
cvs commit -m "write some comments here" file_name
注意:CVS的很多動作都是通過cvs commit進行最後确認并修改的,最好每次隻修改一個文件。在确認的前,還需要用戶填寫修改注釋,以幫助其他開發人員了解修改的原因。如果不用寫-m "comments"而直接确認`cvs commit file_name` 的話,cvs會自動調用系統缺省的文字編輯器(一般是vi)要求你寫入注釋。
注釋的質量很重要:所以不僅必須要寫,而且必須寫一些比較有意義的内容:以方便其他開發人員能夠很好的理解
不好的注釋,很難讓其他的開發人員快速的理解:比如:-m "bugfixed" 甚至 -m ""
好的注釋,甚至可以用中文: -m "在用戶注冊過程中加入了Email地址校驗"
修改某個版本注釋:每次隻确認一個文件到CVS庫裡是一個很好的習慣,但難免有時候忘了指定文件名,把多個文件以同樣注釋commit到CVS庫裡了,以下命令可以允許你修改某個文件某個版本的注釋:
cvs admin -m 1.3:"write some comments here" file_name
添加文件
創建好新文件後,比如:touch new_file
cvs add new_file
注意:對于圖片,Word文檔等非純文本的項目,需要使用cvs add -kb選項按2進制文件方式導入(k表示擴展選項,b表示binary),否則有可能出現文件被破壞的情況
比如:
cvs add -kb new_file.gif
cvs add -kb readme.doc
如果關鍵詞替換屬性在首次導入時設置錯了怎麼辦?
cvs admin -kkv new_file.css
然後确認修改并注釋
cvs ci -m "write some comments here"
删除文件
将某個源文件物理删除後,比如:rm file_name
cvs rm file_name
然後确認修改并注釋
cvs ci -m "write some comments here"
以上面前2步合并的方法為:
cvs rm -f file_name
cvs ci -m "why delete file"
注意:很多cvs命令都有縮寫形式:commit=>ci; update=>up; checkout=>co/get; remove=>rm;
添加目錄
cvs add dir_name
查看修改曆史
cvs log file_name
cvs history file_name
查看當前文件不同版本的區别
cvs diff -r1.3 -r1.5 file_name
查看當前文件(可能已經修改了)和庫中相應文件的區别
cvs diff file_name
cvs的web界面提供了更方便的定位文件修改和比較版本區别的方法,具體安裝設置請看後面的cvsweb使用
正确的通過CVS恢複舊版本的方法:
如果用cvs update -r1.2 file.nam e
這個命令是給file.n ame加一個STICK TAG:"1.2" ,雖然你的本意隻是想将它恢複到1.2版本
正确的恢複版本的方法是:cvs update -p -r1.2 file_name >file_name
如果不小心已經加成STICK TAG的話:用cvs update -A 解決
移動文件/文件重命名
cvs裡沒有cvs move或cvs rename,因為這兩個操作是可以由先cvs remove old_file_name,然後cvs add new_file_name實現的。
删除/移動目錄
最方便的方法是讓管理員直接移動,删除CVSROOT裡相應目錄(因為CVS一個項目下的子目錄都是獨立的,移動到$CVSROOT目錄下都可以作為新的獨立項目:好比一顆樹,其實砍下任意一枝都能獨立存活),對目錄進行了修改後,要求其開發人員重新導出項目cvs checkout project_name 或者用cvs update -dP同步。
項目發布導出不帶CVS目錄的源文件
做開發的時候你可能注意到了,每個開發目錄下,CVS都創建了一個CVS/目錄。裡面有文件用于記錄當前目錄和CVS庫之間的對應信息。但項目發布的時候你一般不希望把文件目錄還帶着含有CVS信息的CVS目錄吧,這個一次性的導出過程使用cvs export命令,不過export隻能針對一個TAG或者日期導出,比如:
cvs export -r release1 project_name
cvs export -D 20021023 project_name
cvs export -D now project_name
CVS是一個C/S系統,多個開發人員通過一個中心版本控制系統來記錄文件版本,從而達到保證文件同步的目的。nnCVS是一個C/S系統,多個開發人員通過一個中心版本控制系統來記錄文件版本,從而達到保證文件同步的目的。工作模式如下:nnCVS服務器(文件版本庫)nn/ | / (版 本 同 步)nn/ | /nn開發者1 開發者2 開發者3nnCVS(Concurrent Version System)版本控制系統是一種GNU軟件包,主要用于在多人開發環境下的源碼的維護。實際上CVS可以維護任意文檔的開發和使用,例如共享文件的編輯修改,而不僅僅局限于程序設計。CVS維護的文件類型可以是文本類型也可以是二進制類型。CVS用Copy-Modify-Merge(拷貝、修改、合并)變化表支持對文件的同時訪問和修改。它明确地将源文件的存儲和用戶的工作空間獨立開來,并使其并行操作。CVS基于客戶端/服務器的行為使其可容納多個用戶,構成網絡也很方便。這一特性使得CVS成為位于不同地點的人同時處理數據文件(特别是程序的源代碼)時的首選。nn所有重要的免費軟件項目都使用CVS作為其程序員之間的中心點,以便能夠綜合各程序員的改進和更改。這些項目包括GNOME、KDE、THE GIMP和Wine等。nnCVS的基本工作思路是這樣的:在一台服務器上建立一個源代碼庫,庫裡可以存放許多不同項目的源程序。由源代碼庫管理員統一管理這些源程序。每個用戶在使用源代碼庫之前,首先要把源代碼庫裡的項目文件下載到本地,然後用戶可以在本地任意修改,最後用CVS命令進行提交,由CVS源代碼庫統一管理修改。這樣,就好象隻有一個人在修改文件一樣,既避免了沖突,又可以做到跟蹤文件變化等。nnCVS是并發版本系統(Concurrent Versions System)的意思,主流的開放源碼網絡透明的版本控制系統。CVS對于從個人開發者到大型,分布團隊都是有用的:nn它的客戶機/服務器存取方法使得開發者可以從任何因特網的接入點存取最 新的代碼。它的無限制的版本管理檢出(check out:注1)的模式避免了通常的因為排它 檢出模式而引起的人工沖突。 它的客戶端工具可以在絕大多數的平台上使用。nnCVS被應用于流行的開放源碼工程中,象Mozilla,GIMP,XEmacs,KDE,和GNOME等。 那麼它到底怎麼樣?nn你可能會說,它非常棒,但是對于 "我"來說它能做什麼?首先,基本的 :一個版本控制系統保持了對一系列文件所作改變的曆史記錄。對于一個開發者來說,那就意味着在你對一個程 序所進行開發的整個期間,能夠跟蹤對其所作的所有改動的痕迹。對你來說,有沒有出現過由于在令行上 按錯鍵而導緻一天的工作都白費的情況呢?版本控制系統給了你一個安全的網絡。nn版本控制系統對任何人都有用,真的。(畢竟,誰不願意使用一個安全的 網絡呢?)但是它們經常被軟件開發團隊使用。在團隊中工作的開發者需要能夠調整他們的各自的修改;一個集 中式版本控制系統允許那樣做。n代碼集中的配置nn個人開發者希望一個版本控制系統的安全網絡能夠運行在他們的本地的 一台機器上。然而,開發團隊需要一個集中的服務器,所有的成員可以将服務器作為倉庫來訪問他們的代碼。在 一個辦公室中,沒有問題 --隻是将倉庫連到本地網絡上的一台服務器上就行了。對于開放源碼項目...噢, 還是沒有問題,這要感謝因特網。CVS内建了客戶機/服務器存取方法,所以任何一個可以連到因特網上的開發 者都可以存取在一台CVS服務器上的文件。n
調整代碼
在傳統的版本控制系統中,一個開發者檢出一個文件,修改它,然後将 其登記回去。檢出文件的開發者擁有對這個文件修改的排它權。沒有其它的開發者可以檢出這個文件 -- 并且隻 有檢出那個文件的開發者可以登記(check in:注2)所做的修改。(當然對于管理員有很多方法可以超越這個 限制。)nn想一下排它的檢出可能會如何工作:Bob的兄弟檢出 foo.java以便加入 注釋,寫好代碼後他什麼也沒做。然後他去吃午飯了。Bob吃完午飯後,發現他的老闆所指給他的一個bug在 foo.java裡。他試圖檢出 foo.java ... 但是版本控制系統不允許他這樣做,因為他的兄弟已經把它檢出了。Bob不 得不等着他的兄弟吃完午飯回來(在這個 "好"日子用了兩個小時),他才可以修正bug。nn在一個大型的開放源碼工程中,因為開發者可能在任意的時區工作得很 晚,給予一個開發者阻止任意地方的其它開發者繼續處理任意文件的能力很明顯示無法運轉。他們最終将因為不 能夠在他們想要的時候開展項目而感到厭煩。nnCVS通過它的無限制的檢出模式解決了這個問題。檢出一個文件并不給定 開發者對那個文件的排它權。其它的開發者也可以對其檢出,進行他們自己的修改,并且将其登記回去。nn"等一下!"你可能會說。"但是後面的登記不是會覆蓋前面的嗎?"回答 是不會。詳細地回答就是當多個開發者對同一個文件作了修改CVS會檢測,并且自動合并那些改變。nn哇噢。自動的?不用擔心 -- CVS 會很小心,并且将會自動合并那些隻 要不是對代碼的同一行所作的改動。如果CVS不能安全的處理這些改動,開發者将不得不手工合并它們。 從此去往何處?nn到現在為止,你已經毫不猶豫地着迷于CVS 的潛力,并且急不可待地想 開始。第一步就是去得到 适合你的平台的CVS軟件。安裝CVS通常就是将其從你下載的壓縮包中解開這麼一件 事。配置CVS 可能要小心一些,它非常依賴于你使用的平台和你的CVS代碼倉庫的存放地。CVShome.org存放了大 量的CVS 文檔:nn。nn



















