svn如何使用import目錄作爲工作拷貝+我的svn學習筆記

 http://blog.sina.com.cn/s/blog_4cd5d2bb0100lawk.html

 

前奏

svn作爲一款極其優秀的開源版本控制系統,應用廣泛,從組織到個人遍及各行各業。因此學習和熟練掌握它,對提高我們日常工作效率和數據安全非常重要,尤其對開發人員協同管理Project的文檔,代碼,各類圖等,能達到事半功倍的效果。不必再每天完成工作後,打包工程目錄,備份每天的版本;也不用幾個人堆在一起效率低下地手工合計代碼;也不用擔心偶爾因忘記打包,而丟失寶貴的數據資料。現在筆者已經養成完全使用svn管理日常的一些小項目,即使是個人使用,因爲實在是不想每次都打包了,然後找數據再去一堆壓縮包裏去找。

svn有Win和Linux的版本,這裏講的是後者,而且主要是命令行操作(不過通過命令行或者能更加理解svn的工作方式和原理),前者有烏龜這類圖形工具,雖功能不全,但操作也確實簡單。

需求分析

爲了避免手工管理一個我們日益變大的項目,於是我們選擇svn,讓程序爲我們自動控制版本並記錄下更改記錄。但每當使用import子命令將工程導入到svn時,我們遇到一個極其惡的問題:將本地的工程目錄全部提交上去之後,但是這個原始工程目錄卻不是工作拷貝,於是我還得把這個原始工作目錄刪掉,重新從版本庫中checkout出來一個拷貝。這太不爽了,暫且不論這個工程佔多大磁盤空間,明明有這個工程,只是缺少版本控制信息,有必要就刪掉而重新檢出整個工程麼。於是我在google再google,但始終沒有找到解決方法,後來瞭解到,svn本來就沒有考慮過這個問題,貌似就只能刪掉原始工程目錄,而重新從庫中檢出一個帶版本控制信息的一模一樣的工程。

Solution

可能是因爲個人有某種強迫症,偶還是一如繼往地尋找方法企圖解決這個問題,現在終於使用了一個小技巧搞定了,目前市場上還沒有見到過這種方法,完全自創哦。方法如下(依然以最經典的helloworld工程爲例) :

1. cd進入helloworld工程所在目錄
2. 遞歸導入工程到版本庫:
svn import helloworld svn://localhost/project -m "Just Test this Trick."
3. 執行最關鍵的命令(參數--depth=empty是精髓,它只初始化版本控制信息,不檢出任何文件):
svn co --depth=empty svn://localhost/project helloworld

4. 然後進入工程目錄:
cd helloworld
5. 執行命令:
svn st
然後顯示所有文件前全帶?號,因爲此時這些文件還不在版本控制管轄範圍內。
6. 因此我們將它們全部加入:
svn add *
現在所有文件前全顯示爲A標記,即爲Add狀態。
7. 爲了與版本庫一致,執行update命令(其實此時這些文件與現在版本庫中是一模一樣的,因爲我們纔剛剛提交完,沒有作任何更改,此舉是爲了“騙過”svn):
svn up *
此時更新必然會有衝突,而且還是100%,程序提示“在 “xxx” 中發現衝突。選擇: (p) 推遲,(mf) 全用我的,(tf) 全用他人的,(h) 使用幫助以得到更多選項:”,這時我們一定要選“(mf) 全用我的“,即輸入mf,否則我們前面的工作就沒有意義了。
8. 這時再用如下命令:
svn st
svn ci
命令均無顯示,因爲無狀態變化,現在這個原始工程已經“轉變“成一個work copy了。現在開始工作吧^_^。



--------------------------------俺是分隔線----------------------------------------
以下是我個人曾經的學習筆記,很亂,如果能用上,則看看,高手們就忽略掉它的存在吧。

http://www.subversion.org.cn/svnbook
http://subversion.tigris.org/faq.zh.html

sudo apt-get install subversion

#sudo apt-get install libapache2-svn(這個是和apache配合使用的,如果不打算使用apache則可不安裝)

完成安裝後,給系統添加一個用戶組(如svn),把想要加入這個組的加一下(至少要把你自己加進吧)

# Add group
sudo addgroup svn
# Append user z as the supplemental Groups to group svn
sudo usermod -G svn -a z

