SVN & Git
PS:本文所有$
符號之后為在終端中執行的命令。
版本控制系統
版本控制
版本控制(Version Control)的作用是追蹤文件的變化。為什么需要版本控制?簡單說,就是當你出錯了,可以很容易地回到沒出錯時的狀態。
你可能已經在不知不覺中,布置了自己的版本控制系統。比如,創建了類似下面這樣的文件名:
- 論文_0510.doc
- 論文_0514.doc
- 論文_0521.doc
- 論文_修改版.doc
- 論文_最終不修改版.doc
這就是軟件中為什么有"Save As"命令的原因。它使得你可以在不破壞源文件的基礎上,得到一個類似的新文件。文件的多版本保存是一個常見問題,通常的解決辦法是這樣的:
- 做一個文件備份(比如Document.old.txt)。
- 在文件名中加入版本號或日期(比如Document_V1.txt,DocumentMarch2007.txt)。
- 在多人編輯的環境下,共享一個文件目錄,并且要求每個人編輯完以后,在文件上做出標識。
什么是版本控制系統(VCS)?
大型的、頻繁修改的、多人編寫的軟件項目,需要一個版本控制系統(簡稱VCS,行話叫做"文件數據庫"),追蹤文件的變化,避免出現混亂。
一次典型的使用過程是這樣的:
愛麗絲add一個文件(list.txt)進入repo。然后,她又把這個文件check out,做了一次編輯(在文件中加入milk這個單詞)。接著,她將修改后的文件check in,并附有一條checking message("加入了新的條目")。第二天早上,鮑勃update了他本地的working set,看到了list.txt的最新修訂版,其中包含了單詞"milk"。如果他使用changelog或diff,都可以發現前一天愛麗絲加入"milk"這個詞。
網上有許多VCS軟件可供選擇,并且都有詳細的教程或手冊,比如SVN、CVS、RCS、Git、Perforce等等。
版本庫
版本庫又名倉庫,英文名repository,你可以簡單理解成一個目錄,這個目錄里面的所有文件都可以被版本控制系統管理起來,每個文件的修改、刪除,都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以“還原”。
SVN
在Mac環境下,由于Mac自帶了SVN的服務器端和客戶端功能,所以我們可以在不裝任何第三方軟件的前提下使用SVN功能,不過還需做一下簡單的配置。
為什么使用SVN
- 進行權限管理,針對不同的人,開放不同的權限。比如Alex是進行A項目的,Bob進行B項目的,那么SVN可以有效的管理每個人看到的項目,Alex不可能獲得Bob的項目,同樣Bob也不可能獲得Alex的項目。
- 對于代碼進行追蹤,代碼不會遺失。不如今天代碼修改亂了,需要恢復到某一天的,那么我們只需要選擇一下恢復的日期即可進行恢復。
搭建SVN服務器
1. 創建代碼倉庫,存儲客戶端上傳的代碼
先在~/Desktop
目錄(這個目錄可以是任意非中文路徑)新建一個svn目錄,以后可以在svn目錄下創建多個倉庫目錄。
打開終端,切換到該目錄cd ~/Desktop/svn
,創建一個learnsvn
倉庫,輸入命令:svnadmin create ./learnsvn
,執行成功后,會發現在該目錄下多了一個LimitFree目錄。
2. 配置SVN的用戶權限
主要是修改./learnsvn/conf目錄下的三個文件
-
打開svnserve.conf,將下列配置項前面的#和空格都去掉
# anon-access = read # auth-access = write # password-db = passwd # authz-db = authz
anon-access = read代表匿名訪問的時候是只讀的,若改為anon-access = none代表禁止匿名訪問,需要帳號密碼才能訪問
-
打開passwd,在[users]下面添加帳號和密碼
[users] # harry = harryssecret # sally = sallyssecret chaosky = 123 student = 123456
帳號是chaosky,密碼是123
-
打開authz,配置用戶組和權限
我們可以將在passwd里添加的用戶分配到不同的用戶組里,以后的話,就可以對不同用戶組設置不同的權限,沒有必要對每個用戶進行單獨設置權限。
在[groups]下面添加組名和用戶名,多個用戶之間用逗號(,)隔開
[groups] topgroup=chaosky,student
說明chaosky和student都是屬于topgroup這個組的,接下來再進行權限配置。
使用[/]代表svn服務器中的所有資源庫
[/] @topgroup = rw
上面的配置說明topgroup這個組中的所有用戶對所有資源庫都有讀寫(rw)權限,組名前面要用@
如果是用戶名,不用加@,比如chaosky這個用戶有讀寫權限
[/] chaosky = rw
3. 啟動SVN服務器
在終端輸入命令:svnserve -d -r ~/Desktop/svn
或svnserve -d -r ~/Desktop/svn/learnsvn
沒有任何提示就說明啟動成功了
4. 關閉SVN服務器
打開活動監視器,輸入svnserve,強制退出進程。
使用SVN客戶端功能
SVN客戶端有兩種使用方式,命令行和GUI界面軟件(CornerStone)
命令行工具
usage: svn <subcommand> [options] [args]
Subversion command-line client.
Type 'svn help <subcommand>' for help on a specific subcommand.
Type 'svn --version' to see the program version and RA modules
or 'svn --version --quiet' to see just the version number.
Most subcommands take file and/or directory arguments, recursing
on the directories. If no arguments are supplied to such a
command, it recurses on the current directory (inclusive) by default.
Available subcommands:
add
auth
blame (praise, annotate, ann)
cat
changelist (cl)
checkout (co)
cleanup
commit (ci)
copy (cp)
delete (del, remove, rm)
diff (di)
export
help (?, h)
import
info
list (ls)
lock
log
merge
mergeinfo
mkdir
move (mv, rename, ren)
patch
propdel (pdel, pd)
propedit (pedit, pe)
propget (pget, pg)
proplist (plist, pl)
propset (pset, ps)
relocate
resolve
resolved
revert
status (stat, st)
switch (sw)
unlock
update (up)
upgrade
Subversion is a tool for version control.
For additional information, see http://subversion.apache.org/
CornerStone
添加代碼倉庫
填寫SVN倉庫信息
基本操作
checkout(檢出)
add(添加文件)
delete(刪除文件)
modify (修改文件)
commit(提交)
update(更新)
resolve conflict(解決沖突)
revert(恢復初始狀態)
Git
安裝Git
直接從AppStore安裝Xcode,Xcode集成了Git,不過默認沒有安裝,你需要運行命令xcode-select --install
安裝“Command Line Tools”,點“Install”就可以完成安裝了。
創建版本庫
-
選擇一個合適的地方,創建一個空目錄:
$ mkdir learngit $ cd learngit
-
通過
git init
命令把這個目錄變成Git可以管理的倉庫:$ git init Initialized empty Git repository in /Users/Chaosky/Desktop/learngit/.git/
瞬間Git就把倉庫建好了,而且告訴你是一個空的倉庫(empty Git repository),細心的讀者可以發現當前目錄下多了一個.git的目錄,這個目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄里面的文件,不然改亂了,就把Git倉庫給破壞了。
把文件添加到版本庫
-
編寫一個README.md文件,內容如下:
Git is a version control system. Git is free software.
一定要放到learngit目錄下(子目錄也行),因為這是一個Git倉庫,放到其他地方Git再厲害也找不到這個文件。
-
用命令
git add
告訴Git,把文件添加到倉庫:$ git add readme.txt
執行上面的命令,沒有任何顯示,這就對了,Unix的哲學是“沒有消息就是好消息”,說明添加成功。
-
用命令
git commit
告訴Git,把文件提交到倉庫:$ git commit -m "wrote a readme file" [master (root-commit) cb926e7] wrote a readme file 1 file changed, 2 insertions(+) create mode 100644 readme.txt
簡單解釋一下git commit命令,-m后面輸入的是本次提交的說明,可以輸入任意內容,當然最好是有意義的,這樣你就能從歷史記錄里方便地找到改動記錄。
git commit命令執行成功后會告訴你,1個文件被改動(我們新添加的readme.txt文件),插入了兩行內容(readme.txt有兩行內容)。
為什么Git添加文件需要add,commit一共兩步呢?因為commit可以一次提交很多文件,所以你可以多次add不同的文件,比如:
$ git add file1.txt $ git add file2.txt file3.txt $ git commit -m "add 3 files."
工作區和暫存區
-
工作區(Working Directory)
就是你在電腦里能看到的目錄。
-
版本庫(Repository)
Git的版本庫里存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區,還有Git為我們自動創建的第一個分支master,以及指向master的一個指針叫HEAD。
前面講了我們把文件往Git版本庫里添加的時候,是分兩步執行的:
第一步是用
git add
把文件添加進去,實際上就是把文件修改添加到暫存區;版本庫狀態第二步是用
git commit
提交更改,實際上就是把暫存區的所有內容提交到當前分支。版本庫狀態你可以簡單理解為,需要提交的文件修改通通放到暫存區,然后,一次性提交暫存區的所有修改。
?
版本庫管理
-
git status
查看倉庫當前的狀態,要隨時掌握工作區的狀態,使用git status命令。
-
git diff
如果git status告訴你有文件被修改過,用git diff可以查看修改內容。
-
git log
顯示從最近到最遠的提交日志。在Git中,用HEAD表示當前版本,也就是最新的提交,上一個版本就是HEAD^ ,上上一個版本就是HEAD^^ ,當然往上100個版本寫100個^比較容易數不過來,所以寫成HEAD~100。
-
git reset --hard commit_id
在版本的歷史之間進行切換,
commit_id
為提交版本的id。 -
git reflog
用來記錄你的每一次命令
-
撤銷修改
場景1:當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令
git checkout -- README.md
。場景2:當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令
git reset HEAD README.md
,就回到了場景1,第二步按場景1操作。 -
git rm
用于刪除一個文件。如果一個文件已經被提交到版本庫,那么你永遠不用擔心誤刪,但是要小心,你只能恢復文件到最新版本,你會丟失最近一次提交后你修改的內容。
遠程倉庫
分布式版本控制系統通常也有一臺充當“中央服務器”的電腦,而充當"中央服務器"角色的倉庫就是遠程倉庫,但這個服務器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣干活,只是交換修改不方便而已。
如果有自己的私有倉庫地址,則無需執行下面幾個操作。
-
注冊遠程倉庫賬號
-
Git@OSC:開源中國Git托管平臺
-
Github:世界最大的Git項目托管平臺
-
Coding:國內新興的Git托管平臺
-
-
添加公鑰到Git托管平臺
-
生成公鑰
SSH Keys:SSH key 可以讓你在你的電腦和 Git托管平臺之間建立安全的加密連接。
你可以按如下命令來生成sshkey:
$ ssh-keygen -t rsa -C "xxxxx@xxxxx.com"
其中
xxxxx@xxxxx.com
需要填寫郵箱信息生成SSH key時,如果不清楚需要輸入的信息,可以全部輸入Enter鍵。
-
查看你的public key,并把他添加到Git托管平臺
$ cat ~/.ssh/id_rsa.pub
具體添加的位置,查看具體的托管平臺。一般來說,在個人資料中可以找到
SSH-KEYS
類似的字樣就是添加公鑰的地方。 -
測試是否添加成功
測試Git@OSC輸入命令:
$ ssh -T git@git.oschina.net Welcome to Git@OSC, yourname!
測試Github輸入命令:
$ ssh -T git@github.com Hi chaoskyme! Youve successfully authenticated, but GitHub does not provide shell access.
生成SSH key只需要生成一次,不同的網站再將公鑰拷貝到網站上即可。
-
-
在Git托管平臺上創建項目
-
添加遠程倉庫
關聯一個遠程倉庫命令:
$ git remote add origin git@server-name:path/repo-name.git
其中
origin
表示遠程倉庫的別名,默認為origin
git@server-name:path/repo-name.git
表示項目在Git托管平臺上的ssh 地址。關聯遠程倉庫只需要執行上面的命令一次即可。
關聯后,第一次推送master分支的所有內容命令:
$ git push -u origin master
此后,每次本地提交后,只要有必要,推送最新修改就可以使用命令:
$ git push origin master
分布式版本系統的最大好處之一是在本地工作完全不需要考慮遠程庫的存在,也就是有沒有聯網都可以正常工作,而SVN在沒有聯網的時候是拒絕干活的!當有網絡的時候,再把本地提交推送一下就完成了同步,真是太方便了!
-
克隆遠程倉庫
$ git clone git@server-name:path/repo-name.git <repo-name>
-
從遠程分支獲取最新版本到本地,有2個命令
-
git fetch:相當于是從遠程獲取最新版本到本地,不會自動merge
$ git fetch origin master $ git log -p master..origin/master $ git merge origin/master
以上命令的含義:
首先從遠程的origin的master主分支下載最新的版本到origin/master分支上;
然后比較本地的master分支和origin/master分支的差別;
最后進行合并。
-
git pull:相當于是從遠程獲取最新版本并merge到本地
$ git pull origin master
上述命令其實相當于git fetch 和 git merge
在實際使用中,git fetch更安全一些
因為在merge前,我們可以查看更新情況,然后再決定是否合并
-
分支管理
Git鼓勵大量使用分支:
查看分支:git branch
創建分支:git branch <name>
切換分支:git checkout <name>
創建+切換分支:git checkout -b <name>
合并某分支到當前分支:git merge <name>
刪除分支:git branch -d <name>
當Git無法自動合并分支時,就必須首先解決沖突。解決沖突后,再提交,合并完成。
用git log --graph
命令可以看到分支合并圖。
推送分支,就是把該分支上的所有本地提交推送到遠程庫。推送時,要指定本地分支,這樣,Git就會把該分支推送到遠程庫對應的遠程分支上:
$ git push origin master
標簽管理
git tag <name>
用于新建一個標簽,默認為HEAD,也可以指定一個commit id;
git tag -a <tagname> -m "blablabla..."
可以指定標簽信息;
git tag -s <tagname> -m "blablabla..."
可以用PGP簽名標簽;
git tag
可以查看所有標簽
git push origin <tagname>
可以推送一個本地標簽;
git push origin —tags
可以推送全部未推送過的本地標簽;
git tag -d <tagname>
可以刪除一個本地標簽;
git push origin :refs/tags/<tagname>
可以刪除一個遠程標簽。
Git常用命令速查表

