[您也可以檢視此文件 單頁版本。]

一般概觀

參與社群

儘管 Subversion 最初是由 CollabNet (https://www.collab.net/) 贊助和託管,但它是一個真正的開源專案,採用 Apache 授權版本 2.0。許多 Subversion 的開發人員由其雇主支付費用來改善 Subversion,而其他許多人只是優秀的志工,有興趣建立更好的版本控制系統。

社群主要透過 IRC、郵件清單和 Subversion 儲存庫存在。要參與

  • 在 #svn-dev 頻道加入 irc.libera.chat(使用 網路介面Matrix 或任何 IRC 軟體;已封存 在此處)。

  • 加入「dev」、「commits」和「announce」郵件清單。dev 清單 dev@subversion.apache.org 是幾乎所有討論發生的地方。所有開發問題都應該在那裡提出,儘管您可能想先查看清單封存。commits 清單會收到自動提交電子郵件。有關詳細資訊,請參閱 https://subversion.dev.org.tw/mailing-lists.html

  • https://svn.apache.org/repos/asf/subversion/trunk/ 取得最新開發來源的副本。
    新的開發總是在 trunk 上進行。錯誤修正、增強功能和新功能會從那裡回傳到各種發行分支。

幾年來,Subversion 社群每年都會在柏林舉行一次 Hackathon:2016201520142013201220112010 [從 archive.org 連結,某些媒體連結無法使用]。

加入專案的方法有很多,可以撰寫程式碼、測試和/或協助管理錯誤資料庫。如果您想貢獻,請查看

若要提交程式碼,請將您的程式碼補丁傳送至 dev@subversion.apache.org。不,請稍候,請先閱讀完本檔案,然後再開始將程式碼補丁傳送至 dev@subversion.apache.org。 :-)

若要協助管理問題資料庫,請閱讀問題摘要,尋找並測試無效或重複其他問題的問題。這兩種情況很常見,第一種情況是因為錯誤通常會在不知不覺中因程式碼中的其他變更而獲得修正,第二種情況是因為人們有時會在沒有注意到問題已獲得回報的情況下提交問題。如果您不確定問題,請將問題張貼至 dev@subversion.apache.org。(「Subversion:我們在此協助您協助我們!」)

協助的另一種方式是在某個平台上設定 Subversion 的自動建置和測試套件執行,並將輸出傳送至 notifications@subversion.apache.org 郵件清單。請參閱 郵件清單頁面 以取得更多詳細資料。

最後,儘管 Subversion 專案的線上性質以及由此產生的抽象化人際接觸,但重要的是要了解在所有貢獻的背後都有真實的人。請以您希望被對待的方式對待其他所有社群成員。檢閱貢獻,而非貢獻者;不要惹惱他人,也不要輕易被惹惱。

理論與文件

  1. 設計

    一份 設計規範 於 2000 年 6 月撰寫,有點過時。但它仍然對儲存庫的內部運作和 Subversion 的各種層級提供了良好的理論簡介。

  2. API 文件

    請參閱 公開 API 文件 部分以取得更多資訊。

  3. Delta 編輯器

    Karl Fogel 為 O'Reilly 的 2007 年書籍 Beautiful Code: Leading Programmers Explain How They Think 撰寫了一章,涵蓋 Subversion 的 delta 編輯器介面 的設計和使用。

  4. 網路協定

    WebDAV 使用 文件是 Subversion 的 DAV 網路協定的簡介,它是一種 HTTP 的延伸方言,使用以「http://」或「https://」開頭的 URL。

    SVN 協定 文件包含 Subversion ra_svn 網路協定的正式說明,這是一個自訂協定,預設使用埠 3690,其 URL 以「svn://」或「svn+ssh://」開頭。

  5. 使用者手冊

    O'Reilly 出版的「使用 Subversion 進行版本控制」是一本詳細說明如何有效使用 Subversion 的書籍。此書的文字內容是免費的,而且持續進行修訂。線上版本可在 https://svnbook.dev.org.tw/ 取得。XML 原始碼和其他語言的翻譯則在其自己的儲存庫中維護,網址為 https://sourceforge.net/projects/svnbook/

  6. 系統備註

    系統特定面向的許多設計概念已記錄在 notes/ 目錄中的個別檔案中。

閱讀程式碼

在您能貢獻程式碼之前,您需要熟悉現有的程式碼庫和介面。

