2008年9月4日 星期四

程式設計的版本控制 - SVN - 指令大全

path:表示本機路徑
url:表示是server上的目錄
file:是本機檔案

0. 一開始要把之前完成的程式上傳到空的svn server

[root@host ~]# svn import path url


1. 將文件checkout到本機端,其中path是你要新增的資料夾是用來放置下載下來檔案;url是網路上server的位置,xxx是使用者名稱

[root@host ~]# svn checkout path url --username xxx


如果我現在有9個版本,我要取得第二個的話就打以下指令,下載第二個版本到本機目錄path下

[root@host ~]# svn checkout -r 2 url path


2. 往檔案庫中添加新的檔案或資料夾

[root@host ~]# svn add file(or path)


3. 將修改過的文件提交到檔案庫

[root@host ~]# svn commit


4. 鎖定工作複本路徑或是檔案庫的 URL, 這樣就沒有其它使用者可以對它們送交任何更動.

[root@host ~]# svn lock path


5. 解除工作複本路徑或 URL 的鎖定

[root@host ~]# svn unlock path


6. 更新到某個版本(若沒有填,則更新到最新版本);svn update如果後面沒有目錄,默認將當前目錄以及子目錄下的所有文件都更新到最新版本。

將版本庫中的文件test.php還原到版本200

[root@host ~]# svn update -r200 test.php

更新到最新版本(如果在提交的時候提示過期的話,是因為衝突,需要先update,修改文件,然後清除svn resolved,最後再提交commit)

[root@host ~]# svn update test.php


6. 查看文件或者目錄狀態(包含子目錄),只列出與server有差異的部分

[root@host ~]# svn status path


顯示文件和子目錄狀態(包含與server沒有差異的部分也全部列出來)

[root@host ~]# svn status -v path

A file_or_dir:目錄或檔案 file_or_dir 已預定要被新增至檔案庫.
M file:檔案 file 的內容已被修改.
D file_or_dir:目錄或檔案 file_or_dir 已預定要自檔案庫刪除.
X dir:目前 dir 未納入版本控制, 但是關聯到一個 Subversion 的外部定義. 欲了解更多外部定義, 請參考 the section called “外部定義”.
? file_or_dir:目錄或檔案你可以藉由 svn status 命令的 --quite (-q) 選項, 或是對父目錄設定其 svn:ignore 性質, 就不會顯示問號代碼. 想知道有哪些檔案會被忽略, 請參照 the section called “svn:ignore”.
! file_or_dir:目錄或檔案 file_or_dir 已納入版本控制之中, 但是它不是消失, 就是不完整. 如果這個檔案或目錄被非 Subversion 的命令所刪除, 就會被判定為消失. 如果是目錄的話, 如果你在取出或是更新時中斷, 那麼它就會變成不完整. 只要執行 svn update, 就可以從檔案庫重新取得目錄或檔案, 或者以 svn revert file_or_dir, 回存消失的檔案.
~ file_or_dir:目錄或檔案 file_or_dir 在檔案庫裡是一種物件, 但是實際在工作複本中又是另一種. 舉個例子, Subversion 可能在檔案庫裡有一個檔案, 但是你刪除了這個檔案, 而以原名稱建立了一個目錄, 但是都沒有使用 svn delete 或 svn add 命令來處理.
C file:file_or_dir 處於衝突的狀態. 也就是說, 在更新時, 來自伺服器的更新與工作複本中的本地更動, 有重疊的部份. 在送交更動回檔案庫之前, 你必須先解決這個這個衝突.

第一列就是顯示上面的狀態,第二列顯示工作版本號,第三和第四列顯示最後一次修改的版本號和修改人。

7. 刪除檔案或資料夾

[root@host ~]# svn delete file(or path)


8. 查看日誌,顯示這個文件的所有修改記錄,及其版本號的變化

[root@host ~]# svn log file


9. 查看文件(資料夾)詳細信息

[root@host ~]# svn info file(or path)

這一個指令也可以查詢目前本地端的版本。

10. 比較差異
將修改的文件與基礎版本比較

[root@host ~]# svn diff file(or path)


對版本m和版本n比較差異

[root@host ~]# svn diff -r m:n file(or path)


11. 將兩個版本之間的差異合併到當前文件(但是一般都會產生衝突,需要處理一下)

[root@host ~]# svn merge -r m:n path


12. SVN 幫助

[root@host ~]# svn help
[root@host ~]# svn help ci


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

[root@host ~]# svn listpath


14. 創建納入版本控制下的新目錄
創建納入版本控制下的新目錄(每一個以工作副本 PATH 指定的目錄,都會創建在本地端,並且加入新增調度,以待下一次的提交。)

[root@host ~]# svn mkdir path


創建版本控制的目錄(每個以URL指定的目錄,都會透過立即提交於倉庫中創建)

[root@host ~]# svn mkdir url


在這兩個情況下,所有的中間目錄都必須事先存在。

