SVN 基本指令教學

SVN 的基本指令介紹, 主要參考自下述:

主要 SubTrain 的 PPT 前面頁數看一看, 基礎就大概都知道了, 後面頁數太進階了, 目前用不到, 以後再看. XD

PS: 如果不知道 SVN 是什麼, 可見此文: 淺談版本控制系統, 裡面連結檔案看完, 應該就很清楚了 🙂

先來看 SVN Trunk/Tags/Branches 目錄 的 架構 和 用途:(英文說明轉載自 SubTrain PPT)

  • trunk: Main line of development(主幹, 主要開發都由在 trunk)
  • tags: Releases (想要 Release 的時後, 就標個 Tag, 以後可以依 Tag 來找回之前版本的資料)
  • branches: Preparation of release, bug fixing(分支, 可以將某些功能切出來, 或者 bug fix 等切成分支, 等做完後再用 Merge 合併回來)

SVN 基本功能:

Import: 將整個 project_directory 的資料 import 進 svn 裡面

  • svn import project_directory http://DOMAIN/svn_project
  • svn import project_directory file:///SVN_PATH/svn_project

Checkout: (checkout 可簡寫成 co), 將資料 checkout 回來

  • svn co http://SVN_PATH/svn_project
  • svn co file:///SVN_PATH/svn_project
  • svn co -r 12 file:///var/lib/svn/dev/projects # 出第12版的 projcets code

List: (list 可簡寫成 ls), 看上面有哪些檔案/資料

  • svn ls http://SVN_PATH/svn_project
  • svn ls file:///SVN_PATH/svn_project

Update: (update 可簡寫成 up), 將目前資訊更新成 SVN 線上最新版本.

  • SVN_CHECKOUT_DIR$ svn up

Commit: (commit 可簡寫成 ci), 將目前所做的修改 commit 回 svn

  • SVN_CHECKOUT_DIR$ svn ci

Status: (status 可簡寫成 st), 看目前檔案/結構 跟 SVN 線上的版本有哪些不同

  • SVN_CHECKOUT_DIR$ svn st

Add: 將此 檔案/目錄 新增進 svn

  • SVN_CHECKOUT_DIR$ svn add filename 或 svn add directory

MV: 改檔名, 並且此檔案之前紀錄還要繼續留下

  • SVN_CHECKOUT_DIR$ svn mv filename new_filename

Revert: 還原這次的修改, 回到前一版的檔案狀態(未 commit 前可用)

  • SVN_CHECKOUT_DIR$  svn revert [file | directory]

SVN 檔案狀態資訊:

  • ?: 此檔案不存在 SVN 裡面
  • A: 此次新增的檔案
  • C: 此檔案已經有人改過, 合併不成功, 需要人工介入
  • D: 此次移除的檔案
  • M: 此檔案有修改過
  • U: 此檔案有被更新過

再來是比較進階一點點, 下述範例轉載自 SubTrain 的教學 PPT:

建立一個 branch

  • svn copy http://svnserver/calc/trunk http://svnserver/calc/branches/my-calc-branch -m 'create a branch' 

建立 Release Tags:

  • svn copy http://svnserver/calc/trunk http://svnserver/calc/tags/Release-1.0.0 -m 'create Release tags for Release 1.0.0'

合併兩個版本的檔案 # 參考自: 用 Subversion 的 Merge 來 Undo

  • svn merge -r REV1:REV2 {path/to/workingcopy}
  •  (UNDO) svn merge -r 1234:1233 ...
  •  (MERGE)svn merge -r 1233:1234 ...
  • svn merge --dry-run -r 343:344 http://svn.example.com/repos/calc/trunk

有 "C" 狀態處理完後, 用 resolved  將自動產生的檔案刪除, 才能正常 commit:

  • svn resolved filename # 這樣子下就會把自動產生 diff 等的檔案刪除

找版本間有什麼不同 diff:

  • svn diff # 自動以現在檔案跟 SVN 內最新版做 diff
  • svn diff -r9237:9238