簽出 Subversion 的副本(如果您尚未擁有具有提交權限的帳戶,則匿名簽出) — 這樣您就能查看程式碼。

'subversion/include/' 內部有一堆具有龐大文件註解的標頭檔。如果您讀過這些註解,您將對實作細節有相當程度的了解。以下是有建議的閱讀順序

  1. 基本建構區塊: svn_string.h svn_error.h svn_types.h

  2. svn_io.h svn_path.h svn_hash.h svn_xml.h

  3. 關鍵介面: svn_delta.h

  4. 用戶端介面: svn_ra.h svn_wc.h svn_client.h

  5. 儲存庫和版本化檔案系統: svn_repos.h svn_fs.h

Subversion 嘗試只使用 C89/C90 方言的 ANSI/ISO C 和 Apache Portable Runtime (APR) 函式庫,以保持可移植性。APR 是 Apache httpd 伺服器使用的可移植性層,更多資訊請參閱 https://apr.apache.org/

由於 Subversion 非常依賴 APR,因此在不先瀏覽 APR 中的特定標頭檔(請查看 'apr/include/')的情況下,可能會難以理解 Subversion。

Subversion 也嘗試提供可靠且安全的軟體。這只能由了解 C 程式語言安全程式設計的開發人員來達成。請參閱 'notes/assurance.txt' 以了解此背後的完整依據。特別是,您應該仔細閱讀 David Wheeler 的安全程式設計(如 'notes/assurance.txt' 中所述)。如果您在任何時候對變更的安全性影響有任何疑問,我們強烈建議您在開發人員郵件清單中請求檢閱。

目錄配置

原始碼樹的粗略指南

分支政策

Subversion 專案強烈建議在共用主幹中進行積極開發。對主幹所做的變更具有最高可見度,並能獲得未發布程式碼所能預期的最大程度的練習。不過,為了讓這對每個人都有利,我們預期主幹隨時都必須保持穩定。它應該可以建置。它應該可以運作。它可能尚未準備好發布,但它肯定應該準備好測試套件。

我們也強烈建議將大型變更拆分為數個較小、合乎邏輯的提交,而每個提交都預期符合上述穩定性需求。

話雖如此,我們了解將所有這些政策套用在特別大型的變更(新功能、全面程式碼重組等)上幾乎是不可能的。在這種情況下,你可以考慮使用專門用於你的開發任務的客製化分支。以下是讓你的基於分支的開發工作順利進行的一些準則。

分支建立和管理

基於分支的開發沒有什麼特別複雜的地方。你從主幹(或從最適合作為你工作來源和目的地的分支)建立一個分支,然後在上面進行你的工作。Subversion 的合併追蹤功能已大幅減少以這種方式工作所需的思考負擔,因此強烈建議善用該功能(使用 Subversion 1.5 或更新的客戶端,並執行所有合併至分支的根目錄和從分支的根目錄合併)。

關於你的分支的記錄訊息政策,請注意有關 撰寫記錄訊息 的區段。

輕量級分支

如果您分階段處理功能或錯誤修正,涉及多個提交,而某些中間階段不穩定到無法進入主線,請在 /branches 中建立一個暫時分支。無需詢問,直接進行即可。在暫時分支中嘗試實驗性想法也無妨。所有上述內容都適用於部分提交者和完整提交者。甚至適用於其他 ASF 專案的提交者,但請與我們聯繫 (透過 dev@) 進行自我介紹,並說明您計畫處理的問題。

當您完成分支時,無論您已將其合併至主線或放棄,請記得移除它。

另請參閱 部分提交存取權限區段,了解我們提供實驗性分支提交存取權限的政策。

BRANCH-README 檔案

對於您預期會長期存在的分支,我們建議在分支根目錄建立並定期更新一個名為 BRANCH-README 的檔案。此類檔案為您提供一個絕佳的集中位置,用於描述分支的下列面向

  • 分支的基本目的:它存在於修正哪個錯誤或實作哪個功能;它與哪些問題編號相關;哪些討論串圍繞著它;哪些設計文件存在於描述情況。

  • 您使用哪種分支管理風格:這是一個功能分支,會定期與其父分支保持同步,並最終重新整合回該父分支嗎?這是一個預期在可預見的未來不會合併回其父分支的分支嗎?它與任何其他分支有關嗎?

  • 您在分支上還有哪些任務要完成?這些任務是否有人認領?它們是否需要更多設計輸入?其他人如何協助您?