15. 恢複本地修改(恢復原始未改變的工作副本文件)(注意: 本子命令不會存取網絡,並且會解除衝突的狀況。但是它不會恢復被刪除的目錄)

[root@host ~]# svn revert path


16. svn switch (sw):更新工作副本至不同的URL。
更新你的工作副本,映射到一個新的URL,其行為跟「svn update」很像,也會將服務器上文件與本地文件合併。這是將工作副本對應到同一倉庫中某個分支或者標記的方法。url是同一個資料庫中新的資料夾

[root@host ~]# switch url [path]

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

[root@host ~]# switch --relocate FROM TO [path…]


17. 解決衝突(svn resolved:移除工作副本的目錄或文件的「衝突」狀態)

[root@host ~]# resolved path

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

18. 看別人寫的commet
使用者在svn update前應該先查出自已目前的版本號,查目前版本號的方法如下,最大的號碼即為你目前的版本號

[root@host ~]# svn status -N -v


然後在svn update後,把原本版本號到最新版本號之間的送交註解看一下。例如:原本你的工作複本版本號為13,當你修改過後要送交之前得作一次svn update,版本號跳為17,那你這時候應該要作一次看comment的指令:

[root@host ~]# svn log -r 13:17 -v


先看看別人之前改了什麼,然後你自已評估與目前你所修改的程式流程有沒有衝突,例如:別人在16版的時候把$content[_msg]變數改為 $content[_lang]變數,那麼如果你有使用$content[_msg]的話,你就應該先改好手邊的工作複本,再作svn commit。

如果你覺得看comment不夠清楚,那麼直接比較一下程式碼到底有那裡是不同

[root@host ~]# svn diff -r 16


上面的指令會比較第16版與你手邊已修改但還未送交的版本作比較,如果你只想比較單一檔案的話,指令是:

[root@host ~]# svn diff -r 16 iLovePerl.php


有時候你個人的commit周期太慢了(可能因為一個bug一直抓不出來),那你還是要在未上傳檔案庫前,經常地(至少是一天一次)觀看遠端檔案庫的版本情況,像是你的工作複本到遠端檔案庫之間的送交註解,其指令如下:

[root@host ~]# svn log -r BASE:HEAD

這樣才不會與其他人的距離差太遠,否則等你要commit時,才來調整你的程式碼,這又太慢了。

有時候,在svn所控制的專案中,你有不想作版本控制的檔案,那該這麼作呢!

像是資料庫的設定檔,這個東西,每個程設師在開發狀態時,可能用的都是臨時性的資料庫,一個人一種設定,如果每一次commit或update後都把別人用的或是自己用的給重設了,那是件很麻煩的事,所以呢,我們使用svn:ignore性質來解救我們,方法如下,後來的Config代表的是一個資料夾,是你所想忽略的檔案所在的那一個資料夾,如果你想忽略的檔案是在現在的目錄中,那就把 Config 換成 .

[root@host ~]# svn propedit svn:ignore Config

然後它會進入stdin的模式,你直接打檔名進去即可,像是

[root@host ~]# svn propedit svn:ignore Config DB.config

然後按下 Ctrl+D即可。請記住DB.config是在Config資料夾中的檔案喔,而且DB.config檔不應該送進svn add中喔

[問題]
19. 像我的話,會由之前某一個檔案copy到另一個檔案,然後,要add的時候會出現「此資料夾以在控管內」,這是因為每一個資料夾內都會有一個.svn的隱藏資料夾,而在由其它資料夾copy過來時,同時也把這一個資料夾也copy過來,這個時候只要把.svn資料刪掉就可以了~

20. 當產品要release出去時,如何把每一個資料夾下的.svn刪掉哩?
其實不是刪掉,而是透過export不會產生.svn資料夾

[root@host ~]# svn export url path (跟 checkout 參數類同)


[2014.05.13 補充]
在commit時,同時加入描述。
% svn commit --message "Corrected number of cheese slices."

[2014.05.29 補充]
方法1
用\n來當作換行
% svn ci -m "This is the first line\nThis is the second line"

方法2
直接 svn commit,然后在vim中编辑log(需要bash中提前设置$SVN_EDITOR=vim)

方法3
提交指定文件中的log
-F [--file] ARG : read log message from file ARG

[2014.06.05 補充]
Log: 如果沒輸入參數, 預設會把所有 commit log 都列出來
svn log
svn log -l 10 # 顯示 10 筆(最新 10筆 Log)
svn log -c 100 # 顯示 revision 100 的 Log
svn log -v -c 100 # 顯示 revision 100 的詳細 Log

參考資料:
svn命令
版本控制系統:svn(subversion)
Version Control with Subversion
SVN命令(linux下)
Version Control with Subversion
目前用不到資料:
研究生必備SVN版本控管
在Linux上裝SVN + Backup Script
Linux(Ubuntu)下Apache + Svn的安装初步完成
svn commit的log中输入换行符
SVN 基本指令教學

沒有留言: