jasmine214--love

          只有當你的內心總是充滿快樂、美好的愿望和寧靜時,你才能擁有強壯的體魄和明朗、快樂或者寧靜的面容。
          posts - 731, comments - 60, trackbacks - 0, articles - 0

          別人的 svn 筆記 ~

          Posted on 2010-09-25 20:36 幻海藍夢 閱讀(2218) 評論(0)  編輯  收藏 所屬分類: Linux版本管理

          ------------------ 參考文檔 --------------------
          官方文檔: http://www.subversion.org.cn/svnbook/ 包括可下載的PDF 和一頁HTML。
          配置文檔: 去ubuntu的wiki吧~~ 如果用 svn + ssh 的話,基本不用配置,按下面“快速工作”即可。

          ------------------ 快速工作: -------------------
          1. 建立版本庫:
          我的方式,是用svn+ssh來訪問版本庫,這意味著:
          不用啟動svnserve守護進程,而是由每次ssh連接到版本庫時,自動啟動svnserve,工作完再退出svnserve進程。這些東西,都是本地的svn調用ssh讓它那樣做的。而啟動的svnserve進程的身份就是ssh用戶的身份,而ssh用戶來自于系統用戶,這就是這種方法的優點:就用系統用戶了。

          正因為如此,每個用戶是否對版本庫能讀寫,就依賴于版本庫的權限設置,就是你用svnadmin create生成的文件的權限設置。
          我的策略是,為了讓某些用戶讀寫版本庫,我創建了一個svn用戶,和一個svn組,然后在/home/svn下建立版本庫。然后把所有需要訪問svn的用戶,加到svn組中,并設置版本庫的所有文件,svn組的人都能夠讀寫。

          在版本庫機器上,具體如下:
          adduser svn            # 創建svn用戶和svn組
          gpasswd -a fengyi svn # 把fengyi用戶加到svn組
          svnadmin create /home/svn/buptnic # 創建版本庫buptnic
          chmod -R g+w /home/svn/buptnic     # 讓所有的文件為組可寫(因為默認一般是組可讀了)
          以上兩步,也可以改為,先用umask 0002,再用svnadmin 一樣的效果。因為默認的umask一般是0022,這會去掉組的寫權限。

          注意:一旦svnadmin create之后,其他的事情,就應該用svn在工作拷貝機器上做了。———— 要點是,大部分svn的子命令,最終效果都是操作版本庫,但是分兩種途徑。如果子命令帶URL的,一般對版本庫直接操作,如果不帶URL的,一般是先對工作拷貝進行操作,然后用commit使版本庫生效。當然,好多命令,即可以帶URL,也可以不帶,一般都是先update,再更改工作拷貝,再commit。

          在工作拷貝機器上,具體如下:
          svn mkdir svn+ssh://svn@210.25.137.252/home/svn/buptnic/flow # 建立flow項目目錄
          svn mkdir svn+ssh://svn@210.25.137.252/home/svn/buptnic/flow/trunk # 建立flow/trunk目錄
          svn mkdir svn+ssh://svn@210.25.137.252/home/svn/buptnic/flow/branches # 建立flow/branches目錄
          svn mkdir svn+ssh://svn@210.25.137.252/home/svn/buptnic/flow/tags # 建立flow/tags目錄

          svn import /home/echo/src svn+ssh://svn@210.25.137.252/home/svn/buptnic/flow/trunk # 將本地的src下的源文件導入到版本庫的trunk目錄下。注意,trunk是主分支,一般習慣是放任何東西,包括文檔,第三方庫。

          然后,就OK了,你可以找個地方,用fengyi用戶做checkout了。
          svn checkout svn+ssh://fengyi@210.25.137.252/home/svn/buptnic/flow

          注意的是:版本庫中,雖然你通過mkdir建立了那些目錄,上傳了那些文件,但是,你是在/home/svn/buptnic/flow中直接看不到的,它們都放在flow 下的db目錄中,是虛擬文件系統里。

          2. 用戶基本操作原則:
          (1) 不管是 版本庫 還是 工作拷貝,他們的維護文件,都在他們的文件夾內,所以,如果要刪除他們,直接用文件系統的rm即可徹底刪除。
          (2) 用svn子命令,對版本庫的直接操作,必須用一種形式的URL,而不能是普通文件路徑,包括在版本庫機器上!!!!!但是svnadmin等命令,就是直接用普通文件路徑來操作版本庫,并要求在版本庫機器上執行。
          (3) 在工作拷貝的哪個目錄執行 svn 子命令,該命令的最后一個參數,默認就是當前目錄,這使得命令的效果從當前目錄開始作用。
          這從每個目錄里有一個.svn看得出來,每個目錄都有維護文件,都可以單獨工作。這也是工作拷貝的不同部分允許不同版本號的基礎。
          (4) commit只有當當前目錄下所有文件的版本號 等于 版本庫當前版本號時,才能成功。
          工作拷貝的不同部分允許不同版本號,所以,當你commit時,可能當前目錄下,比如各個子目錄里 的版本號并不同,如果有比版本庫低的版本號,commit就不能成功,提示信息是 ... out of date ...,這時,你需要update一次,然后,再commit。當然,其他很多情形,也可能導致這種情況,最典型的就是(5)中文件沖突的情況。
          (5) 先在工作拷貝上操作,然后commit到版本庫。
          除了修改文件以外的任何操作,都用svn子命令完成,比如添加一個文件,創建之后,用svn add添加到本地拷貝。當你覺得本次的工作拷貝工作結束時,可以將其commit到版本庫,使得版本庫更新到新的revision。
          (6) 解決沖突
          解決沖突最好的辦法,就是兩個人不要編輯同一個文件。否則,見下面或資料,你就需要update一次,來合并兩人的文件(因為別人先commit了,版本庫里的版本號比自己的高,自己不會commit提交成功,需要先update)。如果需要手工解決沖突,見下面的解決辦法。
          (7) 是的,如果兩個分支獨立發展太久,則必然改動較大,那merge是會有沖突的,你還是要手動解決。
          merge和update沖突時,生成的沖突臨時文件名不同,但是源文件,都是被沖突標志標注了的,你只需要改源文件即可。里面<<<到>>>部分,是沖突區域,即svn認為,在這個區域上,兩個文件各自發展了自己的修改,所以第一個文件的修改,放到<<<和===中,第二文件的修改,放到===和>>>中,你自己選擇,保留哪個修改。如果某個修改為空,即如===和>>>中沒有代碼,那說明“修改”就是“刪除”操作。
          所以,當我們把branches的文件merge到trunk時,得考慮清楚了,因為branches在修改bug,而trunk在增加新特性,為了把branches的bug修改通過merge引入trunk,是很可能導致沖突的。
          (8) revert 和 merge
          revert是在版本內恢復,即:當commit后,就是一個版本了,之后,如果更改了任何東西,但是還沒有commit的話,就可以恢復到上次commit后的狀態。revert不依靠版本庫,僅靠.svn目錄來維護信息。
          而merge,則是依賴版本庫,做的則是版本間的差異比較,從而作用于某個目錄。使得內容恢復到某個版本狀態。
          (9) 忘了的命令,用svn help subcmd 來查閱。
          (10) diff, status, log 怎么用阿?
          下面是trunk目錄下,svn status -v 的輸出:
                         28       28 fengyi       .                                 
                         28       26 fengyi       sheep                             
                         28       26 fengyi       sheep/sheep.c                     
                         28       20 svn          main.c                            
                         28       28 fengyi       cow                               
                         28       28 fengyi       cow/main2.c
          注意到:第一列是當前工作拷貝的版本號,是因為在trunk update后導致所有文件的版本號變為最新。但是,后面的一列數字,表明自那個版本號以來,文件沒有改過(不保證版本庫沒有更新)。你用svn log看那個文件,也只能看到那個號版本,看不到當前工作拷貝的版本號(沒改,沒commit,怎么可能有log!)


          -------------------- 筆記 ---------------------

          第一章 基本概念
          svn就是能夠跟蹤數據變化的文件服務器
          “拷貝-修改-合并”模型而不是“鎖定-修改-解鎖”(見保存的圖)
          每當版本庫由用戶commit了一個提交,文件系統進入了一個新的狀態,叫做一次修訂(revision),每一個修訂版本被賦予一個獨一無二的自然數,commit顯然是原子操作。同時,可以看出,版本庫沒有回退的概念,只有工作拷貝有這個概念,版本庫只不過一直在往前走。
          (許多其它版本控制系統使用每文件一個修訂號的策略,所以會感覺這些概念有點不一樣。)
          SVN概念中,版本庫的修訂版本是統一的,就是說,任何時候,每個文件的“修訂版本”都是一樣的。
          但是工作拷貝中經常是“混合修訂版本”,因為你只提交一個文件,導致版本庫中修訂版本加1,這時,你的工作拷貝中這個文件的修訂版本也加1,但是工作拷貝中其他的文件,只能維持原版本號,除非你update一次。
          這是很有用的一個特性,它允許工作拷貝的任何一個部分在歷史中前進或后退。

          svn有一個基本原則就是“推”動作不會導致“拉”,反之亦然。


          svn commit & svn update 和 四種狀態 (是否修改+是否當前)

          svn status --verbose 檢查“混合修訂版本”
          svn log 顯示一個文件或目錄的歷史修改信息。

          $ svn checkout http://svn.example.com:9834/repos
          $ svn checkout file:///path/to/repos
          $ svn checkout file://localhost/path/to/repos
          C:\> svn checkout file:///X:/path/to/repos

          $ svn checkout http://svn.example.com/repos/calc
          $ svn commit button.c -m "Fixed a typo in button.c."
          $ svn update

          Subversion可以通過多種方式訪問版本庫!!
             ———— 一個重要意思是說:各種svn的子命令,都可以直接訪問版本庫。如果你在版本庫機器上,那么就用file:///,如果你在自己機器上,就用下面四種方式。
             ———— 但是,你怎么只操作本地的工作拷貝呢,以為你想在本地改,改完后再commit,那就不要加這些東西了,直接是文件名,或者不加就好。
          模式    訪問方法
          file:///     直接版本庫訪問(本地磁盤)
          http://     通過配置Subversion的Apache服務器的WebDAV協議
          https://     與http://相似,但是包括SSL加密。
          svn://     通過svnserve服務自定義的協議
          svn+ssh://     與svn://相似,但通過SSH封裝。

          但是注意:一般的做法,還是先update,merge,copy等命令把版本庫數據弄到工作拷貝,修改好工作拷貝后,再commit,這會導致版本庫的進入下一個revision。
          如果直接在版本庫中操作的,比如copy,delete等,也會使得版本庫進入下一個reversion.

          第二章 基本使用
          svn help SUBCOMMAND
          1. 創建版本庫
          創建新的版本庫名 newrepos
          $ svnadmin create /usr/local/svn/newrepos
          將mytree下未版本化的文件,導入該版本庫,文件放在some/project下,沒有mytree文件夾了。
          $ svn import mytree file:///usr/local/svn/newrepos/some/project -m "Initial import"
          注意:import后的路徑,可以在版本庫上,也可以在自己機器上。一般,可以在自己機器上的代碼,直接這樣導入服務器上的版本庫。
          列出newrepos版本庫中某文件夾下的文件。
          $ svn list file:///usr/local/svn/newrepos/some/project

          推薦的版本庫布局: 這里有paint和calc兩個項目
          $ svn list file:///usr/local/svn/repos
          /paint/trunk
          /paint/branches
          /paint/tags
          /calc/trunk
          /calc/branches
          /calc/tags
          /vender/vendorlib1/current #供方最新版本
          /vender/vendorlib1/1.0      #上次最新版本的快照(svn copy)

          注意:文件夾用 svn mkdir 創建。看你在版本庫主機上還是工作拷貝主機上,選用上面某一個URL可以對版本庫進行操作。

          2. 初始化檢出
          在本地創建一個工作拷貝,這個拷貝可能僅僅是一個版本庫中的一個文件夾。
          $ svn checkout http://svn.collab.net/repos/svn/trunk
          同上,只不過,在本地創建的是subv目錄,而不是trunk目錄。
          $ svn checkout http://svn.collab.net/repos/svn/trunk subv


          3. 基本的工作周期
          更新你的工作拷貝
                      svn update
          做出修改: 只有修改一個文件,可以直接修改,其他任何對文件和目錄的操作,均是先通過以下命令在工作拷貝生效,然后,你下次update的時候,才在版本庫生效。這種狀態,常見英文為: sth is scheduled for addition.(比如這個文件是add處理的)
                      svn add foo    (先vim foo,然后用add命令添加)
                      svn delete foo (但是只有在update時,版本庫和工作拷貝內的刪除才會生效)
                      svn copy foo bar
                      svn move foo bar
                  svn mkdir foo (等于mkdir foo; snv add foo)
          檢驗修改: 在你提交你的工作拷貝時,檢查一下修改了哪些東西是個好習慣,這不需要網絡(不需要和版本庫比對)
                      svn status (瀏覽所做的修改,傳說中用的最多的命令)
                          -v 顯示所有文件
                          -u 這個文件常用于預測update前的沖突。會聯系版本庫,看是否工作拷貝里,有過期的文件,以 * 標注。
                                  可能的狀態碼為:
                      A   # file is scheduled for addition
                      C   # file has textual conflicts from an update
                      D   # file is scheduled for deletion
                      M   # the content in bar.c has local modifications
                                  ?   # 這個文件還沒有版本化,你需要用svn add
                      svn diff    (檢查修改的詳細信息,通過 svn diff > patchfile 可以生成補丁文件)
          可能會取消一些修改
                      svn revert (任何修改,然后用revert就可以撤銷任何schedule 的操作,即上次update以來 schedule的操作)
          解決沖突(合并別人的修改)
                      svn update (只要版本庫被別人修改,你鐵定不能commit,必須update一次,而update會嘗試合并被人修改過的版本庫和工作拷貝,生成新的工作拷貝,下面U表示更新(你沒有修改,但是版本庫被修改),G表示合并(你修改了,版本庫也修改了,兩者可以合并),C表示沖突(你修改了,版本庫修改了,兩者不能按照一定規則合并)。如果是C存在,那么你必須解決沖突,svn才能允許你下次commit。如果有沖突,那么對應bar.c 會有三個臨時文件被生成,它們是bar.c.mine, bar.c.rR1(你上次update時的文件), bar.c.rR2(版本庫中的最新版本號的文件)。這個三個臨時文件,會阻止你commit。此時的svn只是要求你考慮下更改沖突的文件,如果考慮好了,用svn resolved bar.c來告訴svn,你改好了,然后resolved會自動刪除這三個臨時文件,然后,你再commit,就行了!所以,svn只是要求你考慮清楚后,刪除這三個文件,它就可以commit了,不管你到底是不是真的改恰當了,這還是你的事,所以,如果不用svn resolved,而是直接刪除這三個文件,也是可以commit的。另外,這三個文件,可以用于你查閱,如果愿意的話。
                      更改沖突文件,通常可以:直接編輯沖突文件;用bar.c.rR2(R2 > R1)來替換bar.c;或者直接用svn revert來恢復文件到上次update時的狀態。如果是前面兩種方法,要接上svn resolved來告訴svn,沖突已解決好了,可以允許自己commit了。
                          $ svn update
                  U INSTALL
                  G README
                  C bar.c
                  Updated to revision 46.
                      svn resolved
          提交你的修改
                    只有當你的工作拷貝的版本號=版本庫版本號時,才能提交成功!!!(小于就得先update,大于是不可能的)
                      svn commit -m "message"/ -F logfile


          4. 檢驗歷史:
          (1) svn log   (從下面就看出每次 commit時 -m 的重要性了,對于追溯很重要)
          $ svn log
          ------------------------------------------------------------------------
          r3 | sally | Mon, 15 Jul 2002 18:03:46 -0500 | 1 line
          Added include lines and corrected # of cheese slices.
          ------------------------------------------------------------------------
          r2 | harry | Mon, 15 Jul 2002 17:47:57 -0500 | 1 line
          Added main() methods.
          ------------------------------------------------------------------------
          r1 | sally | Mon, 15 Jul 2002 17:40:08 -0500 | 1 line
          Initial import
          ------------------------------------------------------------------------

          $ svn log -r 5:19    # shows logs 5 through 19 in chronological order
          $ svn log -r 19:5    # shows logs 5 through 19 in reverse order
          $ svn log -r 8       # shows log for revision 8
          $ svn log foo.c
          $ svn log http://foo.com/svn/trunk/code/foo.c

          注意:
          a. 加上 -v 能顯示文件和目錄的移動和復制 等 “路徑修改” 信息,這可以用于找出刪除的項目。
          b. 如果 svn log -r 8 沒有輸出信息,那請在后面跟出版本庫的路徑。

          (2) svn diff
          $ svn diff                   #比較工作拷貝和.svn中存的上次update時的版本。
          $ svn diff -r 3 rules.txt    #比較工作拷貝和版本庫3版
          $ svn diff -r 2:3 rules.txt #比較版本庫的2版和3版。
          (3) svn cat
          $ svn cat -r 2 rules.txt   #查看版本庫2版
          (4) svn list
          缺省列出的是當前工作拷貝對應的版本庫的URL下的東西,當然,你可以直接寫出版本庫。
          $ svn list -v http://svn.collab.net/repos/svn

          5. 時間機: ———— 注意:版本庫沒有回退的概念,只有你的工作拷貝有回退的概念!!
          (1) 將工作拷貝,回退到以往某個版本: ———— 但注意,根據commit原理,這種回退的工作拷貝,你是無法commit的了。如果,你原意是想回退后,以后還能繼續提交,那應該用svn merge!!!!
          $ svn checkout -r 1729 # Checks out a new working copy at r1729
          $ svn update -r 1729 # Updates an existing working copy to r1729
          (2) 將版本庫的1729版本打包。
          $ svn export http://svn.example.com/svn/repos1 -r 1729

          6. 清理:
          status發現有L的,表明是鎖住了,這通常是由于svn上次要修改,所以鎖住,但是由于某種原因,進程退出了,所以鎖還在,這是用cleanup命令清除即可。
          $ svn status
          L    somedir
          M      somedir/foo.c

          $ svn cleanup
          $ svn status
          M      somedir/foo.c


          第三章 高級主題
          1. 去掉未版本化的文件:
          你當然不想讓臨時文件擾亂版本庫,也讓svn方法有svn自身提供的兩種方法,見這一章相應部分。我還是覺得復雜。
          那就當svn add 和 import時,后面顯示指定出文件名,而不是默認讓它遞歸查找所有的文件和目錄。
          2. 鎖定:
          如果你想當你update后,就能鎖住某些版本庫的話。這樣使得一些非文本的對象,不會由于交替操作發生錯誤,如圖像處理。
          3. 其他很多高級主題。
          見章節中。


          第四章 分支與合并
          當你創建了一個版本庫時(svnadmin create),里面的目錄和文件可以用 svn copy 或者 svn move來移動。但不能在不同版本庫間移動。
          1. 分支:
          “分支”,沒有被SVN賦予特殊的意義,我們稱用 svn copy 后的新的目錄,為一個分支,但對于svn來講,只是一個普通目錄。
          (1) 創建分支:
          由于分支是對版本庫的操作,所以copy后的兩個參數都是版本庫URL,如果你在版本庫機器上,用file:///一樣。
          $ 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."
          上面,也說明了分支放置的地方,在branches里,新建一個my-calc-branch。以后,也可以在branches里建立其他新的分支。
          (2) 版本號還是往前走!
          由于svn的一個版本庫內部沒有“分支”的內建概念,所以不管哪個“分支”被commit了,都會導致版本庫的版本號往前走。

          2. 合并:
          “合并”,即 svn merge 做的事,就是比較版本庫中兩個版本的區別,并把區別應用于你的工作拷貝。這沒有什么限制,兩個版本可以是任何兩個版本,你的工作拷貝,也可以是你本地的任何一個“分支”。但是,這個命令拿來干嘛呢?? 就是為了使得兩個“分支”能夠合并一些共同的東西,比如一個分支做了一些錯誤修改,另一個分支也應該跟著改。但是,這些修改是通過比較哪兩個版本,這就要靠你自己判斷了,一般是看別人用commit -m參數,提交的說明,比如它說,這次提交,修改了xxx,那你就可以比較這次提交和上次版本的差別,然后應用于自己的工作拷貝,這就是所謂的“合并”。
          如果不能合并,不能合并的文件前,會打印C,就同update一樣。這往往表明,你選了錯誤的兩個版本作比較,使得差別不能應用于拷貝。這時,可用svn revert --recursive恢復修改。
          另外,merge必須經常做,如果你打算維護兩個相關的分支的話。否則,長時間不做,merge起來,會沖突很多,不好解決。

          下面是些用法:
          $ svn merge -c 344 http://svn.example.com/repos/calc/trunk #默認合并到當前工作目錄
          $ svn merge -c 344 http://svn.example.com/repos/calc/trunk my-calc-branch
          $ 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

          不太懂 --ignore-ancestry 的用途,這個用于比較兩個不相關的目錄樹

          3. 典型例子:
          (1) 把某個branch合并到trunk
          先進入工作拷貝里的trunk目錄,使得后面svn merge是針對這個工作拷貝。
          $ cd calc/trunk
          $ svn update
          At revision 405.

          用于merge的兩個版本庫版本,是my-calc-branch誕生時的版本341和目前的版本405。注意,這僅僅是對第一次merge,但是如果你后來又修改了分支,你還想merge,那顯然,從406到目前的版本即可。最新版本,可用HEAD代替。不知道,就看上面svn update,告訴你最新是405。或者用svn log查詢。
          $ svn merge -r 341:405 http://svn.example.com/repos/calc/branches/my-calc-branch
          U   integer.c
          U   button.c
          U   Makefile

          檢查一下狀態,不要有沖突的
          $ svn status
          M   integer.c
          M   button.c
          M   Makefile

          # ...examine the diffs, compile, test, etc...

          然后提交,就可以完成合并到trunk。
          $ svn commit -m "Merged my-calc-branch changes r341:405 into the trunk."
          Sending        integer.c
          Sending        button.c
          Sending        Makefile
          Transmitting file data ...
          Committed revision 406.

          (2) 恢復工作拷貝到以前版本:
          注意是303后面跟302,后面的小,這樣就能夠使得工作拷貝,回到以前的版本!! 這樣之后,是可以commit的,這不同于用checkout和update得到的以前版本,這種情況下無法commit.
          $ svn merge -r 303:302 http://svn.example.com/repos/calc/trunk
          U integer.c

          $ svn status
          M integer.c

          $ svn diff

          # verify that the change is removed


          $ svn commit -m "Undoing change committed in r303."
          Sending        integer.c
          Transmitting file data .
          Committed revision 350.

          (3) 恢復單個文件到以前版本:
          如果你想對單個文件回溯? 那還是用svn copy把,它能夠直接把某個版本的文件拷貝到你當前的工作拷貝。如:
          拷貝807版本的real.c到工作拷貝的當前目錄
          $ svn copy -r 807 \
                     http://svn.example.com/repos/calc/trunk/real.c ./real.c
          查看狀態
          $ svn status
          A +   real.c

          提交修改
          $ svn commit -m "Resurrected real.c from revision 807, /calc/trunk/real.c."
          Adding         real.c
          Transmitting file data .
          Committed revision 1390.

          (4) 當然,你可以選擇直接在版本庫中恢復文件和文件夾:
          這所謂恢復,其實就是進入下一個revision,注意下面例子中revision號的變化。
          比如你用這個刪除了:
          $ svn delete http://svn.example.com/repos/calc/branches/my-calc-branch \
                       -m "Removing obsolete branch of calc project."
          Committed revision 375.
          你可以用這個來恢復:
          $ svn copy -r 374 http://svn.example.com/repos/calc/branches/my-calc-branch \
                            http://svn.example.com/repos/calc/branches/my-calc-branch
          Committed revision 376.



          4. 常用分支模式:
          大多數軟件存在這樣一個生命周期:編碼、測試、發布,然后重復。這樣有兩個問題,第一,開發者需要在質量保證小組測試假定穩定版本時繼續開發新特性,新工作在軟件測試時不可以中斷,第二,小組必須一直支持老的發布版本和軟件;如果一個bug在最新的代碼中發現,它一定也存在已發布的版本中,客戶希望立刻得到錯誤修正而不必等到新版本發布。

          (1) 永久分支:
          一般trunk做主分支(給開發者),branches做發布分支(給測試員測試,不允許添加特性,僅做bug修復),tag做打包分支(給用戶):
          這是版本控制可以做的幫助,典型的過程如下:
              * 開發者提交所有的新特性到主干。 每日的修改提交到/trunk:新特性,bug修正和其他。
              * 這個主干被拷貝到“發布”分支。 當小組認為軟件已經做好發布的準備(如,版本1.0)然后/trunk會被拷貝到/branches/1.0。
              * 項目組繼續并行工作,一個小組開始對分支進行嚴酷的測試(一般只允許做bug修復性的提交),同時另一個小組在/trunk繼續新的工作(如,添加新特性,準備2.0)。兩邊發現的bug,可以相互merge。注意,這種分支,也就是“維護某個版本”的由來。即不會添加新特性了,如果OK了,就放到tags里,然后以后有bug,也繼續在分支改。
              * 分支已經作了標簽并且發布,當測試結束,/branches/1.0作為引用快照已經拷貝到/tags/1.0.0,這個標簽被打包發布給客戶。
              * 分支多次維護。當繼續在/trunk上為版本2.0工作,bug修正繼續從/trunk運送到/branches/1.0,如果積累了足夠的bug修正,管理部門決定發布1.0.1版本:拷貝/branches/1.0到/tags/1.0.1,標簽被打包發布。

          整個過程隨著軟件的成熟不斷重復:當2.0完成,一個新的2.0分支被創建,測試、打標簽和最終發布,經過許多年,版本庫結束了許多版本發布,進入了“維護”模式,許多標簽代表了最終的發布版本。
          (2) 臨時分支:
          有時,可能做些trunk的臨時分支,以開發某種特性,或做較大更改。
          這些分支,一旦開發結束,就merge入主分支,并刪除自己。
          (3) 供方分支:
          顯然,我們需要用到別人提供的庫。但是,我們怎么用呢?一般是,放到我們的版本庫中,準備一個current目錄,將其放入,然后做快照到如1.0。然后拷貝到brunch中做使用和定制。然后,一旦有新版本發布,我們想用的話,把最新版本替換current,然后和1.0做比較,用merge將修改應用于brunch中的版本。
          目錄結構為:
          在repos根目錄下,再創建一個vender目錄,庫名叫libcomplex比如,就創建libcomplex目錄,在里面再創建current放最新版本,用1.0放上次版本的快照(svn copy)
          -------- 從文檔上摘抄的例子:---------
          也許一個例子有助于我們闡述這個算法,我們會使用這樣一個場景,我們的開發團隊正在開發一個計算器程序,與一個第三方的復雜數字運算庫libcomplex關聯。我們從供方分支的初始創建開始,并且導入供方drop,我們會把每株分支目錄叫做libcomplex,我們的代碼drop會進入到供方分支的子目錄current,并且因為svn import創建所有的需要的中間父目錄,我們可以使用一個命令完成這一步。

          $ svn import /path/to/libcomplex-1.0 \
                       http://svn.example.com/repos/vendor/libcomplex/current \
                       -m 'importing initial 1.0 vendor drop'


          我們現在在/vendor/libcomplex/current有了libcomplex當前版本的代碼,現在我們為那個版本作標簽(見“標簽”一節),然后拷貝它到主要開發分支,我們的拷貝會在calc項目目錄創建一個新的目錄libcomplex,它是這個我們將要進行自定義的供方數據的拷貝版本。

          $ svn copy http://svn.example.com/repos/vendor/libcomplex/current \
                     http://svn.example.com/repos/vendor/libcomplex/1.0      \
                     -m 'tagging libcomplex-1.0'

          $ svn copy http://svn.example.com/repos/vendor/libcomplex/1.0 \
                     http://svn.example.com/repos/calc/libcomplex        \
                     -m 'bringing libcomplex-1.0 into the main branch'


          我們取出我們項目的主分支—現在包括了第一個供方釋放的拷貝—我們開始自定義libcomplex的代碼,在我們知道之前,我們的libcomplex修改版本是已經與我們的計算器程序完全集成了。 [23]

          幾周之后,libcomplex得開發者發布了一個新的版本—版本1.1—包括了我們很需要的一些特性和功能。我們很希望升級到這個版本,但不希望失去在當前版本所作的修改。我們本質上會希望把我們當前基線版本是的libcomplex1.0的拷貝替換為libcomplex 1.1,然后把前面自定義的修改應用到新的版本。但是實際上我們通過一個相反的方向解決這個問題,應用libcomplex從版本1.0到1.1的修改到我們修改的拷貝。

          為了執行這個升級,我們取出一個我們供方分支的拷貝,替換current目錄為新的libcomplex 1.1的代碼,我們只是拷貝新文件到存在的文件上,或者是解壓縮libcomplex 1.1的打包文件到我們存在的文件和目錄。此時的目標是讓我們的current目錄只保留libcomplex 1.1的代碼,并且保證所有的代碼在版本控制之下,哦,我們希望在最小的版本控制歷史擾動下完成這件事。

          完成了這個從1.0到1.1的代碼替換,svn status會顯示文件的本地修改,或許也包括了一些未版本化或者丟失的文件,如果我們做了我們應該做的事情,未版本化的文件應該都是libcomplex在1.1新引入的文件—我們運行svn add來將它們加入到版本控制。丟失的文件是存在于1.1但是不是在1.1,在這些路徑我們運行svn delete。最終一旦我們的current工作拷貝只是包括了libcomplex1.1的代碼,我們可以提交這些改變目錄和文件的修改。

          我們的current分支現在保存了新的供方drop,我們為這個新的版本創建一個新的標簽(就像我們為1.0版本drop所作的),然后合并這從個標簽前一個版本的區別到主要開發分支。

          $ cd working-copies/calc
          $ svn merge http://svn.example.com/repos/vendor/libcomplex/1.0      \
                      http://svn.example.com/repos/vendor/libcomplex/current \
                      libcomplex
          … # resolve all the conflicts between their changes and our changes
          $ svn commit -m 'merging libcomplex-1.1 into the main branch'





          5. 聰明的switch
          svn switch可以把工作拷貝的全部或部分,邏輯上轉換為 其他分支 的工作拷貝! 這是繼前面,一個工作拷貝中可以混合不同版本后,又一種混合方式 ———— 混合不同的分支的部分。 它表現得像update!!
          舉個例子,你的工作拷貝目錄是/calc/trunk,你已經做了很多修改,然后你突然發現應該在分支上修改更好,沒問題!你可以使用svn switch使得工作拷貝邏輯上變為分支的工作拷貝,而你本地修改還會保留,你可以測試并提交它們到分支。

          如果服務器做了svn move造成文件移動,那么 svn update會?? 必須用svn switch??

          6. 建立標簽:
          標簽就是一次正式發行打包。這里再次說明了:標簽和分支一樣,都是人為的概念,對于svn來說,都是用svn copy制造的“快照”。比如標簽就是從trunk拷貝到tags,或者從測試的branch拷貝到tags。

          但是,需要用一種方法,來禁止用戶提交commit,因為標簽概念上,不允許修改了,只是歷史沉淀。
          怎么做呢??? svn+ssh的話,用基本文件系統的權限來解決吧。
          http://hi.baidu.com/00%C6%F3%B6%EC/blog/item/c2bb0245d00dd03786947321.html

          主站蜘蛛池模板: 麦盖提县| 芜湖县| 鄂托克前旗| 民权县| 宁城县| 潮州市| 丰顺县| 延长县| 巴中市| 自贡市| 金山区| 塔河县| 新兴县| 华池县| 辛集市| 清流县| 博罗县| 常德市| 罗山县| 资溪县| 绵竹市| 云南省| 元谋县| 东明县| 海阳市| 门头沟区| 松溪县| 山阴县| 栾城县| 江门市| 通化县| 连平县| 江城| 宁海县| 贺州市| 山丹县| 曲阜市| 合阳县| 龙游县| 曲松县| 高陵县|