CVS(Concurrent Versions System)即版本控制系統,是一個C/S(Client/Service)系統。多個開發人員經過一箇中心版本控制系統來記錄文件版本,從而達到保證文件同步的目的,工做模式:php
CVS服務器(文件版本庫)
/ | \
(版 本 同 步)
/ | \
開發者1 開發者2 開發者3git
a、 代碼統一管理,保存全部代碼文件更改的歷史記錄。對代碼進行集中統一管理,能夠方便查看新增或刪除的文件,可以跟蹤全部代碼改動痕跡。能夠隨意恢復到之前任意一個歷史版本。並避免了由於版本不一樣引入的深層BUG。
b、 完善的衝突解決方案,能夠方便的解決文件衝突問題,而不須要藉助其它的文件比較工具和手工的粘貼複製。
c、 代碼權限的管理。能夠爲不一樣的用戶設置不一樣的權限。能夠設置訪問用戶的密碼、只讀、修改等權限,並且經過CVS ROOT目錄下的腳本,提供了相應功能擴充的接口,不但能夠完成精細的權限控制,還能完成更加個性化的功能。
d、 支持方便的版本發佈和分支功能。數據庫
資源庫(Repository)
CVS的資源庫存儲所有的版本控制下的文件copy,一般不允許直接訪問,只能經過cvs命令,得到一份本地copy,改動後再check in(commit)回資源庫。而資源庫一般爲與工做目錄分離的。CVS經過多種方式訪問資源庫。每種方法有不一樣目錄表示形式。
版本(Revision)
每個文件的各個版本都不相同,形如1.1, 1.2.1,通常1.1是該文件的第一個revision,後面的一個將自動增長最右面的一個整數,好比1.2, 1.3, 1.4...有時候會出現1.3.2.2,緣由見後。revision老是偶數個數字。通常狀況下將revision看做時CVS本身內部的一個編號,而tag則能夠標誌用戶的特定信息。
標籤(Tag)
用符號化的表示方法標誌文件特定revision的信息。一般不須要對某一個孤立的文件做tag,而是對全部文件同時做一個tag,之後用戶能夠僅向特定tag的文件提交或者checkout。另一個做用是在發佈軟件的時候表示哪些文件及其哪一個版本是可用的;各文件不一樣revision能夠包括在一個tag中。若是命名一個已存在的tag默認將不會覆蓋原來的;
分支(Branch)
當用戶修改一個branch時不會對另外的branch產生任何影響。能夠在適當的時候經過合併的方法將兩個版本合起來;branch老是在當前revision後面加上一個偶數整數(從2開始,到0結束),因此branch老是奇數個數字,好比1.2後面branch爲1.2.2,該分支下revision可能爲1.2.2.1,1.2.2.2,...
衝突(Conflct)
徹底是純文本的衝突,不包含邏輯上的矛盾。通常是一份文件,A作了改動,B在A提交以前也作了改動,這樣最後誰commit就會出現衝突,須要手工解決衝突再提交。緩存
Check Out(檢出)
把源文件從cvs源代碼倉庫中取出,缺省的版本是最新的版本,你也能夠選擇指定的版本。在每次更改源代碼以前,須要Check Out最新的版本,再起基礎之上對源代碼進行修改。將代碼目錄checkout到指定目錄下,全部文件都是read-write。
Check In(檢入)
把源代碼加入到cvs源代碼倉庫中,每個添加進代碼庫中的文件的版本是 1.1。之後每次修改文件從新ci之後,此文件的版本遞增爲1.2 ,1.3.……。在每次對源代碼修改以後,須要Check In,提交最新版本的源代碼。
Synchronize with Repository(與資源庫同步,簡稱同步)
使本地更改與資源庫同步,它會列出本地和資源庫之間不一樣的全部文件。
Add to Version Control
將新的文件加入到版本控制之中。
Add to .cvsIgnore
將文件設置到版本控制以外,這樣該文件或目錄中的文件的更改在CVS中不可見,即便同步也沒法發現。安全
1、 同步(Synchronize)
就是將本地更改與服務器同步,同步以後能夠清晰的看到上一撿出(Check Out)版本以後本地、服務器上的最新改動。這是很是有用的,特別是敏捷開發,強調集體擁有代碼。有了同步功能,你能夠全局把握項目的代碼,能夠很方便的跟蹤公共模塊代碼的任何改動。
同步以後,它有四種Mode能夠選擇,從左到右分別爲:
Incoming Mode:表示修改是來自服務器,對應於更新(update)操做。
Outgoing Mode:表示修改是來自本地,對應提交(commit)操做。
Incoming/ Outgoing Mode:本地和服務器修改都在該模式(Mode)中顯示。
Conflicts Mode:顯示本地和服務器修改的衝突文件。
2、 更新(update)
比較簡單,選擇Incoming Mode,再選中要更新的文件,右鍵選擇update操做。
3、 解決衝突併合並(solve conflct and merge)
若是有衝突文件,衝突文件不能更新。你必須先解決衝突再操做。選中衝突的文件,再點右鍵選擇"Open in Compare Editor",用比較工具打開該文件。以下圖:
4、 提交(commit)
更新服務器代碼,解決衝突以後,首先要查看本地文件修改以後是否有錯誤。若是有,固然首先解決錯誤,再提交。服務器
SVN(Subversion),是一個開源的版本控制系統,較於CVS,採用了分支管理系統,設計目標就是取代CVS。文件保存在中央倉庫,除了能記住文件和目錄的每次修改外,版本庫就像普通的文件服務器,說的簡單一點SVN就是用於多我的共同開發同一個項目,共用資源的目的。管理者能夠將文件恢復到過去的版本,而且經過檢查歷史知道誰對數據作了哪些修改。能夠看做是「時間機器」。網絡
SVN的版本庫能夠經過網絡訪問,從而使用戶能夠在不一樣的電腦上操做。容許用戶在各自的空間裏修改和管理同一組數據,修改再也不是單線進行(一個一個進行)。開發速度大大提升。此外,全部的工做都已版本化,沒必要擔憂因爲錯位的更改而影響軟件質量,若是出現不正確的更改,只要撤銷那一次更改操做。app
SVN集中式代碼管理的核心是服務器,全部開發者在開始新一天的工做以前必須從服務器獲取代碼,而後開發,最後解決衝突,提交。全部的版本信息都放在服務器上。若是脫離了服務器,開發者基本上能夠說是沒法工做的。下面舉例說明:
開始新一天的工做:
一、從服務器下載項目組最新代碼。
二、進入本身的分支,進行工做,每隔一個小時向服務器本身的分支提交一次代碼(不少人都有這個習慣。由於有時候本身對代碼改來改去,最後又想還原到前一個小時的版本,或者看看前一個小時本身修改了哪些代碼,就須要這樣作了)。
三、下班時間快到了,把本身的分支合併到服務器主分支上,一天的工做完成,並反映給服務器。
這就是經典的svn工做流程,從流程上看,有很多缺點,但也有優勢。編輯器
優勢
一、管理方便,邏輯明確,符合通常人思惟習慣。
二、易於管理,集中式服務器更能保證安全性。
三、代碼一致性很是高。
四、適合開發人數很少的項目開發。
五、大部分軟件配置管理的大學教材都是使用svn和vss。分佈式
缺點
一、服務器壓力太大,數據庫容量暴增。
二、若是不能鏈接到服務器上,基本上不能夠工做,看上面第二步,若是服務器不能鏈接上,就不能提交,還原,對比等等。
三、不適合開源開發(開發人數很是很是多,可是Google app engine就是用svn的)。可是通常集中式管理的有很是明確的權限管理機制(例如分支訪問限制),能夠實現分層管理,從而很好的解決開發人數衆多的問題。
1.將文件檢出checkout到本地目錄
svn checkout path(path是服務器上的目錄)
簡寫:svn co
簡寫:svn co
二、往版本庫中添加新的文件
svn add file
3.將改動的文件提交到版本庫
svn commit -m 「LogMessage」 [-N] [--no-unlock] PATH(若是選擇了保持鎖,就使用–no-unlock開關)
簡寫:svn ci
四、加鎖/解鎖
svn lock -m 「LockMessage」 [--force] PATH
svn unlock PATH
五、更新到某個版本
svn update -r m path
簡寫:svn up
六、查看文件或者目錄狀態
1)svn status path(目錄下的文件和子目錄的狀態,正常狀態不顯示)
2)svn status -v path(顯示文件和子目錄狀態)
簡寫:svn st
七、刪除文件
svn delete path -m 「delete test fle」
簡寫:svn (del, remove, rm)
八、查看日誌
svn log path
九、查看文件詳細信息
svn info path
十、比較差別
svn diff path(將修改的文件與基礎版本比較)
svn diff -r m:n path(對版本m和版本n比較差別)
簡寫:svn di
十一、將兩個版本之間的差別合併到當前文件
svn merge -r m:n path
十二、SVN 幫助
svn help
svn help ci
1三、版本庫下的文件和目錄列表
svn list path 顯示path目錄下的全部屬於版本庫的文件和目錄簡寫:svn ls
1四、建立歸入版本控制下的新目錄
svn mkdir 建立歸入版本控制下的新目錄。
1六、代碼庫URL變動
svn switch (sw): 更新工做副本至不一樣的URL。
用法:
一、switch URL [PATH]
更新你的工做副本,映射到一個新的URL,其行爲跟「svn update」很像,也會將 服務器上文件與本地文件合併。這是將工做副本對應到同一倉庫中某個分支或者標記的方法。
二、switch --relocate FROM TO [PATH...]
改寫工做副本的URL元數據,以反映單純的URL上的改變。當倉庫的根URL變更 (好比方案名或是主機名稱變更),可是工做副本仍舊對映到同一倉庫的同一目錄時使用 這個命令更新工做副本與倉庫的對應關係。
1七、解決衝突
svn resolved: 移除工做副本的目錄或文件的「衝突」狀態。
用法: resolved PATH...
注意: 本子命令不會依語法來解決衝突或是移除衝突標記;它只是移除衝突的相關文件,而後讓 PATH 能夠再次提交。
1八、輸出指定文件或URL的內容。
svn cat 目標[@版本]...若是指定了版本,將從指定的版本開始查找。
svn cat -r PREV filename > filename (PREV 是上一版本,也能夠寫具體版本號,這樣輸出結果是能夠提交的)
Git是一款免費,開源的分佈式版本控制系統,有效、高速的處理大小項目版本管理。
Git不只僅是版本控制系統,也是一個內容管理系統(CMS),工做管理系統。
Git工做區、暫緩區、和版本庫概念
工做區:就是你在電腦裏能看到的目錄。
暫緩區:英文名index 通常存放在.git目錄下的index文件中,因此咱們把暫存區有時也叫索引(index)。
版本庫:工做區有一個隱藏目錄.git 是Git的版本庫。
三者之間的關係以下:
圖中左側爲工做區,右側爲版本庫。在版本庫中標記爲 "index" 的區域是暫存區(stage, index),標記爲 "master" 的是 master 分支所表明的目錄樹。
圖中咱們能夠看出此時 "HEAD" 實際是指向 master 分支的一個"遊標"。因此圖示的命令中出現 HEAD 的地方能夠用 master 來替換。
圖中的 objects 標識的區域爲 Git 的對象庫,實際位於 ".git/objects" 目錄下,裏面包含了建立的各類對象及內容。
當對工做區修改(或新增)的文件執行 "git add" 命令時,暫存區的目錄樹被更新,同時工做區修改(或新增)的文件內容被寫入到對象庫中的一個新的對象中,而該對象的ID被記錄在暫存區的文件索引中。
當執行提交操做(git commit)時,暫存區的目錄樹寫到版本庫(對象庫)中,master 分支會作相應的更新。即 master 指向的目錄樹就是提交時暫存區的目錄樹。
當執行 "git reset HEAD" 命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,可是工做區不受影響。
當執行 "git rm --cached <file>" 命令時,會直接從暫存區刪除文件,工做區則不作出改變。
當執行 "git checkout ." 或者 "git checkout -- <file>" 命令時,會用暫存區所有或指定的文件替換工做區的文件。這個操做很危險,會清除工做區中未添加到暫存區的改動。
當執行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令時,會用 HEAD 指向的 master 分支中的所有或者部分文件替換暫存區和以及工做區中的文件。這個命令也是極具危險性的,由於不但會清除工做區中未提交的改動,也會清除暫存區中未提交的改動。
通常工做流程以下:
1.克隆Git 資源做爲工做目錄。
2.在克隆的資源上添加或修改文件
3.若是其餘人修改了,能夠更新資源
4.在提交前查看修改
5.提交修改
6.修改完成後,若是發現錯誤,能夠撤回提交再次修改並提交
git init 初始化一個Git 倉庫,Git的不少命令都須要在Git的倉庫裏運行。
在執行git init 命令後,Git倉庫會生成一個.git 目錄,該目錄包含了資源的全部元數據,其餘的項目目錄不變。
使用當前目錄做爲Git倉庫:
git init (會生成一個.git 目錄)
使用指定目錄做爲Git倉庫
git init newrepo
初始化後,會在newrepo目錄下出現一個名爲.git的目錄,全部Git 須要的數據和資源都存放在這個目錄中。
若是當前目錄下有好多個文件想要歸入版本控制,須要先用git add 命令 告訴git 開始對這些文件進行跟蹤,而後提交
git add a
git add b
git add c
git commit -m '初始化項目版本'
git clone
使用git clone 從現有Git 倉庫中拷貝項目
git clone
若是須要克隆到指定的目錄,可使用
git clone repo directory
repo:Git 倉庫
directory:本地目錄
git init
用git init 在目錄中建立新的Git 倉庫。是本地化的
在目錄中執行git init ,就能夠建立一個Git 倉庫了。
如:
mkdir newDir
cd newDir/
git init
能夠在項目中生成.git這個子目錄,這就是Git倉庫,全部關於項目的快照數據都存放在這裏。
git clone
使用git clone 拷貝一個Git 倉庫到本地,能夠查看或者進行修改。
git clone [url]
url 爲複製的項目連接。
git add能夠將該文件添加到緩存。
$ touch README
$ touch hello.php
$ ls README hello.php
$ git status -s ?? README ?? hello.php $
git touch 用於建立文件
git status -s 用於查看項目的當前狀態。
git add hello.php README
git add 命令用於添加文件
如今再次執行git status ,就能夠看到這兩個文件已經添加上去了。
$ git status -s
A README
A hello.php
$
新項目中,添加全部文件很廣泛,可使用 git add .(中間有一個空格) 命令來添加當前項目的全部文件
git add .
再次使用git status -s 查看狀態
$ git status -s
A 1.txt
A 2.txt
A README
A hello.txt
A ssm
如今修改README文件:在README文件中添加 #Runoob Git測試字樣,保存並退出。
再次執行git status -s
$ git status -s
A 1.txt
A 2.txt
AM README
A hello.txt
A ssm
AM狀態的意思是,這個文件在咱們將它添加到緩存以後有改動,改動後咱們再執行git add命令將它添加到緩存中。
git add .
當咱們要講修改的內容包含在即將提交的快照裏面的時候,須要執行 git add 。
$ git status -s
A 1.txt
A 2.txt
A README
A hello.txt
A ssm
git status
git status能夠查看在你上次提交以後是否有修改 git status -s 用於得到簡短的結果輸出。
git status on branch master
$ git status on branch master
On branch master
Initial commit
nothing to commit (create/copy files and use "git add" to track)
git diff
git diff能夠查看執行git status 的結果的詳細信息。
git diff 命令顯示已寫入緩存與已修改但還沒有寫入緩存的改動的區別。 git diff 主要有兩個使用場景:
還沒有緩存的改動:git diff
查看已緩存的改動: git diff --cached
查看已緩存的與未緩存的全部改動:git diff HEAD
顯示摘要而非整個diff git diff --stat
git status 顯示上次提交更新後或者寫入緩存的改動,而git diff 一行一行的顯示這些改動具體是啥。
git commit
使用git add 命令將想要快照的內容寫入緩存區,而執行git commit 是將緩存區內容添加到倉庫中。
Git 爲每個提交都記錄名字和郵箱,因此第一步須要配置用戶名和郵箱地址
$ git config --global user.name 'runoob'
$ git config --global user.email test@runoob.com
而後寫入緩存,並提交對文件的全部改動。使用-m 選項在命令行中提供註釋
$ git add hello.php
$ git status -s
A README A hello.php
$ $ git commit -m '第一次版本提交' [master (root-commit) d32cf1f] 第一次版本提交
2 files changed, 4 insertions(+)
create mode 100644 README
create mode 100644 hello.php
如今已近記錄好快照,若是再執行git status
$ git status
On branch master
nothing to commit, working tree clean
咱們在最近一次提交後,沒有作任何改動,是一個working directory clean 乾淨的工做目錄
若是沒有設置-m 選項,Git 會嘗試打開一個編輯器以填寫提交信息,若是Git 在你對他的配置中找不到信息,默認會打開Vim ,屏幕會這樣。。
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master # Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: hello.php
# ~ ~ ".git/COMMIT_EDITMSG" 9L, 257C
若是以爲git add 提交緩存的流程太繁瑣,Git 可使用 -a 選項跳過這一步,
git commit -a
$ git commit -a
On branch master
nothing to commit, working tree clean
git reset HEAD
git reset HEAD命令用於取消已緩存內容。
git reset HEAD 能夠取消以前git add 添加,但不但願包含在下一提交快照中的緩存。
git rm
git rm 會將條目從緩存區移出,。
git rm file 會將文件從緩存區和硬盤中(工做目錄)刪除。
git mv
git mv命令用於移動或者重命名一個文件,目錄,軟鏈接。
幾乎每種版本控制系統都以某種形式支持分支。使用分支意味着能夠從開發主線上分離開來,而後在不影響主線的同時繼續工做。
Git 的優勢就在於它的分支模型。
建立分支:git branch(branchName)
切換分支:git checkout(branchName)
當切換分支的時候,Git 會用該分支的最後提交的快照替換你電腦上的工做目錄的內容,因此多個分支不須要多個目錄。
合併分支: git merge
能夠屢次合併到統一分支,也能夠選擇在合併後直接刪除被併入的分支。
列出分支:
git branch
沒有參數時,git branch 會列出你在本地的分支
$ git branch
* master
意思是:有一個叫master的分支,而且該分支是當前分支,當執行git init 的時候,缺省狀況下Git 就會建立master 分支,可使用git branch (branchName) 建立一個新的分支。
git checkout -b(branchName)
git checkout -b 命令用來建立新分支並當即切換到該分支下,從而在該分支進行操做
刪除分支
git branch -d(branchname)