以下是 BRANCH-README 檔案範例,用來示範我們在討論什麼

This branch exists for the resolution of issue #8810, per the ideas
documented in /trunk/notes/frobnobbing-feature.txt.  It is a feature
branch, receiving regular sync merges from /trunk, and expected to be
reintegrated back thereto.

TODO:

  * compose regression tests        [DONE]
  * add frob identification logic   [STARTED (fitz)]
  * add nobbing bits                []

為什麼這麼大驚小怪?因為這個專案理想化溝通與協作,了解後者更有可能發生在強調前者時。

只要記得當你將分支合併回其來源時,刪除 BRANCH-README 檔案即可。

文件

記錄一切

每個函式,不論是公開或內部,都必須從文件註解開始,描述函式功能。文件應提及函式接收的每個參數、每個可能的回傳值,以及(如果不明顯)函式可能回傳錯誤的條件。

對於內部文件,將參數名稱以大寫放入文件字串中,即使它們在實際宣告中並非大寫,以便讓人類讀者一眼就能看出。

對於公開或半公開 API 函式,文件字串應放在宣告函式的 .h 檔案中,否則,放在 .c 檔案中函式定義的上方。

對於結構類型,記錄結構的每個個別成員以及結構本身。

對於實際的原始碼,在內部記錄每個函式的區塊,以便熟悉 Subversion 的人可以了解正在實作的演算法。不要包含明顯或過於冗長的記錄;註解應有助於了解程式碼,而不是阻礙它。

例如

  /*** How not to document.  Don't do this. ***/

  /* Make a foo object. */
  static foo_t *
  make_foo_object(arg1, arg2, apr_pool_t *pool)
  {
     /* Create a subpool. */
     apr_pool_t *subpool = svn_pool_create(pool);

     /* Allocate a foo object from the main pool */
     foo_t *foo = apr_palloc(pool, sizeof(*foo));
     ...
  }

相反地,記錄像這樣大小適中的程式碼區塊

      /* Transmit the segment (if its within the scope of our concern). */
      SVN_ERR(maybe_crop_and_send_segment(segment, start_rev, end_rev,
                                          receiver, receiver_baton, subpool));

      /* If we've set CURRENT_REV to SVN_INVALID_REVNUM, we're done
         (and didn't ever reach END_REV).  */
      if (! SVN_IS_VALID_REVNUM(current_rev))
        break;

      /* If there's a gap in the history, we need to report as much
         (if the gap is within the scope of our concern). */
      if (segment->range_start - current_rev < 1)
        {
          svn_location_segment_t *gap_segment;
          gap_segment = apr_pcalloc(subpool, sizeof(*gap_segment));
          gap_segment->range_end = segment->range_start - 1;
          gap_segment->range_start = current_rev + 1;
          gap_segment->path = NULL;
          SVN_ERR(maybe_crop_and_send_segment(gap_segment, start_rev, end_rev,
                                              receiver, receiver_baton,
                                              subpool));
        }