參考文章
- http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
- 參考書籍:《Git權威指南》
- http://backlogtool.com/git-guide/cn/
SVN vs Git (集中式 vs 分布式)
先說集中式版本控制系統,版本庫是集中存放在中央服務器的,而干活的時候,用的都是自己的電腦,所以要先從中央服務器取得最新的版本,然后開始干活,干完活了,再把自己的活推送給中央服務器。中央服務器就好比是一個圖書館,你要改一本書,必須先從圖書館借出來,然后回到家自己改,改完了,再放回圖書館。
集中式版本控制系統最大的毛病就是必須聯網才能工作。
那分布式版本控制系統與集中式版本控制系統有何不同呢?首先,分布式版本控制系統根本沒有“中央服務器”,每個人的電腦上都是一個完整的版本庫,這樣,你工作的時候,就不需要聯網了,因為版本庫就在你自己的電腦上。既然每個人電腦上都有一個完整的版本庫,那多個人如何協作呢?比方說你在自己電腦上改了文件A,你的同事也在他的電腦上改了文件A,這時,你們倆之間只需把各自的修改推送給對方,就可以互相看到對方的修改了。
和集中式版本控制系統相比,分布式版本控制系統的安全性要高很多,因為每個人電腦里都有完整的版本庫,某一個人的電腦壞掉了不要緊,隨便從其他人那里復制一個就可以了。而集中式版本控制系統的中央服務器要是出了問題,所有人都沒法干活了。
在實際使用分布式版本控制系統的時候,其實很少在兩人之間的電腦上推送版本庫的修改,因為可能你們倆不在一個局域網內,兩臺電腦互相訪問不了,也可能今天你的同事病了,他的電腦壓根沒有開機。因此,分布式版本控制系統通常也有一臺充當“中央服務器”的電腦,但這個服務器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣干活,只是交換修改不方便而已。
。