cd svnroot/
mkdir zigbee_paper
sudo chown -R root:svn zigbee_paper/
sudo svnadmin create /home/z/public/share/svnroot/zigbee_paper/

$ svnserve -d --foreground -r /home/svn
# -d -- daemon mode
# --foreground -- run in foreground (useful for debugging)
# -r -- root of directory to serve
# svnserve --daemon --root=#SVNPATH/repos --listen-port=3690
注:不推薦使用root用戶啓動服務,默認端口號爲3690

設置爲隨系統自動啓動

編寫啓動腳本文件,命名爲svn,放到 /etc/init.d/ 中

#!/bin/sh
# description: svnserve auto start-stop script.
#

# svn command home
svn_home=/usr/bin

# svn repository home

svn_repository=/home/svn

# svn owner
svn_owner=root

###
if [ ! -f "$svn_home/svnserve" ]
then
echo "svnserver startup: cannot start"
exit
fi
case "$1" in
'start')
echo "starting svnserve..."
su - $svn_owner -c "$svn_home/svnserve -d -r $svn_repository"
# if the user of script is root,can use the command below
# $svn_home/svnserve -d -r /svn
echo "start svnserve finished!"
;;
'stop')
echo "stoping svnserve..."
su - $svn_owner -c "$svn_home/killall svnserve"
echo "stop svnserve finished!"
;;
'restart')
echo "restarting svnserve..."
$0 stop
$0 start
;;
*)
echo "usage: svn { start | stop | restart } "
exit 1
esac
exit 0


更改啓動腳本文件屬性
sudo chmod 755 /etc/init.d/svn


製作符號鏈接
sudo ln -s /etc/init.d/svn /etc/rc1.d/K99svn
sudo ln -s /etc/init.d/svn /etc/rc2.d/S99svn


注:
rc1,rc2,rc3,rc4,rc5,rc6 文件夾中的文件,是不同運行級別的文件,根據不同的場景,系統會自動執行不同文件夾中的文件;
K 爲不執行的文件,S 爲執行的文件,執行的時候,按照K或者S後面的序號,從小到大逐一執行,一般自己建立的腳本,序號都命名爲 99,可以有多個
執行K文件,實際上是調用腳本中的stop命令;執行S開頭的文件,實際上是調用文件中的start命令
S40以後,纔是系統網絡配置完成的時刻。序號要調整到40後面

SVN 1.5會更加靈活,通過-N選項將會多餘,我們使用–depth選項代替它,根據規格,–depth的可能值有:
–depth=empty: 更新不會拉出任何不存在的文件或目錄
–depth=files: 更新會拉出所有的文件,但不包括子目錄
–depth=immediates: 更新會拉入所有不存在的文件或子目錄;但子目錄的設置爲depth=empty。
–depth=infinity: 更新會拉入所有不存在的文件和目錄,子目錄的設置爲depth=infinity,與目前的缺省更新行爲方式相同。

我們可以這樣操作:

A 通過命令行操作

1、檢出目錄images
svn co --depth=empty http://www.iusesvn.com/project1/images images_work_dir

這樣就在本地形成了一個工作拷貝目錄images_work_dir

2、進入images_work_dir目錄,單獨更新logo.jpg
svn up logo.jpg

這樣,我們就單獨檢出了logo.jpg,後面就可以對這個文件進行修改、提交等操作。


這三個命令(svn status、svn diff和 svn revert)都可以在沒有網絡的情況下工作,這讓你在沒有網絡連接時的管理修改過程更加簡單,像在飛機上旅行,乘坐火車往返或是在海灘上奮力工作時。

Subversion通過在.svn管理區域使用原始的版本緩存來做到這一點,這使得恢復本地版本而不必訪問網絡,這個緩存(叫做“text-base”)也允許Subversion可以根據原始版本生成一個壓縮的增量(“區別”)提交.
svn revert ITEM的效果與刪除ITEM然後執行svn update -r BASE ITEM完全一樣,但是,如果你使用svn revert它不必通知版本庫就可以恢復文件。


svn update
$ svn update
U INSTALL
G README
C bar.c
Updated to revision 50.
U和G沒必要關心,文件乾淨的接受了版本庫的變化,文件標示爲U表明本地沒有修改,文件已經根據版本庫更新。G標示合併,標示本地已經修改過,與版本庫沒有重迭的地方,已經合併。但是C表示衝突,說明服務器上的改動同你的改動衝突了,你需要自己手工去解決。

