創(chuàng)建自己的版本庫
svnadmin create –fs-type fsfs /home/lmzhang/myrepos.
svn ci -m “”
關(guān)于內(nèi)置版本號.
HEAD - 最新版本號.
BASE - 當(dāng)前工作版本的未修改版本.
COMMITTED - BASE - 1
PREV - COMMITTED - 1
svn merge 的作用可以用語在任何兩個(gè)版本之間的差異合并到某個(gè)工作版本的功能.
語法如下
舉例來說我有一個(gè)工作copy,內(nèi)有一個(gè)1.txt 當(dāng)前版本號是1.
內(nèi)容是 first.
然后我添加為 first second. svn ci -m “”.
然后我執(zhí)行 svn merge -r HEAD:PREV 1.txt , svn將比較 HEAD版本和PREV版本的內(nèi)容差異,然后將這個(gè)差異合并到 當(dāng)前路徑下的1.txt , 由于差異是減少了 second , 因此相當(dāng)于回到了 版本1.
svn merge的語法允許非常靈活的指定參數(shù),如下是一些例子:
$ svn merge http://svn.example.com/repos/branch1@150 \
http://svn.example.com/repos/branch2@212 \
my-working-copy
$ svn merge -r 100:200 http://svn.example.com/repos/trunk my-working-copy
$ svn merge -r 100:200 http://svn.example.com/repos/trunk
第一種語法使用URL@REV的形式直接列出了所有參數(shù),第二種語法可以用來作為比較同一個(gè)URL的不同版本的簡略寫法,最后一種語法表示工作拷貝是可選的,如果省略,默認(rèn)是當(dāng)前目錄。
svn 的分支創(chuàng)建倒是很容易.
svn copy from to , 那么to就成為了from的一個(gè)copy,在svn的概念中就是分支或者tag.
問題在于合并.
svn 的概念中,分之合并實(shí)際上是將某個(gè)分之某個(gè)版本到另外一個(gè)版本之間的變化合并到某個(gè)目錄的概念.
比如 分支 b-1 從開始分支的版本 4 , 到做了修改后的版本 9 . 想合并到主干上.
// 下面說明了,為什么要用上面這種做法,僅僅比較帶合并的分支的信息.
(
但是要哪兩個(gè)樹進(jìn)行比較呢?乍一看,回答很明確,只要比較最新的主干與分支。但是你要意識到—這個(gè)想法是錯(cuò)誤的,傷害了許多新用戶!因?yàn)?span>svn merge的操作很像svn diff,比較最新的主干和分支樹不僅僅會描述你在分支上所作的修改,這樣的比較會展示太多的不同,不僅包括分支上的增加,也包括了主干上的刪除操作,而這些刪除根本就沒有在分支上發(fā)生過。
)
另外通過同一分支上的版本間merge可以執(zhí)行反向操作,比如版本5對于版本4的修改是完全錯(cuò)誤的,那么可以通過 svn merge -r 5:4 file.cpp working-copy 來達(dá)到在working-copy 中取消這個(gè)修改.
反向操作另外一個(gè)作用,加入你刪除了head版本中的test.cpp , 但是又想找回來,那么你可以 svn log -v 察看test.cpp 是什么時(shí)候被刪除的., -r 10 , 上一個(gè)版本 8 . 那么可以執(zhí)行如下
svn merger -r 10:8 file:///…/ working-copy 就還原了.
當(dāng)然svn copy -r 也可以.
還有一種方式就是兩個(gè)分支間直接進(jìn)行合并.
另外merge 有一個(gè)有用的參數(shù),–dry-run 表示僅僅模擬本次合并的效果,實(shí)際上并不生效.
舉例來說
就表示將主干 v1 到分支b_1 v4 之間的差別進(jìn)行列舉合并到當(dāng)前工作目錄.
tag 本身和branch在svn 中的操方式是一樣的,不過tag還有一個(gè)增強(qiáng)點(diǎn),就是能夠?qū)?dāng)前工作目錄直接進(jìn)行tag.
update 狀態(tài)
U foo
文件foo
更新了(從服務(wù)器收到修改)。
A foo
文件或目錄foo
被添加到工作拷貝。
D foo
文件或目錄foo
在工作拷貝被刪除了。
R foo
文件或目錄foo
在工作拷貝已經(jīng)被替換了,這是說,foo
被刪除,而一個(gè)新的同樣名字的項(xiàng)目添加進(jìn)來,它們具有同樣的名字,但是版本庫會把它們看作具備不同歷史的不同對象。
G foo
文件foo
接收到版本庫的更改,你的本地版本也已經(jīng)修改,但改變沒有互相影響,Subversion成功的將版本庫和本地文件合并,沒有發(fā)生任何問題。
C foo
文件foo
的修改與服務(wù)器沖突,服務(wù)器的修改與你的修改交迭在一起,不要恐慌,這種沖突需要人(你)來解決,我們在后面的章節(jié)討論這種情況。
svn status
L some_dir # svn已經(jīng)在.svn目錄鎖定了some_dir
M bar.c # bar.c的內(nèi)容已經(jīng)在本地修改過了
M baz.c # baz.c屬性有修改,但沒有內(nèi)容修改
X 3rd_party # 這個(gè)目錄是外部定義的一部分
? foo.o # svn并沒有管理foo.o
! some_dir # svn管理這個(gè),但它可能丟失或者不完
~ qux # 作為file/dir/link進(jìn)行了版本控制,但類型已經(jīng)改變
I .screenrc # svn不管理這個(gè),配置確定要忽略它
A + moved_dir # 包含歷史的添加,歷史記錄了它的來歷
M + moved_dir/README # 包含歷史的添加,并有了本地修改
D stuff/fish.c # 這個(gè)文件預(yù)定要刪除
A stuff/loot/bloo.h # 這個(gè)文件預(yù)定要添加
C stuff/loot/lump.c # 這個(gè)文件在更新時(shí)發(fā)生沖突
C stuff/loot/glub.c # 文件在更新時(shí)發(fā)生屬性沖突
R xyz.c # 這個(gè)文件預(yù)定要被替換
S stuff/squawk # 這個(gè)文件已經(jīng)跳轉(zhuǎn)到了分支
K dog.jpg # 文件在本地鎖定;有鎖定令牌
O cat.jpg # 文件在版本庫被其他用戶鎖定
B bird.jpg # 文件本地鎖定,但鎖定發(fā)生錯(cuò)誤
T fish.jpg # 文件本地鎖定,但鎖定丟失
第一列
A item
文件、目錄或是符號鏈item
預(yù)定加入到版本庫。
C item
文件item
發(fā)生沖突,在從服務(wù)器更新時(shí)與本地版本發(fā)生交迭,在你提交到版本庫前,必須手工的解決沖突。
D item
文件、目錄或是符號鏈item
預(yù)定從版本庫中刪除。
M item
文件item
的內(nèi)容被修改了。
R item
文件、目錄或是符號鏈item
預(yù)定將要替換版本庫中的item
,這意味著這個(gè)對象首先要被刪除,另外一個(gè)同名的對象將要被添加,所有的操作發(fā)生在一個(gè)修訂版本。
X item
目錄沒有版本化,但是與Subversion的外部定義關(guān)聯(lián),關(guān)于外部定義,可以看“外部定義”一節(jié)。
? item
文件、目錄或是符號鏈item
不在版本控制之下,你可以通過使用svn status的--quiet
(-q
)參數(shù)或父目錄的svn:ignore
屬性忽略這個(gè)問題,關(guān)于忽略文件的使用,見“svn:ignore
”一節(jié)。
! item
文件、目錄或是符號鏈item
在版本控制之下,但是已經(jīng)丟失或者不完整,這可能因?yàn)槭褂梅荢ubversion命令刪除造成的,如果是一個(gè)目錄,有可能是檢出或是更新時(shí)的中斷造成的,使用svn update可以重新從版本庫獲得文件或者目錄,也可以使用svn revert file恢復(fù)原來的文件。
~ item
文件、目錄或是符號鏈item
在版本庫已經(jīng)存在,但你的工作拷貝中的是另一個(gè)。舉一個(gè)例子,你刪除了一個(gè)版本庫的文件,新建了一個(gè)在原來的位置,而且整個(gè)過程中沒有使用svn delete或是svn add。
I item
文件、目錄或是符號鏈item
不在版本控制下,Subversion已經(jīng)配置好了會在svn add、svn import和svn status命令忽略這個(gè)文件,關(guān)于忽略文件,見“svn:ignore
”一節(jié)。注意,這個(gè)符號只會在使用svn status的參數(shù)--no-ignore
時(shí)才會出現(xiàn)—否則這個(gè)文件會被忽略且不會顯示!
第二列說明文件或目錄的屬性的狀態(tài)(更多細(xì)節(jié)可以看“屬性”一節(jié)),如果一個(gè)M
出現(xiàn)在第二列,說明屬性被修改了,否則顯示空白。
第三列只顯示空白或者L
,L
表示Subversion已經(jīng)鎖定了這個(gè)目錄的工作區(qū)域.svn
,當(dāng)你的svn commit正在運(yùn)行的時(shí)候—也許正在輸入log信息,運(yùn)行svn status你可以看到L
標(biāo)記,如果這時(shí)候Subversion并沒有運(yùn)行,可以推測Subversion發(fā)生中斷并且已經(jīng)鎖定,你必須運(yùn)行svn cleanup來清除鎖定(本節(jié)后面將有更多論述)。
第四列只會顯示空白或+
,+
的意思是一個(gè)有附加歷史信息的文件或目錄預(yù)定添加或者修改到版本庫,通常出現(xiàn)在svn move或是svn copy時(shí),如果是看到A +
就是說要包含歷史的增加,它可以是一個(gè)文件或是拷貝的根目錄。+
表示它是即將包含歷史增加到版本庫的目錄的一部分,也就是說他的父目錄要拷貝,它只是跟著一起的。 M +
表示將要包含歷史的增加,并且已經(jīng)更改了。當(dāng)你提交時(shí),首先會隨父目錄進(jìn)行包含歷史的增加,然后本地的修改提交到更改后的版本
第五列只顯示空白或是S
,表示這個(gè)目錄或文件已經(jīng)轉(zhuǎn)到了一個(gè)分支下了(使用svn switch)。
svn status也有一個(gè)–verbose
(-v
)選項(xiàng),它可以顯示工作拷貝中的所有項(xiàng)目,即使沒有改變過:
$ svn status --verbose
M 44 23 sally README
44 30 sally INSTALL
M 44 20 harry bar.c
44 18 ira stuff
44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
44 21 sally stuff/things
A 0 ? ? stuff/things/bloo.h
44 36 harry stuff/things/gloo.c
第一列保持相同,第二列顯示一個(gè)工作版本號,第三和第四列顯示最后一次修改的版本號和修改人。
上面所有的svn status調(diào)用并沒有聯(lián)系版本庫,只是與.svn
中的元數(shù)據(jù)進(jìn)行比較的結(jié)果,最后,是–show-updates
(-u
)參數(shù),它將會聯(lián)系版本庫為已經(jīng)過時(shí)的數(shù)據(jù)添加新信息:
$ svn status --show-updates --verbose
M * 44 23 sally README
M 44 20 harry bar.c
* 44 35 harry stuff/trout.c
D 44 19 ira stuff/fish.c
A 0 ? ? stuff/things/bloo.h
Status against revision: 46
注意這兩個(gè)星號:如果你現(xiàn)在執(zhí)行svn update,你的README
和trout.c
會被更新,這告訴你許多有用的信息—你可以在提交之前,需要使用更新操作得到文件README
的更新,或者說文件已經(jīng)過時(shí),版本庫會拒絕了你的提交。
輸出的格式為統(tǒng)一區(qū)別格式(unified diff format),刪除的行前面加一個(gè)-
,添加的行前面有一個(gè)+
,svn diff命令也打印文件名和打補(bǔ)丁需要的信息,所以你可以通過重定向一個(gè)區(qū)別文件來生成“補(bǔ)丁”:
$ svn diff > patchfile
舉個(gè)例子,你可以把補(bǔ)丁文件發(fā)送郵件到其他開發(fā)者,在提交之前審核和測試。
如果你只是希望檢查一個(gè)過去的版本而不希望察看它們的區(qū)別,使用svn cat:
$ svn cat --revision 2 rules.txt
Be kind to others
Freedom = Chocolate Ice Cream
Everything in moderation
Chew with your mouth open
$
你可以重定向輸出到一個(gè)文件:
$ svn cat --revision 2 rules.txt > rules.txt.v2
除了以上的命令,你可以使用帶參數(shù)--revision
的svn update和svn checkout來使整個(gè)工作拷貝“回到過去”[7]:
$ svn checkout --revision 1729 # Checks out a new working copy at r1729
…
$ svn update --revision 1729 # Updates an existing working copy to r1729
…
# 建立庫
$ svnadmin create /usr/local/svn/newrepos
# 建立分支
建立一個(gè)備份只是傳遞兩個(gè)目錄參數(shù)到svn copy命令:
$ cd bigwc
$ svn copy trunk branches/my-calc-branch
$ svn status
A + branches/my-calc-branch
現(xiàn)在,我們必須告訴你建立分支最簡單的方法:svn copy可以直接對兩個(gè)URL操作。
$ svn copy http://svn.example.com/repos/calc/trunk \
http://svn.example.com/repos/calc/branches/my-calc-branch \
-m "Creating a private branch of /calc/trunk."
Committed revision 341.
鎖定-修改-解鎖問題
我們有兩個(gè)共同工作者,Harry和Sally,他們想同時(shí)編輯版本庫里的同一個(gè)文件,如果首先Harry保存它的修改,過了一會,Sally可能湊巧用自己的版本覆蓋了這些文件,Harry的更改不會永遠(yuǎn)消失(因?yàn)橄到y(tǒng)記錄了每次修改),Harry所有的修改不會出現(xiàn)在Sally的文件中,所以Harry的工作還是丟失了—至少是從最新的版本中丟失了—而且是意外的,這就是我們要明確避免的情況!
在這種情況下,我們應(yīng)該明確對需要進(jìn)行修改的目錄進(jìn)行鎖定.
拷貝-修改-合并模型假定文件是可以根據(jù)上下文合并的:就是版本庫的文件主要是以行為基礎(chǔ)的文本文件(例如程序源代碼)。但對于二進(jìn)制格式,例如藝術(shù)品或聲音,在這種情況下,十分有必要讓用戶輪流修改文件,如果沒有線性的訪問,有些人的許多工作就最終要被放棄。
copy-edit-merge
原文:http://www.alisdn.com/wordpress/?p=1381