SVN & Git
PS:本文所有$
符號之后為在終端中執(zhí)行的命令夸浅。
版本控制系統(tǒng)
版本控制
版本控制(Version Control)的作用是追蹤文件的變化椎瘟。為什么需要版本控制?簡單說雹舀,就是當你出錯了淑廊,可以很容易地回到?jīng)]出錯時的狀態(tài)凳鬓。
你可能已經(jīng)在不知不覺中,布置了自己的版本控制系統(tǒng)泽腮。比如泊愧,創(chuàng)建了類似下面這樣的文件名:
- 論文_0510.doc
- 論文_0514.doc
- 論文_0521.doc
- 論文_修改版.doc
- 論文_最終不修改版.doc
這就是軟件中為什么有"Save As"命令的原因。它使得你可以在不破壞源文件的基礎(chǔ)上盛正,得到一個類似的新文件删咱。文件的多版本保存是一個常見問題,通常的解決辦法是這樣的:
- 做一個文件備份(比如Document.old.txt)豪筝。
- 在文件名中加入版本號或日期(比如Document_V1.txt痰滋,DocumentMarch2007.txt)摘能。
- 在多人編輯的環(huán)境下,共享一個文件目錄敲街,并且要求每個人編輯完以后团搞,在文件上做出標識。
什么是版本控制系統(tǒng)(VCS)多艇?
大型的逻恐、頻繁修改的、多人編寫的軟件項目峻黍,需要一個版本控制系統(tǒng)(簡稱VCS复隆,行話叫做"文件數(shù)據(jù)庫"),追蹤文件的變化姆涩,避免出現(xiàn)混亂挽拂。
一次典型的使用過程是這樣的:
愛麗絲add一個文件(list.txt)進入repo。然后骨饿,她又把這個文件check out亏栈,做了一次編輯(在文件中加入milk這個單詞)。接著宏赘,她將修改后的文件check in绒北,并附有一條checking message("加入了新的條目")。第二天早上察署,鮑勃update了他本地的working set闷游,看到了list.txt的最新修訂版,其中包含了單詞"milk"箕母。如果他使用changelog或diff储藐,都可以發(fā)現(xiàn)前一天愛麗絲加入"milk"這個詞俱济。
網(wǎng)上有許多VCS軟件可供選擇嘶是,并且都有詳細的教程或手冊,比如SVN蛛碌、CVS聂喇、RCS、Git蔚携、Perforce等等希太。
版本庫
版本庫又名倉庫,英文名repository酝蜒,你可以簡單理解成一個目錄誊辉,這個目錄里面的所有文件都可以被版本控制系統(tǒng)管理起來,每個文件的修改亡脑、刪除堕澄,都能跟蹤邀跃,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以“還原”蛙紫。
SVN
在Mac環(huán)境下拍屑,由于Mac自帶了SVN的服務(wù)器端和客戶端功能,所以我們可以在不裝任何第三方軟件的前提下使用SVN功能坑傅,不過還需做一下簡單的配置僵驰。
為什么使用SVN
- 進行權(quán)限管理,針對不同的人唁毒,開放不同的權(quán)限蒜茴。比如Alex是進行A項目的,Bob進行B項目的枉证,那么SVN可以有效的管理每個人看到的項目矮男,Alex不可能獲得Bob的項目,同樣Bob也不可能獲得Alex的項目室谚。
- 對于代碼進行追蹤毡鉴,代碼不會遺失。不如今天代碼修改亂了秒赤,需要恢復到某一天的猪瞬,那么我們只需要選擇一下恢復的日期即可進行恢復。
搭建SVN服務(wù)器
1. 創(chuàng)建代碼倉庫入篮,存儲客戶端上傳的代碼
先在~/Desktop
目錄(這個目錄可以是任意非中文路徑)新建一個svn目錄陈瘦,以后可以在svn目錄下創(chuàng)建多個倉庫目錄。
打開終端潮售,切換到該目錄cd ~/Desktop/svn
痊项,創(chuàng)建一個learnsvn
倉庫,輸入命令:svnadmin create ./learnsvn
酥诽,執(zhí)行成功后鞍泉,會發(fā)現(xiàn)在該目錄下多了一個LimitFree目錄。
2. 配置SVN的用戶權(quán)限
主要是修改./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,配置用戶組和權(quán)限
我們可以將在passwd里添加的用戶分配到不同的用戶組里恒界,以后的話睦刃,就可以對不同用戶組設(shè)置不同的權(quán)限,沒有必要對每個用戶進行單獨設(shè)置權(quán)限十酣。
在[groups]下面添加組名和用戶名涩拙,多個用戶之間用逗號(,)隔開
[groups] topgroup=chaosky,student
說明chaosky和student都是屬于topgroup這個組的枣宫,接下來再進行權(quán)限配置。
使用[/]代表svn服務(wù)器中的所有資源庫
[/] @topgroup = rw
上面的配置說明topgroup這個組中的所有用戶對所有資源庫都有讀寫(rw)權(quán)限吃环,組名前面要用@
如果是用戶名也颤,不用加@,比如chaosky這個用戶有讀寫權(quán)限
[/] chaosky = rw
3. 啟動SVN服務(wù)器
在終端輸入命令:svnserve -d -r ~/Desktop/svn
或svnserve -d -r ~/Desktop/svn/learnsvn
沒有任何提示就說明啟動成功了
4. 關(guān)閉SVN服務(wù)器
打開活動監(jiān)視器郁轻,輸入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(恢復初始狀態(tài))
Git
安裝Git
直接從AppStore安裝Xcode竭沫,Xcode集成了Git,不過默認沒有安裝骑篙,你需要運行命令xcode-select --install
安裝“Command Line Tools”蜕提,點“Install”就可以完成安裝了。
創(chuàng)建版本庫
-
選擇一個合適的地方靶端,創(chuàng)建一個空目錄:
$ mkdir learngit $ cd learngit
-
通過
git init
命令把這個目錄變成Git可以管理的倉庫:$ git init Initialized empty Git repository in /Users/Chaosky/Desktop/learngit/.git/
瞬間Git就把倉庫建好了谎势,而且告訴你是一個空的倉庫(empty Git repository),細心的讀者可以發(fā)現(xiàn)當前目錄下多了一個.git的目錄杨名,這個目錄是Git來跟蹤管理版本庫的脏榆,沒事千萬不要手動修改這個目錄里面的文件,不然改亂了台谍,就把Git倉庫給破壞了须喂。
把文件添加到版本庫
-
編寫一個README.md文件,內(nèi)容如下:
Git is a version control system. Git is free software.
一定要放到learngit目錄下(子目錄也行)趁蕊,因為這是一個Git倉庫坞生,放到其他地方Git再厲害也找不到這個文件。
-
用命令
git add
告訴Git掷伙,把文件添加到倉庫:$ git add readme.txt
執(zhí)行上面的命令是己,沒有任何顯示,這就對了炎咖,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后面輸入的是本次提交的說明俄烁,可以輸入任意內(nèi)容绸栅,當然最好是有意義的,這樣你就能從歷史記錄里方便地找到改動記錄页屠。
git commit命令執(zhí)行成功后會告訴你粹胯,1個文件被改動(我們新添加的readme.txt文件)蓖柔,插入了兩行內(nèi)容(readme.txt有兩行內(nèi)容)。
為什么Git添加文件需要add风纠,commit一共兩步呢况鸣?因為commit可以一次提交很多文件,所以你可以多次add不同的文件竹观,比如:
$ git add file1.txt $ git add file2.txt file3.txt $ git commit -m "add 3 files."
工作區(qū)和暫存區(qū)
-
工作區(qū)(Working Directory)
就是你在電腦里能看到的目錄镐捧。
-
版本庫(Repository)
Git的版本庫里存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區(qū)臭增,還有Git為我們自動創(chuàng)建的第一個分支master懂酱,以及指向master的一個指針叫HEAD。
前面講了我們把文件往Git版本庫里添加的時候誊抛,是分兩步執(zhí)行的:
第一步是用
git add
把文件添加進去列牺,實際上就是把文件修改添加到暫存區(qū);版本庫狀態(tài)第二步是用
git commit
提交更改拗窃,實際上就是把暫存區(qū)的所有內(nèi)容提交到當前分支瞎领。版本庫狀態(tài)你可以簡單理解為,需要提交的文件修改通通放到暫存區(qū)随夸,然后默刚,一次性提交暫存區(qū)的所有修改。
?
版本庫管理
-
git status
查看倉庫當前的狀態(tài)逃魄,要隨時掌握工作區(qū)的狀態(tài)荤西,使用git status命令。
-
git diff
如果git status告訴你有文件被修改過伍俘,用git diff可以查看修改內(nèi)容邪锌。
-
git log
顯示從最近到最遠的提交日志。在Git中癌瘾,用HEAD表示當前版本觅丰,也就是最新的提交,上一個版本就是HEAD^ 妨退,上上一個版本就是HEAD^^ 妇萄,當然往上100個版本寫100個^比較容易數(shù)不過來,所以寫成HEAD~100咬荷。
-
git reset --hard commit_id
在版本的歷史之間進行切換冠句,
commit_id
為提交版本的id。 -
git reflog
用來記錄你的每一次命令
-
撤銷修改
場景1:當你改亂了工作區(qū)某個文件的內(nèi)容幸乒,想直接丟棄工作區(qū)的修改時懦底,用命令
git checkout -- README.md
。場景2:當你不但改亂了工作區(qū)某個文件的內(nèi)容罕扎,還添加到了暫存區(qū)時聚唐,想丟棄修改丐重,分兩步,第一步用命令
git reset HEAD README.md
杆查,就回到了場景1扮惦,第二步按場景1操作。 -
git rm
用于刪除一個文件亲桦。如果一個文件已經(jīng)被提交到版本庫径缅,那么你永遠不用擔心誤刪,但是要小心烙肺,你只能恢復文件到最新版本纳猪,你會丟失最近一次提交后你修改的內(nèi)容。
遠程倉庫
分布式版本控制系統(tǒng)通常也有一臺充當“中央服務(wù)器”的電腦桃笙,而充當"中央服務(wù)器"角色的倉庫就是遠程倉庫氏堤,但這個服務(wù)器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣干活搏明,只是交換修改不方便而已鼠锈。
如果有自己的私有倉庫地址,則無需執(zhí)行下面幾個操作星著。
-
注冊遠程倉庫賬號
-
Git@OSC:開源中國Git托管平臺
-
Github:世界最大的Git項目托管平臺
-
Coding:國內(nèi)新興的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只需要生成一次襟锐,不同的網(wǎng)站再將公鑰拷貝到網(wǎng)站上即可。
-
-
在Git托管平臺上創(chuàng)建項目
-
添加遠程倉庫
關(guān)聯(lián)一個遠程倉庫命令:
$ git remote add origin git@server-name:path/repo-name.git
其中
origin
表示遠程倉庫的別名膛锭,默認為origin
git@server-name:path/repo-name.git
表示項目在Git托管平臺上的ssh 地址粮坞。關(guān)聯(lián)遠程倉庫只需要執(zhí)行上面的命令一次即可。
關(guān)聯(lián)后初狰,第一次推送master分支的所有內(nèi)容命令:
$ git push -u origin master
此后莫杈,每次本地提交后,只要有必要跷究,推送最新修改就可以使用命令:
$ git push origin master
分布式版本系統(tǒng)的最大好處之一是在本地工作完全不需要考慮遠程庫的存在姓迅,也就是有沒有聯(lián)網(wǎng)都可以正常工作敲霍,而SVN在沒有聯(lián)網(wǎng)的時候是拒絕干活的俊马!當有網(wǎng)絡(luò)的時候丁存,再把本地提交推送一下就完成了同步,真是太方便了柴我!
-
克隆遠程倉庫
$ 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
創(chuàng)建分支:git branch <name>
切換分支:git checkout <name>
創(chuàng)建+切換分支:git checkout -b <name>
合并某分支到當前分支:git merge <name>
刪除分支:git branch -d <name>
當Git無法自動合并分支時觉增,就必須首先解決沖突。解決沖突后翻斟,再提交逾礁,合并完成。
用git log --graph
命令可以看到分支合并圖访惜。
推送分支嘹履,就是把該分支上的所有本地提交推送到遠程庫。推送時债热,要指定本地分支砾嫉,這樣,Git就會把該分支推送到遠程庫對應(yīng)的遠程分支上:
$ 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權(quán)威指南》
- http://backlogtool.com/git-guide/cn/
SVN vs Git (集中式 vs 分布式)
先說集中式版本控制系統(tǒng)避消,版本庫是集中存放在中央服務(wù)器的低滩,而干活的時候,用的都是自己的電腦岩喷,所以要先從中央服務(wù)器取得最新的版本恕沫,然后開始干活,干完活了纱意,再把自己的活推送給中央服務(wù)器婶溯。中央服務(wù)器就好比是一個圖書館,你要改一本書,必須先從圖書館借出來迄委,然后回到家自己改褐筛,改完了,再放回圖書館叙身。
集中式版本控制系統(tǒng)最大的毛病就是必須聯(lián)網(wǎng)才能工作渔扎。
那分布式版本控制系統(tǒng)與集中式版本控制系統(tǒng)有何不同呢?首先信轿,分布式版本控制系統(tǒng)根本沒有“中央服務(wù)器”晃痴,每個人的電腦上都是一個完整的版本庫,這樣财忽,你工作的時候倘核,就不需要聯(lián)網(wǎng)了,因為版本庫就在你自己的電腦上即彪。既然每個人電腦上都有一個完整的版本庫笤虫,那多個人如何協(xié)作呢?比方說你在自己電腦上改了文件A祖凫,你的同事也在他的電腦上改了文件A琼蚯,這時,你們倆之間只需把各自的修改推送給對方惠况,就可以互相看到對方的修改了遭庶。
和集中式版本控制系統(tǒng)相比,分布式版本控制系統(tǒng)的安全性要高很多稠屠,因為每個人電腦里都有完整的版本庫峦睡,某一個人的電腦壞掉了不要緊,隨便從其他人那里復制一個就可以了权埠。而集中式版本控制系統(tǒng)的中央服務(wù)器要是出了問題榨了,所有人都沒法干活了。
在實際使用分布式版本控制系統(tǒng)的時候攘蔽,其實很少在兩人之間的電腦上推送版本庫的修改龙屉,因為可能你們倆不在一個局域網(wǎng)內(nèi),兩臺電腦互相訪問不了满俗,也可能今天你的同事病了转捕,他的電腦壓根沒有開機。因此唆垃,分布式版本控制系統(tǒng)通常也有一臺充當“中央服務(wù)器”的電腦五芝,但這個服務(wù)器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣干活辕万,只是交換修改不方便而已枢步。