svn status可能返回的狀態碼(注意,#之後的不是svn status打印的)。
L some_dir # svn已經在.svn目錄鎖定了some_dir
M bar.c # bar.c的內容已經在本地修改過了
M baz.c # baz.c屬性有修改,但沒有內容修改
X 3rd_party # 這個目錄是外部定義的一部分
? foo.o # svn並沒有管理foo.o
! some_dir # svn管理這個,但它可能丟失或者不完
~ qux # 作爲file/dir/link進行了版本控制,但類型已經改變
I .screenrc # svn不管理這個,配置確定要忽略它
A + moved_dir # 包含歷史的添加,歷史記錄了它的來歷
M + moved_dir/README # 包含歷史的添加,並有了本地修改
D stuff/fish.c # 這個文件預定要刪除
A stuff/loot/bloo.h # 這個文件預定要添加
C stuff/loot/lump.c # 這個文件在更新時發生衝突

C stuff/loot/glub.c # 文件在更新時發生屬性衝突
R xyz.c # 這個文件預定要被替換
S stuff/squawk # 這個文件已經跳轉到了分支
K dog.jpg # 文件在本地鎖定;有鎖定令牌
O cat.jpg # 文件在版本庫被其他用戶鎖定
B bird.jpg # 文件本地鎖定,但鎖定發生錯誤
T fish.jpg # 文件本地鎖定,但鎖定丟失

在這種格式下,svn status打印五列字符,緊跟一些空格,接着是文件或者目錄名。第一列告訴一個文件的狀態或它的內容,返回代碼解釋如下:
A item

文件、目錄或是符號鏈item預定加入到版本庫。
C item

文件item發生衝突,在從服務器更新時與本地版本發生交迭,在你提交到版本庫前,必須手工的解決衝突。
D item

文件、目錄或是符號鏈item預定從版本庫中刪除。
M item

文件item的內容被修改了。
R item

文件、目錄或是符號鏈item預定將要替換版本庫中的item,這意味着這個對象首先要被刪除,另外一個同名的對象將要被添加,所有的操作發生在一個修訂版本。
X item

目錄沒有版本化,但是與Subversion的外部定義關聯,關於外部定義,可以看“外部定義”一節。
? item

文件、目錄或是符號鏈item不在版本控制之下,你可以通過使用svn status的--quiet(-q)參數或父目錄的svn:ignore屬性忽略這個問題,關於忽略文件的使用,見“svn:ignore”一節。
! item

文件、目錄或是符號鏈item在版本控制之下,但是已經丟失或者不完整,這可能因爲使用非Subversion命令刪除造成的,如果是一個目錄,有可能是檢出或是更新時的中斷造成的,使用svn update可以重新從版本庫獲得文件或者目錄,也可以使用svn revert file恢復原來的文件。
~ item

文件、目錄或是符號鏈item在版本庫已經存在,但你的工作拷貝中的是另一個。舉一個例子,你刪除了一個版本庫的文件,新建了一個在原來的位置,而且整個過程中沒有使用svn delete或是svn add。
I item

文件、目錄或是符號鏈item不在版本控制下,Subversion已經配置好了會在svn add、svn import和svn status命令忽略這個文件,關於忽略文件,見“svn:ignore”一節。注意,這個符號只會在使用svn status的參數--no-ignore時纔會出現—否則這個文件會被忽略且不會顯示!


Collision:

小於號、等於號和大於號串是衝突標記,並不是衝突的數據,你一定要確定這些內容在下次提交之前得到刪除,前兩組標誌中間的內容是你在衝突區所做的修改:
<<<<<<< .mine
Salami
Mortadella
Prosciutto
=======

後兩組之間的是Sally提交的修改衝突:
=======
Sauerkraut
Grilled Chicken
>>>>>>> .r2


svn import temp/ file:///home/z/public/share/svnroot/test/
在導入數據之後,你會發現原先的目錄樹並沒有納入版本控制,爲了開始工作,你還是要運行svn checkout得到一個乾淨的目錄樹工作拷貝。

global-ignores選項是一個空格分隔的列表,用來描述Subversion在它們版本化之前不想顯示的文件和目錄,缺省值是*.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store。
svn status,svn add和svn import命令也會忽略匹配這個列表的文件,你可以用單個的--no-ignore命令行參數來覆蓋這個選項。
1、Linux命令行下將文件checkout到本地目錄

svn checkout path(path是服務器上的目錄)

例如:svn checkout svn://192.168.1.1/pro/domain

簡寫:svn co

2、Linux命令行下往版本庫中添加新的文件

svn add file

例如:svn add test.php(添加test.php)

svn add *.php(添加當前目錄下所有的php文件)

3、Linux命令行下將改動的文件提交到版本庫

svn commit -m “LogMessage“ [-N] [--no-unlock] PATH(如果選擇了保持鎖,就使用–no-unlock開關)

例如:svn commit -m “add test file for my test“ test.php

簡寫:svn ci

4、Linux命令行下的加鎖/解鎖

svn lock -m “LockMessage“ [--force] PATH

例如:svn lock -m “lock test file“ test.php

svn unlock PATH

5、Linux命令行下更新到某個版本

svn update -r m path

例如:

svn update如果後面沒有目錄,默認將當前目錄以及子目錄下的所有文件都更新到最新版本。

svn update -r 200 test.php(將版本庫中的文件test.php還原到版本200)

svn update test.php(更新,與版本庫同步。如果在提交的時候提示過期的話,是因爲衝突,需要先update,修改文件,然後清除svn resolved,最後再提交commit)

簡寫:svn up

6、Linux命令行下查看文件或者目錄狀態

1)svn status path(目錄下的文件和子目錄的狀態,正常狀態不顯示)