Info: 列出現在路徑, 版本編號, 最後一次修改日期 ... 等資訊

  • svn info

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

Propset (propset, pset, ps): 版本控制都有些特殊 Keyword 設定, 如 Id 就是最常用的, 設定方法如下:

  1. 在檔案內找地方加入 $Id$
  2. 設定此檔案要能吃 Id 的 Keyword: svn ps svn:keywords 'Id' filename (只需設一次即可, 之後就不用再設)
  3. svn ci 後, $Id$ 會自動代換成 $Id:filename 編號 年月日時分秒 username $ 的資訊
  4. svn help ps 可以看到有哪些 Keyword 可以用, 即 Keyword 的說明.(ex: URL, Author, Date, Rev, Id 等.)

其它 SVN Client:

SVK 相關介紹:

其它相關網頁

作者: Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.

在〈SVN 基本指令教學〉中有 96 則留言

  1. 我把我的步驟再清楚地描述一下好了:
    原始碼放在 /var/www/project
    svn 放在 /home/svn/project
    server 上下指令:svn import /var/www/project http://localhost/svn/project
    然後在 windows 上用烏龜 checkout,改好後 commit
    然後在 http://serverIP/svn/project 輸入帳號密碼後可以看見已經成功更新的程式碼目錄及檔案
    但是 /var/www/project 裡的檔案卻是沒有更新
    svn up 不是指的是更新 client 端的檔案嗎?
    還是要下怎樣的指令才會更新 svn 裡的檔案到 /var/www/project?
    謝謝您抽空指教,感謝!

  2. 謝謝您的指教
    想再請問一下,svn 是否有選項能夠在 commit 之後自動把程式碼 export 到 /var/www/project 下呢?

  3. 沒有, 不過 SVN 在遇到這種狀況, 有很多已經遇先想好的處理.
    你找 /home/svn/project/hooks/post-commit.tmpl, 把這個 改名成 post-commit, 之後再加上 svn export 等指令就可以做到了 🙂

  4. 感謝前輩的回答
    能否再請教一下…
    SVN 是不是無法紀錄檔案的權限?
    我在 linux 下檔案權限改好(chmod)以後,commit 再 export/checkout,發現檔案權限沒有修改成功
    如果想要操作 svn 裡原始碼檔案的權限(用烏龜或是linux下操作),請問該怎麼做呢…
    (我有找了相關的連結,但都沒看到相關的指令)
    謝謝您

  5. 嗯, 這個問題我也無解, 我的做法是, 先從 svn delete 掉後, 改完權限再 svn add & commit 上去.
    他只記得剛開始 add 後的權限(我的測試是這樣子).
    如果您有找到解法, 還請跟小弟說一下.. Orz..

  6. 我稍微找了一下解決方案:http://www.fwolf.com/blog/post/258
    及 google://svn chmod 出來的一些 link
    這問題其他人在以前就問過了
    但似乎都無解
    不過利用 post-commit,設定 commit 後自動 chmod
    還算可以解決這問題

  7. 呵呵, 這招也是很有趣, 我是都用之前說的方法, 不然就是寫 .sh 來做 chmod 的動作, 都忘了有 post-commit 可以用了, 感恩~ 🙂

  8. 妳好,像你請問一下,若是下面有一堆目錄,可以新增檔案或者是目錄,可以用svn import,來自動完成嗎?
    謝謝您!

  9. import 是在第一次使用的, 之後就不行了, 之後都要用 add 的, 不過應該可以 add *, 他會自動判斷, 已經加過的就不會再加進去了~
    這樣子應該跟 import 差不多吧? 🙂

  10. 後來執行了svn add /www/jsp/a/*
    ANS:svn: '/www/jsp/a' 不是工作副本
    svn: 無法開啟檔案 '/www/jsp/a/.svn/entries': 沒有此一檔案或目錄
    是因為當初沒有先從SVN機器上checkout嗎?
    謝謝你的回答

  11. 不好意思再請問一下
    那有沒有可能可以用svn import來達成呢?
    因為之前用cvs的時候是可以用omport的方式去達成
    謝謝你!!

  12. 我後來持續測試之後,發現就是在client使用TortoiseSVN
    在目錄上層按下svn COMMIT,可是他會彈出一個視窗
    讓你選擇有異動的檔案
    不知道這個部份,要怎麼用指令表示呢?
    svn commit path ??
    因為svn COMMIT可以直接幫你判別是新增還是修改或者是刪除
    真的很謝謝你!

  13. "這邊有簡單的 script, 可以讓您將新的檔案都變 add, 再 commit 即可"
    這樣的話只解決掉新增的問題
    但是修改跟刪除的話,用svn add是沒有用的
    變成需要用到svn update跟svn delete
    謝謝!

  14. 嗯嗯, 可以在目錄下使用 svn st, 就可以看到異動狀況了.
    不過, 刪除和修改這些, 我是沒有特別做, 因為 svn ci 就會自動帶到了 🙂

  15. 那這樣我曉得了
    就先執行svn commit 把修改跟刪除的進行處理
    之後再執行svn add語法把新增的也處理
    再進行svn commit這樣就全包了!!!
    雖然用烏龜SVN可以svn commit全包說~
    就可以少掉後面的步驟!
    多謝你!!

  16. 喔喔, 基本上兩者是一樣的, svn commit 是都一致的.
    我記得烏龜的 svn commit, 是出現很多 file, 然後讓你勾選是否要新增.
    你在 cli 狀況, 也是可以這樣子做, 先 svn add file 後, 再一起和 修改/刪除的一起 commit 就可以了 🙂
    加油囉~ 🙂

  17. 在 post-commit 自動 svn update 將錯誤訊息 log 起來,找出無法自動 post-commit 的原因:
    #post-commit 如果沒有這行會無法自動 post-commit
    #出處:http://www.php126.com/archives/562.html
    export LANG=zh_TW.UTF-8
    若系統編碼是 big5 則改成 export LANG=zh_TW.Big5

  18. 就是svn up之後
    有時候會出現
    G filename
    說這各檔被auto merge
    可是我不想他這樣做
    寧願看到
    c
    有辦法改成這樣嗎?
    謝謝~~

  19. 厄... 我們大家都只想看到 G, 不想看到 C 耶, 因為看到 G 代表他幫你合併好囉~
    不過我猜您是想知道他有修改了哪些東西~
    我通常都是直接看這版本和上一版本的 diff 就可以了(用 svn command 或 trac 來看)

  20. 不好意思,請問一下
    我安裝TortoiseSVN-1.5.3.13783-win32-svn-1.5.2跟svn-1.4.0後
    我在c:\建立一個folder:aaa
    按右鍵→SVN Checkout
    輸入網址,可是顯示 xml data was not well-formed的錯誤訊息
    google一下,相關資料很少
    是我少了設定什麼嗎?

    請多指教,謝謝

  21. 可用svn propset svn:executable "1" [file path] 試試,可參考http://twpug.net/docs/Subversion/#svn-ch-6-sect-2.3.1中的svn:executable

  22. 您好
    看到你的文章讓我了解很多,不過我是第一次碰linux,版本用的是ubuntu,之前用久了windows,所以不是很清楚這個系統的運作方式,在參考了TortoiseSVN的圖形化介面後,比較了解working copy跟repository是不同資料夾,但是在ubuntu下只要輸入指令就會產生出working copy,但是他是生在哪個目錄下,難道不用去指定一個路徑嗎?或者是我要先 cd 到我要的目錄下再做checkout的動作?

  23. 先 cd 到你要的目錄後, 再做 checkout 的動作.
    因為不曉得你的目錄狀況, 如果會很散亂, 建議就先建個目錄再 checkout 囉~ 🙂

  24. 假設我checkout一個working copy,想要cd到該目錄下輸入svn st的指令時,他顯示bash:cd: /home/svn/myproject/branches: No such file or directory所以有點搞不清楚checkout出來的東西跑哪了

  25. 權限不足, 代表有人已經建過那個目錄了 (tmp 應該是大家都可以存取的)
    再換個目錄名稱即可.
    發送訊息會變兩篇文章, 主要是滑鼠可能同時按了兩下. XD

  26. 因為最近遇到一個比較不一樣的case,他必須要
    包含一些*.o檔,例如:某些chip vendor 的device
    driver library.... 最好也一起上傳到 svn server
    作管理會比較方便,只是svn import 就是default不
    將 *.o 上傳,不知要如何是好????

  27. 感謝前輩的快速幫忙,我目前也只能利用 shell script
    方式結合 find ./ -iname "*" > file_list.txt;再一一自動化讓他去作 svn add "$a" ,唉~~~~
    只是這樣速度好慢,不知原本就400多M的 Source Code看看是否明天上班時可以上傳完畢....
    還是要說聲謝謝您 🙂

  28. 您好:
    目前部門正在評估一套版本控制軟體, 想請問一下, SVN是否可記錄check-in, check-out時間, 另外是否有記載每個版本check-in 的username, 可以經由client軟體顯示出來嗎? 謝謝.

  29. check-in 的時間, 和 check-in 的 username, 如果有 trac, 都可以顯示出來(windows client 我不熟).
    check-out 的時間, 目前知道的是不行, 不過如果 svn 走 http, 或許是可以從 access.log 來撈.

  30. 您好:
    過了一陣子又來請教您問題了!一直有個疑問是,在XP上的程式碼或者是資料夾要如何丟進ubuntu裡面?之前是灌了TortoiseSVN,但是我想應該不用這麼麻煩才對。難道要透過VirtualBox的共享資料夾來傳送檔案嗎?

  31. 厄, 我不懂您要做的事耶, svn commit ?
    如果是的話, XP 是都灌 TortoiseSVN 這套軟體來 commit.
    其它軟體我也不熟耶. 而且, 我沒在用 XP.. Orz..

  32. 假設我的程式碼在XP上,我想用Ubuntu的Subversion來做版本控制,我要如何將檔案從XP移動到Ubuntu裡面?之前的做法是在XP上用TortoiseSVN,設一個資料夾,選擇create repository here,之後在將XP上的程式碼丟進這個資料夾做check-in check-out的動作,資料夾的名稱位址要跟Ubuntu的一樣,這樣Ubuntu就可以看到XP上的檔案並做控制了。我想問的是有沒有其他方法,這樣似乎有點繁複,還有要如何將一整個資料夾的程式碼放到Ubuntu去呢?

  33. 厄, 直接在 local 建立一個資料夾, 把檔案都放進去.
    再來 svn add directory 就會順便把裡面的檔案都丟進去了.
    或者用 import 的方式(第一次)
    這不會複雜阿.. 還是你覺得要怎麼做??.. @.@a..

  34. 您好
    上次的問題已經解決了^^
    這次又有問題想請教一下,我用的是svn://沒有搭配SSH
    網上很少有關只有svn://這部分的權限設定文章
    結果就自己先照著其他協定的方式設定一次,發現跟version control with subversion所說的不同,他無法在svn://ip/後面輸入詳盡的path,例如:svn://ip/repo/project 會出現URL 'svn://ip/repo/project' doesn't exist所以才想說是不是有地方沒設定好?
    還是說只有svn://這個協定是只能輸入svn://ip/?

  35. 你好,請教分支branch/tag問題: 嘗試多種方式無法成功,且 browser 工作正常.
    #svn copy http://localhost/svn/evalbd http://localhost/svn/NetApp/branch/evalbd_branch
    svn: Server sent unexpected return value (403 Forbidden) in response to OPTIONS request for 'http://localhost/svn'
    #svn copy file: home/svn/evalbd file: home/svn/NetApp/branch/evalbd_branch
    svn: 無法開啟 URL 的 ra_local session
    svn: 無法開啟檔案庫 'file: home/svn'
    WorkSpace:
    ==================
    /home/allen/evalbd
    svn:
    ==================
    /home/svn/evalbd
    /home/svn/NetApp/branch/evalbd_branch
    subversion.conf:
    =====================
    DAV svn
    SVNParentPath /homesvn

  36. 抱歉我不了解你的意思!
    我要copy的來源和目的都在 /home/svn 之下, 為何說是不同 repository?
    還是我弄錯了呢?

  37. 是我搞錯了, 因為命名方式搞混了. Orz.
    想問一下, 是否已經有 /home/svn/NetApp/branch/ 這些目錄了? (在 SVN 裡面).
    如果沒有的話, 先試著把這些建出來再做 copy 動作看看?

  38. 先謝謝你快速回應!
    是的,我也有先建 svnadmin create /home/svn/NetApp/branch/evalbd_branch
    但結果就如我所 post

  39. 嗯嗯, 就跟我想的一樣. XD
    您建了兩個 repository.
    svn 要建 branch, 得要在同一個 repository.
    您不需要另外用 svnadmin create.
    您把 svn 的 /home/svn 當 file system 的觀念去想, 會比較容易懂~ 🙂

  40. 我嘗試以下操作,svn copy 還是有問題!
    ================================
    #svn import /home/allen/NetApp file: home/svn/NetApp/
    新增 /home/allen/NetApp/trunk
    新增 /home/allen/NetApp/trunk/hello
    新增 /home/allen/NetApp/trunk/hello/hello.c
    新增 /home/allen/NetApp/trunk/hello/hello.h
    新增 /home/allen/NetApp/branches
    新增 /home/allen/NetApp/tags
    #svn copy http://localhost/svn/NetApp/trunk/hello http://localhost/svn/NetApp/branches/hello_branch
    svn: Can't open file '/home/svn/NetApp/db/txn-current-lock': Permission denied

  41. 有影響, 因為您的 SVN 是走 Apache, 所以權限需要是 Apache 的權限.
    那解法就是改成 Apache 的權限, 或者就是開 777(大家都可讀寫), 就可以囉~ 🙂

  42. 我是用 TortoiseSVN -> Show Log(顯示紀錄),
    然後選取一個版本,然後選取位於畫面下方的檔案,最後按右鍵,
    會出現一個選項"Save Revision to..(儲存版本至..)",
    這樣可以複製到我指定的資料夾。
    現在問題是,複製過來的未包含其目錄,
    我希望能夠保留其路徑。是否有辦法達到呢?
    例如:
    [檔案庫]中是
    /dir_a/file_x
    /dir_b/dir_b_1/file_y
    /file_z
    [問題]是
    /file_x
    /file_y
    /file_z

  43. 想請問一下版主,如果現在我從別人電腦的檔案庫checkout一份code。然後我想要把這份code在commit到我電腦中的檔案庫中,請問我該怎麼下commit指令呢?(我已經用過一次import把basic版本import進去了,這次想把差異部分commit到我這台電腦做備份)

  44. 您好:
    原先別人在server上架設用vmware + redhat 3企業版架設 svn + apache2
    ,可以正常存取,但我接手後
    mount一個新的磁碟 /jason
    svn新增一個資料夾 /jason/repos
    設定/jason/repos/conf/authz
    [repos:/]
    jason=rw
    httpd.conf新增的設定也跟之前一樣

    DAV svn
    SVNParentPath /jason/repos
    Satisfy Any
    AuthType Basic
    AuthName "SVN Repository"
    AuthUserFile /jason/repos/conf/authz
    AuthzSVNAccessFile /jason/repos/conf/passwd
    Require valid-user

    請問:
    為什麼用ie連上去還是permission denid?
    http://my-ip/jason/repos
    PS:我已經將資料夾權限開至777

    1. 我不太清楚你是怎麼架設的, 不過, 一般都不會讓人可以存取根目錄.
      設定應該是在 repos 下面, 在建立一層 Project, 那個才是可以存取到的階層.
      (純屬猜測, 因為這個可能的原因太多了, 不知道怎麼架設, 沒辦法找問題, 參考看看囉~)

  45. Tsung兄
    請問您一下, 假設我有兩個修訂版1和2, 我在修訂版2裡執行[update to revision]回修訂版1, 接著回到修訂版1後, 進行修改, 再commit時, 就會發生錯誤
    Commit failed (details follow):
    File or directory 't1.txt' is out of date; try updating
    resource out of date; try updating
    請問這該怎麼解決, 因為用update好像就又會變回修訂版2,
    還是說這種案例不是這樣處理的

    謝謝

    1. svn 的一個優點是, 你可以 checkout 某個版本的某個檔案.
      所以, 要還原的話, 我都是在另一個地方, checkout 那個版本的檔案後, cp 回去蓋掉,
      在 commit log 寫 rollback. 🙂

  46. 有個問題想請教一下,假設我現在svn 已經到了100版, 如果我要切割成2份 一份1~ 70, 另外一份71之後開始算起, dump 版本我會,但是我把第二份load 進去的時候,版本編號會從1開始算起, 我應該怎麼修改版本編號?

    1. 這個我不知道耶, 理論上, 不應該會有修改版號這種事情耶.
      這是歷史紀錄, 如果歷史紀錄可以修改... 那就不叫歷史紀錄了. XD

  47. 不好意思,我的作法是這樣
    svnadmin dump -r50:100 /home/svn/src > /src_50-100
    svnadmin create src_50-100
    svnadmin load src_50-100 < /src_50-100

    可是這樣的話 src_50-100 的 svn 版號 會從1開始算起
    有沒有什麼方法可以當co 版本時可以從50開始算?

  48. 很抱歉問了這個奇怪的問題, 實際上我的server是一台4核的Desktop.
    每天都會備份所以將下列指令放在crontab內 dump source
    svnadmin dump /home/svn/source > /backup/source.bak
    可是我發現當系統執行這個指令的時候會不完全,實際上只dump 169版
    可是我的source已經到了200,所以才會有將source切割的想法

    ps :如果不透過crontab而直接在console下指令,卻不會有dump不完全的問題

  49. 版主您好:我想請問一下
    我已經有一個資料夾受到SVN版本的控制。
    其中其他的AutoBuild軟體(HudSon)每日會自動update那個資料夾並編譯出新版程式 。
    我該如何在Windows系統下寫一個批次檔batch檔自動去執行commit呢?
    我試過在批次檔裡寫如下的指令

    C:\Program Files\TortoiseSVN\bin\TortoiseProc.exe /command:commit /path:D:\Hudson\workspace\PowerCarBuild\build\newest_build /closeonend:1

    他會執行(打開)TortoiseSVN,但是並不會自動commit,必需要有人
    按下確認之後才會真正執行commit指令。但我想要的是他完全自動化
    不知道有沒有什麼解決的方式呢?非常謝謝回答

    1. 嗯嗯, Windows 你可能得要找一下 Command 的路徑, 做類似下述的事情:
      svn add *
      svn commit
      就可以做到你想要得事情了.

  50. 您好抱歉
    我在執行svn時遇到怡個很嚴重的問題
    當我輸入 svn -version
    系統回復:svn: invalid option character: e
    Type 'svn help' for usage.
    網路上說這代表已經安裝
    但是我在輸入 svn help
    系統回復:svn: E125001: Couldn't determine absolute path of '.'
    svn: E000002: No such file or directory
    這是啥麼意思?為啥不能使用?可以麻煩您為我解答嗎?拜託T>T

  51. 你好:
    可請問一下,那個如果svn commit上去了,但用svn info看時,時間是錯的,需要再那修改嗎?
    我的Fedora linux 時間已是正確.....

  52. 你好,這裡有個問題想要請教一下

    請先確認一下下面的語法

    :SVN_COMMIT
    set MSG=""
    svn commit -m %MSG%

    我這裡的
    set MSG=""
    內容想要填入目前使用電腦的日期時間
    如:20180909

    不知道在set MSG=""的""裡面是否可以填入這樣的變數呢?
    我最終是要寫在Windows平台的bat檔案

    感謝!

    1. 要設定變數當然是可以,只是 windows 的 bat 我太久沒寫過,而且手邊也沒有 Windows 可以測試,沒辦法告訴你怎麼寫..

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料