閱讀 Subversion 程式碼,以概覽文件在實務上的樣貌;特別是,請參閱 subversion/include/*.h 以取得 doxygen 範例。

公開 API 文件

我們使用 Doxygen 格式來撰寫公開介面文件。這表示任何放入公開標頭檔的內容。產生的文件會 發布在網站上,提供最新版本和一些較早的 Subversion 原始碼。

我們只使用少部分可用的 doxygen 指令 來標記我們的原始碼。撰寫 doxygen 文件時,套用下列慣例

  • 使用完整句子和散文描述函式,在參數名稱前加上 @a,在類型和巨集名稱前加上 @c
  • 使用 <tt>...</tt> 來顯示多個字詞,使用 @p 來只顯示一個字詞,並使用打字機字體。
  • 常數值,例如 TRUEFALSENULL 應全部大寫。
  • 當多個函式相關時,定義群組名稱,並使用 @defgroup@{...@} 將它們分組在一起。

請參閱 Doxygen 手冊,取得完整指令清單。

提交修補程式的準則

撰寫修補程式

若要取得最新原始碼,請執行

svn checkout https://svn.apache.org/repos/asf/subversion/trunk/ svn-trunk

並遵循 INSTALL 檔案中的說明。(如果您沒有 svn 軟體,下載原始碼 tarball。)

如果您的修補程式實作新功能,或變更大量程式碼,請記得先在 dev@ 清單上討論。(IRC 上的 #svn-dev 也適用於在郵件清單討論之前(但不是取代)的快速回饋。如果您在 IRC 上詢問,請等候一段時間再回覆,因為並非所有人都隨時都在線上(特別是在週末)。)這是為了讓社群能夠表達疑慮,並盡快針對建議的功能或實作細節提出改進建議,如果能及早提供回饋(甚至在撰寫任何程式碼之前),對所有相關人員而言總是比較好的。

如果您對修補程式有任何疑問,請隨時在 IRC 或 dev@ 上發問。

提交修補程式

將修補程式郵件寄送至 dev@subversion.apache.org,並在主旨行開頭加上 [PATCH]。這有助於我們的修補程式管理員立即發現修補程式。例如

   Subject: [PATCH] fix for rev printing bug in svn status

如果修補程式針對特定問題,請也包含問題編號:「[PATCH] issue #1729: ...」。對該特定問題有興趣的開發人員會知道要閱讀郵件。

修補程式提交應包含一個邏輯變更;請不要在一個提交中混入 N 個不相關的變更,請改為寄送 N 封獨立的電子郵件。

使用 svn diff -x-p 從 Subversion trunk 工作副本的頂端產生修補程式。如果您要比對的檔案不在版本控制之下,您可以使用 diff -u 來達成相同的效果。

請在您的修補程式中加入記錄訊息。良好的記錄訊息有助於潛在的審查者了解您的修補程式中的變更,並增加套用的可能性。您可以將記錄訊息置於電子郵件主旨中,或置於修補程式附件的頂端(請見下方)。不論哪種方式,都應遵循撰寫記錄訊息中提供的準則,並以三個方括號括住,如下所示

   [[[
   Fix issue #1729: Don't crash because of a missing file.

   * subversion/libsvn_ra_ansible/get_editor.c
     (frobnicate_file): Check that file exists before frobnicating.
   ]]]

(括號實際上並非記錄訊息的一部分,它們僅是用於清楚地標示記錄訊息與其周圍內容的方式。)

如果可能,請將修補程式作為附件,其 MIME 類型為 text/x-difftext/x-patchtext/plain。大多數人的郵件閱讀器都可以內嵌顯示這些類型,而將修補程式作為附件讓他們可以方便地從訊息中擷取修補程式。切勿以歸檔或壓縮形式(例如 tar、gzip、zip、bzip2)傳送修補程式,因為這會讓其他人無法在自己的郵件閱讀器中直接審查修補程式。

如果您無法以這些 MIME 類型之一附加修補程式,或者修補程式很短,則可以直接將其包含在訊息的主旨中。但請注意:有些郵件編輯器會在長行的中間插入未要求的行中斷,從而破壞內嵌修補程式。如果您認為您的郵件軟體可能會這樣做,請改用附件。

如果修補程式實作新功能,請務必在您的郵件中完整描述該功能;如果修補程式修正錯誤,請詳細描述錯誤並提供重現步驟。這些準則的例外情況是當修補程式針對問題資料庫中的特定問題時,這種情況下,只需在您的記錄訊息中參照問題編號,如撰寫記錄訊息中所述。

在套用程式碼修補程式之前,通常會經過幾輪的回饋與變更。如果你的修補程式沒有立即被接受,請不要氣餒 — 這並不表示你搞砸了,這只表示有很多雙眼睛在審查每一筆程式碼提交,而鮮少有修補程式沒有任何可以改進的地方。在討論大家對你的修補程式的回應後,請進行適當的變更並重新提交,等待下一輪的回饋,然後重複這些步驟,直到有提交者套用你的修補程式。你可以在提交修補程式之前,檢閱並套用專案的程式碼規範,以避免一些反覆作業。

如果你一段時間沒有收到回應,而且沒有看到修補程式被套用,這可能只是表示大家真的很忙。請繼續重新張貼,並不要猶豫指出你仍在等待回應。一種思考方式是,修補程式管理高度容易癱瘓,而且我們需要你承擔管理與程式碼編寫的責任。每一個修補程式都需要有人引導它完成流程,而最適合執行此任務的人就是最初的提交者。