<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ### 賣主分支 當開發軟件時有這樣一個情況,你版本控制的數據可能關聯于或者是依賴于其他人的數據,通常來講,你的項目的需要會要求你自己的項目對外部實體提供的數據保持盡可能最新的版本,同時不會犧牲穩定性,這種情況總是會出現―只要某個小組的信息對另一個小組的信息有直接的影響。 舉個例子,軟件開發者會工作在一個使用第三方庫的應用,Subversion恰好是和Apache的Portable Runtime library(見[“Apache可移植運行庫”一節])有這樣一個關系。Subversion源代碼依賴于APR庫來實現可移植需求。在Subversion的早期開發階段,項目緊密地追蹤APR的API修改,經常在庫代碼的“流血的邊緣”粘住,現在APR和Subversion都已經成熟了,Subversion只嘗試同步APR的經過良好測試的,穩定的API庫。 現在,如果你的項目依賴于其他人的信息,有許多方法可以用來嘗試同步你的信息,最痛苦的,你可以為項目所有的貢獻者發布口頭或書寫的指導,告訴他們確信他們擁有你們的項目需要的特定版本的第三方信息。如果第三方信息是用Subversion版本庫維護,你可以使用Subversion的外部定義來有效的“強制”特定的版本的信息在你的工作拷貝的的位置(見[“外部定義”一節])。 但是有時候,你希望在你自己的版本控制系統維護一個針對第三方數據的自定義修改,回到軟件開發的例子,程序員為了他們自己的目的會需要修改第三方庫,這些修改會包括新的功能和bug修正,在成為第三方工具官方發布之前,只是內部維護。或者這些修改永遠不會傳給庫的維護者,只是作為滿足軟件開發需要的單獨的自定義修改存在。 現在你會面對一個有趣的情形,你的項目可以用某種脫節的樣式保持它關于第三方數據自己的修改,如使用補丁文件或者是完全的可選版本的文件和目錄。但是這很快會成為維護的頭痛的事情,需要一種機制來應用你對第三方數據的自定義修改,并且迫使在第三方數據的后續版本重建這些修改。 這個問題的解決方案是使用*賣主分支*,一個賣主分支是一個目錄樹保存了第三方實體或賣主的信息,每一個賣主數據的版本吸收到你的項目叫做*賣主drop*。 賣主分支提供了兩個關鍵的益處,第一,通過在我們的版本控制系統保存現在支持的賣主drop,你項目的成員不需要指導他們是否有了正確版本的賣主數據,他們只需要作為不同工作拷貝更新的一部份,簡單的接受正確的版本就可以了。第二,因為數據存在于你自己的Subversion版本庫,你可以在恰當的位置保存你的自定義修改―你不需要一個自動的(或者是更壞,手工的)方法來交換你的自定義行為。 ### 常規的賣主分支管理過程 管理賣主分支通常會像這個樣子,你創建一個頂級的目錄(如`/vendor`)來保存賣主分支,然后你導入第三方的代碼到你的子目錄。然后你將拷貝這個子目錄到主要的開發分支(例如`/trunk`)的適當位置。你一直在你的主要開發分支上做本地修改,當你的追蹤的代碼有了新版本,你會把帶到賣主分支并且把它合并到你的`/trunk`,解決任何你的本地修改和他們的修改的沖突。 也許一個例子有助于我們闡述這個算法,我們會使用這樣一個場景,我們的開發團隊正在開發一個計算器程序,與一個第三方的復雜數字運算庫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' … ~~~ 我們取出我們項目的主分支―現在包括了第一個賣主drop的拷貝―我們開始自定義libcomplex的代碼,我們知道,我們的libcomplex修改版本是已經與我們的計算器程序完全集成。 幾周之后,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' … ~~~ 在這個瑣碎的用例里,第三方工具的新版本會從一個文件和目錄的角度來看,就像前一個版本。沒有任何libcomplex源文件會被刪除、被改名或是移動到別的位置―新的版本只會保存針對上一個版本的文本修改。在完美世界,我們對呢修改會干凈得應用到庫的新版本,不會產生任何并發和沖突。 但是事情總不是這樣簡單,實際上源文件在不同的版本間的移動是很常見的,這種過程復雜性可以確保我們的修改會一直對新的版本代碼有效,可以很快使形勢退化到我們需要在新版本手工的重新創建我們的自定義修改。一旦Subversion知道了給定文件的歷史―包括了所有以前的位置―合并到新版本的進程就會很簡單,但是我們需要負責告訴Subversion賣主drop之間源文件布局的改變。 ### **svn_load_dirs.pl** 不僅僅包含一些刪除、添加和移動的賣主drops使得升級第三方數據后續版本的過程變得復雜,所以Subversion提供了一個**svn_load_dirs.pl**腳本來輔助這個過程,這個腳本自動進行我們前面提到的常規賣主分支管理過程的導入步驟,從而使得錯誤最小化。你仍要負責使用合并命令合并第三方的新版本數據合并到主要開發分支,但是**svn_load_dirs.pl**幫助你快速到達這一步驟。 一句話,**svn_load_dirs.pl**是一個增強的**svn import**,具備了許多重要的特性: - 它可以在任何有一個存在的版本庫目錄與一個外部的目錄匹配時執行,會執行所有必要的添加和刪除并且可以選則執行移動。 - 它可以用來操作一系列復雜的操作,如那些需要一個中間媒介的提交―如在操作之前重命名一個文件或者目錄兩次。 - 它可以隨意的為新導入目錄打上標簽。 - 它可以隨意為符合正則表達式的文件和目錄添加任意的屬性。 **svn_load_dirs.pl**利用三個強制的參數,第一個參數是Subversion工作的基本目錄URL,第二個參數在URL之后―相對于第一個參數―指向當前的賣主分支將會導入的目錄,最后,第三個參數是一個需要導入的本地目錄,使用前面的例子,一個典型的**svn_load_dirs.pl**調用看起來如下: ~~~ $ svn_load_dirs.pl http://svn.example.com/repos/vendor/libcomplex \ current \ /path/to/libcomplex-1.1 … ~~~ 你可以說明你會希望**svn_load_dirs.pl**同時打上標簽,這使用`-t`命令行選項,需要制定一個標簽名。這個標簽是第一個參數的一個相對URL。 ~~~ $ svn_load_dirs.pl -t libcomplex-1.1 \ http://svn.example.com/repos/vendor/libcomplex \ current \ /path/to/libcomplex-1.1 … ~~~ 當你運行**svn_load_dirs.pl**,它會檢驗你的存在的“current”賣主drop,并且與提議的新賣主drop比較,在這個瑣碎的例子里,沒有文件只出現在一個版本里,腳本執行新的導入而不會發生意外。然而如果版本之間有了文件布局的區別,**svn_load_dirs.pl**會詢問你如何解決這個區別,例如你會有機會告訴腳本libcomplex版本1.0的`math.c`文件在1.1已經重命名為`arithmetic.c`,任何沒有解釋為移動的差異都會被看作是常規的添加和刪除。 這個腳本也接受單獨配置文件用來為*添加到*版本庫的文件和目錄設置匹配正則表達式的屬性。配置文件通過**svn_load_dirs.pl**的`-p`命令行選項指定,這個配置文件的每一行都是一個空白分割的兩列或者四列值:一個Perl樣式的正則表達式來匹配添加的路徑、一個控制關鍵字(`break`或者是`cont`)和可選的屬性名和值。 ~~~ \.png$ break svn:mime-type image/png \.jpeg$ break svn:mime-type image/jpeg \.m3u$ cont svn:mime-type audio/x-mpegurl \.m3u$ break svn:eol-style LF .* break svn:eol-style native ~~~ 對每一個添加的路徑,會按照順序為匹配正則表達式的文件配置屬性,除非控制標志是`break`(意味著不需要更多的路徑匹配應用到這個路徑)。如果控制說明是`cont`―`continue`的縮寫―然后匹配工作會繼續到配置文件的下一行。 任何正則表達式,屬性名或者屬性值的空格必須使用單引號或者雙銀行環繞,你可以使用反斜杠(`\`)換碼符來回避引號,反斜杠只會在解析配置文件時回避引號,所以不要保護對正則表達式不需要的其它字符。 而且完全沒有bug,當然!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看