【?:不在svn的控制中;M:內容被修改;C:發生衝突;A:預定加入到版本庫;K:被鎖定】

2)svn status -v path(顯示文件和子目錄狀態)

第一列保持相同,第二列顯示工作版本號,第三和第四列顯示最後一次修改的版本號和修改人。

注:svn status、svn diff和 svn revert這三條命令在沒有網絡的情況下也可以執行的,原因是svn在本地的.svn中保留了本地版本的原始拷貝。

簡寫:svn st

7、Linux命令行下刪除文件

svn delete path -m “delete test fle“

例如:svn delete svn://192.168.1.1/pro/domain/test.php -m “delete test file”

或者直接svn delete test.php 然後再svn ci -m ‘delete test file‘,推薦使用這種

簡寫:svn (del, remove, rm)

8、Linux命令行下查看日誌

svn log path

例如:svn log test.php 顯示這個文件的所有修改記錄,及其版本號的變化

9、Linux命令行下查看文件詳細信息

svn info path

例如:svn info test.php

10、Linux命令行下比較差異

svn diff path(將修改的文件與基礎版本比較)

例如:svn diff test.php

svn diff -r m:n path(對版本m和版本n比較差異)

例如:svn diff -r 200:201 test.php

簡寫:svn di

11、Linux命令行下將兩個版本之間的差異合併到當前文件

svn merge -r m:n path

例如:svn merge -r 200:205 test.php(將版本200與205之間的差異合併到當前文件,但是一般都會產生衝突,需要處理一下)



12、Linux命令行下SVN 幫助

svn help

svn help ci

以上是常用命令,下面寫幾個不經常用的

13、Linux命令行下版本庫下的文件和目錄列表

svn list path

顯示path目錄下的所有屬於版本庫的文件和目錄

簡寫:svn ls

14、Linux命令行下創建納入版本控制下的新目錄

svn mkdir: 創建納入版本控制下的新目錄。

用法: 1、mkdir PATH…

2、mkdir URL…

創建版本控制的目錄。

1、每一個以工作副本 PATH 指定的目錄,都會創建在本地端,並且加入新增調度,以待下一次的提交。

2、每個以URL指定的目錄,都會透過立即提交於倉庫中創建.在這兩個情況下,所有的中間目錄都必須事先存在。

15、Linux命令行下恢復本地修改

svn revert: 恢復原始未改變的工作副本文件 (恢復大部份的本地修改)。revert:

用法: revert PATH…

注意: 本子命令不會存取網絡,並且會解除衝突的狀況。但是它不會恢復被刪除的目錄

16、Linux命令行下代碼庫URL變更

svn switch (sw): 更新工作副本至不同的URL。

用法: 1、switch URL [PATH]

2、switch –relocate FROM TO [PATH...]

1、更新你的工作副本,映射到一個新的URL,其行爲跟“svn update”很像,也會將服務器上文件與本地文件合併。這是將工作副本對應到同一倉庫中某個分支或者標記的方法。

2、改寫工作副本的URL元數據,以反映單純的URL上的改變。當倉庫的根URL變動(比如方案名或是主機名稱變動),但是工作副本仍舊對映到同一倉庫的同一目錄時使用這個命令更新工作副本與倉庫的對應關係。

17、Linux命令行下解決衝突

svn resolved: 移除工作副本的目錄或文件的“衝突”狀態。

用法: resolved PATH…

注意: 本子命令不會依語法來解決衝突或是移除衝突標記;它只是移除衝突的相關文件,然後讓 PATH 可以再次提交。

18、Linux命令行下輸出指定文件或URL的內容。

svn cat 目標[@版本]…如果指定了版本,將從指定的版本開始查找。

svn cat -r PREV filename > filename (PREV 是上一版本,也可以寫具體版本號,這樣輸出結果是可以提交的)


典型的工作週期:
*更新你的工作拷貝
o svn update
*做出修改
o svn add
o svn delete
o svn copy
o svn move
*檢驗修改
o svn status
o svn diff
o svn revert
*合併別人的修改到工作拷貝
o svn update
o svn resolved
*提交你的修改
o svn commit


客戶端在使用類似svn,http://這種網絡協議訪問資源時(即通過svnserve進程),會通過一定的權限驗證,這種驗證是通過資源的一些配置文件設定的。如在本例中,這些配置文件放在了/usr/local/svn/test/conf/下,包括三個authz,passwd,svnserve.conf。這三個文件的配置就不詳談了。另外的幾種客戶端方式如http也不介紹了,svnbook上去看,都有。

如果想通過網絡方式,即svn,http等訪問(推薦使用這種方式,而不是file://方式),必須要把svnserve進程啓動,如果你不小心把機器重新啓動了,一定要手動把它再啓動一邊。




刪除項目:
svnadmin dump E:\repos\project1 > aaa.dump
cat aaa.dump | svndumpfilter exclude /tags/beta1 > bbb.dump
svnadmin create E:\repos\project1_new
svnadmin load E:\repos\project1_new < bbb.dump

1. export 出所有文件,刪除你想要刪除的
2. 刪除代碼庫,用 svn create 命令重建之
3. 導入
這樣不能保留歷史版本




配置中文環境:

1.編輯/var/lib/locales/supported.d/*
格式參考 /usr/share/i18n/SUPPORTED
vi /var/lib/locales/supported.d/local
vi /var/lib/locales/supported.d/zh
vi /var/lib/locales/supported.d/en

如:
more /var/lib/locales/supported.d/local
zh_CN.UTF-8 UTF-8
en_US.UTF-8 UTF-8
zh_CN.GB18030 GB18030

2.生成locale(自動保存在/usr/lib/locale/中)
locale-gen

3.修改locale
vi /etc/environment

LANG="zh_CN.UTF-8"
改成
LANG="zh_CN.GB18030"

more /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:
/usr/games"
#LANG="zh_CN.UTF-8"
LANG="zh_CN.GB18030"
LANGUAGE="zh_CN:zh:en_US:en"
CLASSPATH=.:/usr/lib/jvm/java-1.5.0-sun/lib
JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun

4.重新啓動或切換下運行級別,查看locale
root@1006:~# locale
LANG=zh_CN.GB18030
LANGUAGE=zh_CN:zh:en_US:en
LC_CTYPE="zh_CN.GB18030"
LC_NUMERIC="zh_CN.GB18030"
LC_TIME="zh_CN.GB18030"
LC_COLLATE="zh_CN.GB18030"
LC_MONETARY="zh_CN.GB18030"
LC_MESSAGES="zh_CN.GB18030"
LC_PAPER="zh_CN.GB18030"
LC_NAME="zh_CN.GB18030"
LC_ADDRESS="zh_CN.GB18030"
LC_TELEPHONE="zh_CN.GB18030"
LC_MEASUREMENT="zh_CN.GB18030"
LC_IDENTIFICATION="zh_CN.GB18030"
LC_ALL=


#!/bin/sh
export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8
/usr/bin/svn update /var/www/html --username=weiqi --password=******
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章