Subversionプロジェクトに貢献する場合は、まずこちらをお読みください。
SubversionはもともとCollabNet(https://www.collab.net/)が後援し、ホストしていましたが、Apache License, Version 2.0に基づく真のオープンソースプロジェクトです。Subversionの開発者の多くは、Subversionを改善するために雇用主から報酬を受けていますが、その他多くの開発者は、より良いバージョン管理システムの構築に関心のある単なる優れたボランティアです。
コミュニティは主にIRC、メーリングリスト、Subversionリポジトリを通じて存在しています。参加するには、
irc.libera.chatの#svn-devチャネルに参加してください(WebインターフェースまたはMatrixまたは任意のIRCソフトウェアを使用してください。アーカイブはこちら)。
「dev」、「commits」、「announce」のメーリングリストに参加してください。devリストであるdev@subversion.apache.orgでは、ほとんどすべての議論が行われます。すべての開発に関する質問はそこに送信する必要がありますが、最初にリストアーカイブを確認することをお勧めします。「commits」リストは、自動コミットメールを受信します。詳細については、https://subversion.dokyumento.jp/mailing-lists.htmlを参照してください。
https://svn.apache.org/repos/asf/subversion/trunk/から最新の開発ソースのコピーを入手してください。
新しい開発は常にtrunkで行われます。バグ修正、機能強化、および新機能は、そこからさまざまなリリースブランチにバックポートされます。
Subversionコミュニティは数年間、年に一度ベルリンでハッカソンを開催しています:2016、2015、2014、2013、2012、2011、および2010 [archive.orgからリンクされています。一部のメディアリンクは機能しません]。
コードを書く、テストする、またはバグデータベースの管理を支援するなど、プロジェクトに参加する方法はたくさんあります。貢献したい場合は、以下を参照してください。
コードを送信するには、パッチをdev@subversion.apache.orgに送信するだけです。いいえ、まずこのファイルの残りの部分を読んでから、パッチをdev@subversion.apache.orgに送信してください。 :-)
問題データベースの管理を支援するには、問題の概要を確認し、無効な問題または他の問題の重複である問題を調べてテストします。両方の種類が非常に一般的です。1つ目は、コードの他の変更の副作用としてバグが意図せずに修正されることがよくあるため、2つ目は、すでに報告されていることに気づかずに問題を提起する人がいるためです。問題が不明な場合は、dev@subversion.apache.orgに質問を投稿してください。(「Subversion:私たちはあなたが私たちを助けるのを助けるためにここにいます!」)
支援するもう1つの方法は、Subversionの自動ビルドとテストスイートの実行をいくつかのプラットフォームで設定し、出力をnotifications@subversion.apache.orgメーリングリストに送信することです。詳細については、メーリングリストページを参照してください。
最後に、Subversionプロジェクトのオンラインの性質と、その事実から生じる人間関係の抽象化にもかかわらず、すべての貢献の終わりには実際の人がいることを認識することが重要です。他のすべてのコミュニティメンバーを、自分が扱われたいように扱ってください。貢献者ではなく、貢献をレビューしてください。他人をイライラさせないでください。また、すぐにイライラしないでください。
設計
設計仕様は2000年6月に作成され、少し古くなっています。ただし、リポジトリの内部動作とSubversionのさまざまなレイヤーについて、優れた理論的導入を行っています。
APIドキュメント
詳細については、公開APIドキュメントに関するセクションを参照してください。
デルタエディター
Karl Fogelは、O'Reillyの2007年の著書Beautiful Code:Leading Programmers Explain How They Thinkで、Subversionのデルタエディターインターフェースの設計と使用について章を書きました。
ネットワークプロトコル
WebDAVの使用ドキュメントは、SubversionのDAVネットワークプロトコルを紹介するものです。これは、HTTPの拡張版であり、「http://」または「https://」で始まるURLを使用します。
SVNプロトコルドキュメントには、Subversion ra_svnネットワークプロトコルの正式な説明が含まれています。これは、ポート3690(デフォルト)上のカスタムプロトコルであり、URLは「svn://」または「svn+ssh://」で始まります。
ユーザーマニュアル
Version Control with Subversionは、Subversionを効果的に使用する方法を詳細に示すO'Reillyから出版された書籍です。書籍のテキストは無料で、積極的に改訂されています。オンライン版はhttps://svnbook.red-bean.com/で入手できます。XMLソースと他の言語への翻訳は、https://sourceforge.net/projects/svnbook/の独自のリポジトリで保守されています。
システムノート
システムの特定の側面に関する多くの設計アイデアは、notes/ディレクトリの個々のファイルに文書化されています。
コードを貢献する前に、既存のコードベースとインターフェースに慣れる必要があります。
Subversionのコピーをチェックアウトします(コミットアクセスのあるアカウントがまだない場合は匿名で)—コードを見ることができるように。
'subversion/include/'内には、巨大なドキュメントコメントを含む多くのヘッダーファイルがあります。これらを読めば、実装の詳細をかなりよく理解できるでしょう。以下に推奨される熟読順序を示します。
基本ビルディングブロック:svn_string.h、svn_error.h、svn_types.h
重要なインターフェース:svn_delta.h
クライアントサイドのインターフェース:svn_ra.h、svn_wc.h、svn_client.h
リポジトリとバージョン管理されたファイルシステム: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 を理解するのが難しい場合があります。
メモリープール:apr_pools.h
ファイルシステムアクセス:apr_file_io.h
ハッシュと配列:apr_hash.h、apr_tables.h
Subversion は、信頼性が高く安全なソフトウェアの提供も試みています。これは、C プログラミング言語での安全なプログラミングを理解している開発者によってのみ達成できます。この背景にある完全な理論的根拠については、「notes/assurance.txt」を参照してください。特に、David Wheeler の Secure Programming ( 「notes/assurance.txt」 で言及) を注意深く読むことをお勧めします。変更のセキュリティ上の影響について疑問がある場合は、開発者メーリングリストでレビューを求めることを強くお勧めします。
ソースツリーの大まかなガイド
doc/
ユーザーおよび開発者向けドキュメント。
tools/
Subversion で動作するが、Subversion が依存していないもの。tools/ 内のコードは、Subversion プロジェクトによって共同で保守されており、Subversion 自体と同じオープンソース著作権の下にあります。
contrib/
Subversion で動作するが、Subversion が依存していないもの。Subversion 開発に参加する人もいれば、そうでない人もいる個人によって保守されています。contrib/ 内のコードはオープンソースですが、Subversion 自体とは異なるライセンスまたは著作権所有者を持つ場合があります。
subversion/
Subversion 自体のソースコード (外部ライブラリとは対照的)。
subversion/include/
Subversion ライブラリのユーザー向けの公開ヘッダーファイル。
subversion/include/private/
Subversion ライブラリ内で内部的に共有される非公開ヘッダーファイル。
subversion/libsvn_fs/
バージョン管理の「ファイルシステム」API。
subversion/libsvn_repos/
`libsvn_fs` コアを中心に構築されたリポジトリ機能。
subversion/libsvn_delta/
ツリーデルタ、テキストデルタ、プロパティデルタ用の共通コード。
subversion/libsvn_wc/
ワーキングコピー用の共通コード。
subversion/libsvn_ra/
リポジトリアクセス用の共通コード。
subversion/libsvn_client/
クライアント操作用の共通コード。
subversion/svn/
コマンドラインクライアント。
subversion/tests/
自動テストスイート。
Subversion プロジェクトは、アクティブな開発が共通の trunk で行われることを強く推奨します。trunk に加えられた変更は、最も高い可視性を持ち、リリースされていないコードから期待できる最大の演習が行われます。しかし、これがすべての人にとって有益であるためには、私たちの trunk は常に安定していることが期待されます。ビルドできるはずです。動作するはずです。リリース準備ができていないかもしれませんが、テストスイートの準備は確かにできているはずです。
また、大きな変更は、より小さく、論理的なコミットに分割することを強く推奨します。それぞれのコミットは、上記の安定性の要件を満たすことが期待されます。
とは言え、特に大きな変更 (新機能、大規模なコード再編成など) にこれらのポリシーをすべて適用することはほぼ不可能であることを理解しています。そのような状況では、開発タスク専用のカスタムブランチの使用を検討するかもしれません。以下に、ブランチベースの開発作業をスムーズに進めるためのガイドラインをいくつか示します。
ブランチベースの開発について特に複雑なことはありません。trunk (または、作業のソースと宛先の両方として最適に機能するブランチ) からブランチを作成し、そのブランチで作業を行います。Subversion のマージトラッキング機能は、この方法で作業するために必要な精神的なオーバーヘッドを大幅に軽減するのに役立っているため、その機能 (Subversion 1.5 以降のクライアントを使用し、ブランチのルートとの間でマージをすべて実行する) を適切に活用することを強くお勧めします。
ブランチのログメッセージに関するポリシーについては、「ログメッセージの作成」のセクションを参照してください。
複数のコミットを伴う段階で機能またはバグ修正に取り組んでおり、中間段階の一部が trunk に進むのに十分な安定性がない場合は、/branches に一時的なブランチを作成します。尋ねる必要はありません。実行してください。一時的なブランチで実験的なアイデアを試すのも問題ありません。また、上記のすべては、部分コミッターだけでなく、フルコミッターにも当てはまります。他の ASF プロジェクトのコミッターにも当てはまりますが、(dev@) で私たちに連絡してください。自己紹介と、取り組む予定の問題を紹介してください。
ブランチの作業が完了したら、trunk にマージするか、あきらめるかした場合、削除することを忘れないでください。
実験的なブランチへのコミットアクセスを提供するポリシーについては、「部分コミットアクセスに関するセクション」も参照してください。
長期間存在することが予想されるブランチの場合、ブランチのルートに次の名前のファイルを作成し、定期的に更新することをお勧めします。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 のコードを読んで、ドキュメントが実際にどのように見えるかの概要を把握してください。特に、doxygen の例については subversion/include/*.h を参照してください。
パブリックインターフェースドキュメントには、Doxygen 形式を使用します。これは、パブリックヘッダーファイルに含まれるすべてのものを意味します。生成されたドキュメントは、最新および以前の Subversion ソースのWeb サイトで公開されています。
ソースをマークアップするために、利用可能な doxygen コマンド のごく一部のみを使用します。doxygen ドキュメントを作成する場合、次の規則が適用されます。
@a
、型およびマクロ名の前に @c
を付けます。<tt>...</tt>
を使用し、1 つの単語のみをタイプライターフォントで表示するには @p
を使用します。TRUE
、FALSE
、NULL
などの定数値はすべて大文字にする必要があります。@defgroup
と @{...@}
を使用してそれらをグループ化します。コマンドの完全なリストについては、Doxygen マニュアルを参照してください。
最新のソースコードを取得するには、次を実行します。
svn checkout https://svn.apache.org/repos/asf/subversion/trunk/ svn-trunk
およびINSTALLファイルの手順に従ってください。(svnクライアントがない場合は、ソース tarball をダウンロードしてください。)
パッチが新機能を実装したり、大量のコードを変更したりする場合は、まず dev@ リストで議論することを忘れないでください。(#svn-dev の IRC は、メーリングリストでの議論の前に、迅速なフィードバックを得るのにも適切です。しかし、代わりにすることはできません。IRC で質問する場合は、全員が常にオンラインになっているわけではない (特に週末) ため、返信があるまでしばらくお待ちください。) そうすることで、コミュニティは提案された機能や実装の詳細に関する懸念を表明し、改善を提案できます。できるだけ早く、フィードバックは、後からではなく、できるだけ早く提供されることが、すべての関係者にとって常に優れています (コードが記述される前であっても)。
パッチについて質問がある場合は、IRC または dev@ でお気軽にお尋ねください。
パッチを dev@subversion.apache.org にメールで送信し、件名行を次のように開始します。[PATCH]これにより、パッチマネージャーがパッチをすぐに検出できるようになります。例えば
Subject: [PATCH] fix for rev printing bug in svn status
パッチが特定の問題に対処する場合は、問題番号も以下のように含めてください。[PATCH] issue #1729: ...特定の問題に関心のある開発者は、メールを読むべきだとわかるでしょう。
パッチの提出は、1つの論理的な変更を含むべきです。無関係な変更を1つの提出に混在させないでください。代わりに、N個の別々のメールを送信してください。
パッチを生成するには、以下を使用してください。svn diff -x-pSubversionトランクのワーキングコピーの最上位から実行します。差分をとっているファイルがリビジョン管理下にない場合は、以下を使用すると同じ効果が得られます。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. ]]]
(括弧は実際にはログメッセージの一部ではなく、ログメッセージを周囲の文脈から明確に区別するための単なる方法です。)
可能な場合は、パッチをtext/x-diff
、text/x-patch
、またはtext/plain
のMIMEタイプで添付ファイルとして送信してください。ほとんどの人のメーラーはそれらをインラインで表示でき、パッチを添付ファイルとして送信することで、メッセージからパッチを簡単に抽出できます。アーカイブ形式または圧縮形式(tar、gzip、zip、bzip2など)でパッチを送信しないでください。これにより、メールリーダーで直接パッチをレビューすることができなくなります。
これらのMIMEタイプのいずれかでパッチを添付できない場合、またはパッチが非常に短い場合は、メッセージの本文に直接含めてもかまいません。ただし、注意が必要です。一部のメールエディターは、長い行の途中に不要な改行を挿入して、インラインパッチを破損させることがあります。メールソフトウェアがこのようなことをする可能性がある場合は、代わりに添付ファイルを使用してください。
パッチが新しい機能を実装する場合は、メールでその機能を完全に説明してください。パッチがバグを修正する場合は、バグを詳細に説明し、再現手順を記述してください。これらのガイドラインの例外は、パッチが課題データベースの特定の問題に対処する場合です。その場合は、ログメッセージの書き方で説明されているように、ログメッセージで課題番号を参照するだけで済みます。
パッチが適用される前に、数回にわたるフィードバックと変更を受けるのは正常です。パッチがすぐに受け入れられなくても落胆しないでください。それはあなたが失敗したという意味ではなく、すべてのコード提出を多くの人が見ているため、改善の余地が少なくとも少しもないパッチはまれであることを意味します。パッチに対する人々の反応について議論した後、適切な変更を加えて再提出し、次のフィードバックを待ち、コミッターが適用するまで、この作業を繰り返してください。提出する前に、プロジェクトのコーディング規約を確認して適用することで、いくつかの反復を回避できます。
しばらく返信がなく、パッチが適用されているのを確認できない場合は、単に人々が非常に忙しいだけかもしれません。遠慮せずに再投稿し、まだ返信を待っていることを指摘してください。パッチ管理は高度に並列化可能であり、コーディングだけでなく、管理の分担も担う必要があると考えると良いでしょう。すべてのパッチには、プロセスを通してそれを導く誰かが必要であり、それを行うのに最も適任なのは元の提出者です。
Subversionプロジェクトのコミッターは、バージョン管理されたリソースへの変更を直接コミットする権利が付与された人々です。プロジェクトは実力主義であり、それは(とりわけ)プロジェクトの運営が作業を行う人々によって処理されることを意味します。コミットアクセスには、フルアクセスと部分アクセスの2種類があります。フルアクセスはツリー内のどこでも、部分アクセスはそのコミッターの特定の専門分野内のみを意味します。すべての貢献はソースに関係なく評価されますが、Subversionにコードを貢献するすべての人がコミットアクセスを獲得するわけではありません。
COMMITTERSファイルには、フルコミッターと部分コミッターの両方がリストされており、各部分コミッターのドメインが示されています。
誰かがいくつかの重要なパッチを正常に貢献した後、通常はその貢献者からのほとんどのパッチをレビューして適用したフルコミッターが、その貢献者をコミットアクセスに推薦します。この提案は、他のフルコミッターのみに送信されます。その後の議論は非公開であるため、誰もが安心して意見を述べることができます。異議がなければ、貢献者にコミットアクセスが付与されます。決定はコンセンサスによって行われます。手順を規定する正式なルールはありませんが、一般的に誰かが強く反対する場合は、アクセスは提供されないか、仮のベースで提供されます。
フルコミットアクセスの主な基準は、良い判断力です。
フルコミッターになるために、技術的な達人である必要も、コードベース全体の深い知識を示す必要もありません。知らないことを知っているだけでいいのです。あなたのパッチがこのファイルのガイドラインを遵守し、コーディングの通常のすべての定量化できないルール(コードは読みやすく、堅牢で、保守可能である必要があるなど)を遵守し、「まず、害をなさない」というヒポクラテスの原則を尊重していれば、おそらくすぐにコミットアクセスを取得できるでしょう。パッチのサイズ、複雑さ、量は、バグを回避し、コードの残りの部分への不必要な影響を最小限に抑えるために示す注意の程度ほど重要ではありません。多くのフルコミッターは、大規模なコード貢献をしたのではなく、多くの中小規模のクリーンな修正を行い、それぞれがコードの明確な改善となった人々です。(もちろん、これはプロジェクトがコミットアクセスを得るためだけの非常に些細なパッチを必要としているという意味ではありません。何がパッチの投稿に値するかを知っていることと、そうでないことを知っていることは、良い判断力を示すことの一部です:-)。)
開発者が新しいコミッターを発見するのを支援するために、パッチやその他の貢献を特別なクレジット形式で記録しています。これは、ブラウザフレンドリーな貢献者リストを作成するために解析され、毎晩更新されます。誰かをコミットアクセスに推薦することを考えていて、その人のすべての変更を確認したい場合は、その貢献者リストが最も便利な場所になるかもしれません。
フルコミッターが部分コミッターを推薦します。通常、これはフルコミッターが提案された部分コミッターと同じ領域にいくつかのパッチを適用しており、その人が直接コミットする方が簡単だと気づいたことを意味します。スポンサーが招待状を発行する前に、private@でその見通しを打診することが慣例であり推奨されますが、必須ではありません。スポンサーは良い判断力を使用することが信頼されています。
スポンサーは、部分コミッターの最初の数回のコミットを監視して、すべてがスムーズに進んでいることを確認します。
部分コミッターによって提出されたパッチは、その人のドメイン外であっても、そのコミッターによってコミットされる場合があります。これには、少なくとも1人のフルコミッターからの承認(しばしば+1の投票として表現されます)が必要です。そのような場合、承認はログメッセージに以下のように記載する必要があります。
Approved by: lundblad
フルコミッターは、いつでも誰にでも実験ブランチへのコミットアクセスを提供できます。実験ブランチがトランクにマージされる可能性が高い必要はありません(ただし、常に目指すべき良い目標です)。新しいコードをSubversionに投入することと、新しい開発者をプロジェクトに参加させることの両方が、これらのブランチの目標であるため、フルコミッター(実際にはすべてのフルコミッター)がコミットに関するフィードバックを提供することで、そのようなブランチを新しい開発者のためのトレーニングの場と見なすことも重要です。軽量ブランチに関するセクション、およびこのメールも参照してください。
https://svn.haxx.se/dev/archive-2007-11/0848.shtml From: Karl Fogel <kfogel@red-bean.com> To: dev@subversion.tigris.org Subject: branch liberalization (was: Elego tree conflicts work) Date: Tue, 20 Nov 2007 10:49:38 -0800 Message-Id: <87y7cswy4d.fsf@red-bean.com>
ツールがcontrib/エリアに受け入れられると、そのツールをそこで維持するために、その作者に部分コミットアクセスを自動的に提供します。フルコミッターは誰でもこれを推奨できます。通常、議論や投票は必要ありませんが、異議がある場合は、通常の意思決定手順が適用されます(最初にコンセンサスに達するように試み、コンセンサスに達することができない場合は、フルコミッター間で投票します)。
contrib/の下のコードはオープンソースである必要がありますが、Subversion自体と同じライセンスまたは著作権所有者を持つ必要はありません。
フルコミッターであろうと部分コミッターであろうと、どのコミッターも、Webページ、APIドキュメント、コードコメント、コミットメッセージなど、どこにでも明白なタイプミス、文法の間違い、フォーマットの問題を修正できます。「明白」であるかどうかを判断するのはコミッターの判断に委ねられています。わからない場合は、聞いてください。
「明白な修正」ルールを適用する場合は、コミットのログメッセージでその旨を記載してください。例えば
------------------------------------------------------------------------ r32135 | stylesen | 2008-07-16 10:04:25 +0200 (Wed, 16 Jul 2008) | 8 lines Update "check-license.py" so that it can generate license text applicable to this year. Obvious fix. * tools/dev/check-license.py (NEW_LICENSE): s/2005/2008/ ------------------------------------------------------------------------
Subversionは、ASFの一部であり、100以上の他のASF プロジェクトと同じリポジトリを共有しています。これらのプロジェクトのコミッターはSubversionのフルコミッターまたは部分コミッターとはみなされませんが、明白な修正、および提出したパッチをコミットすることを歓迎します。ただし、パッチはフルコミッター(またはドメイン内の部分コミッター)から+1の承認を受けている必要があります。どちらの場合も、ログメッセージのガイドラインに従ってください。
Subversionプロジェクトにおけるリリース管理者の役割は、コードを安定させ、パッケージ化し、一般公開するプロセスを処理することです。もし私たちが飛行機を製造していたとしたら、RMは建設チェックリストを見て、機体に航空会社のロゴをペイントし、完成したユニットを顧客に納品する人物でしょう。
そのため、RM(リリース管理者)になること自体に伴う実際の開発作業はありません。あなたが行う必要がある作業はすべて非コーディングです。つまり、人々の調整、情報の集約、および新しい安定版リリースを発表する公的な声としての役割です。RMが行う必要のあるタスクの多くは反復的であり、まだ誰もツールを開発していないため、またはタスクが自動化を少し冗長にする人間による検証を必要とするため、自動化されていません。リリースプロセスについては、Subversion リリースの作成のセクションで詳しく読むことができます。
この段階で、RMの役割は地味だと感じるかもしれませんが、それはある意味で正しいです。プロジェクト内で名声と富をもたらすようなポジションを探しているなら、trunkで本当に必要なものを実装する方が良いでしょう。リリースを気にせずコードに集中したい人々を本当に助けたいと考えているなら、RMはあなたに向いているでしょう。
リリース管理の知識をより広く普及させるために、RMの役割は現在、さまざまな犠牲者ボランティアの間で持ち回り制になっています。
Subversionには通常、パッチマネージャーがおり、その仕事はdev@メーリングリストを監視し、パッチが「見落とされない」ようにすることです。
これは、「[PATCH]」というメールを含むすべてのスレッドを監視し、スレッドの進捗状況に基づいて適切なアクションを実行することを意味します。スレッドが自然に解決した場合(パッチがコミットされた場合、またはパッチを適用する必要がないという合意が得られた場合など)、それ以上の措置は必要ありません。しかし、明確な決定なしにスレッドが消滅した場合、パッチは課題追跡システムに保存する必要があります。これは、そのパッチに関する議論スレッドの要約と、関連するメーリングリストアーカイブへのリンクが、追跡システムのいくつかの課題に追加されることを意味します。既存の課題追跡項目のパッチの場合、パッチはその項目に保存されます。それ以外の場合は、適切なタイプ(「DEFECT」、「FEATURE」、または「ENHANCEMENT」(「PATCH」ではない))の新しい課題が作成され、パッチがその新しい課題に保存され、「パッチ」キーワードが課題に記録されます。
パッチマネージャーには、Subversionの基本的な技術的理解と、スレッドをざっと読んで合意に達したかどうか、そしてそうである場合はどのような合意かを大まかに理解する能力が必要です。Subversionの開発経験やコミットアクセスは必要ありません。メール閲覧ソフトウェアの使用に関する専門知識はオプションですが、推奨されます :-)。
現在のパッチマネージャーは、Gavin 'Beau' Baumanis <gavin@thespidernet.com> です。
Subversionのコードとヘッダーファイルは、いくつかの重要な線に沿って分離されています。ライブラリ固有のものとライブラリ間のもの、パブリックとプライベートです。この分離は、主に適切なモジュール性とコード編成に重点を置いているためですが、広く採用されているパブリックAPIの提供者および保守者としての約束のためでもあります。Subversionで新しい関数を作成する際には、これらの点を慎重に検討し、進めながら自問自答する必要があります。
「新しいコードの利用者は、単一のライブラリ内の特定のソースコードファイルにローカルですか?」 そうである場合、おそらく同じソースファイル内の静的関数を使用することになります。
「新しい関数は、このライブラリ内の他のソースコードは使用する必要があるが、ライブラリ*外部*からは何も使用する必要がないようなタイプですか?」 その場合は、非静的な、二重アンダースコア付きの名前の関数(例:svn_foo__do_something)を使い、そのプロトタイプを適切なライブラリ固有のヘッダーファイルに記述することになります。
「異なるライブラリからコードにアクセスする必要がありますか?」 ここでは、さらにいくつかの質問に答える必要があります。たとえば、「コードは、元々配置しようとしていたライブラリに配置する必要がありますか、それともlibsvn_subrなどのより一般的なユーティリティライブラリに配置する必要がありますか?」 いずれにしても、ライブラリ間のヘッダーファイルを使用することになります。ただし、どちらにするかを決定する前に、次の質問をご覧ください...
「コードは、永続的に維持できる合理的なAPIを持ち、SubversionのパブリックAPIの提供に価値をもたらすものですか?」 そうである場合は、パブリックAPI内のプロトタイプを、すぐにsubversion/include/に追加することになります。そうでない場合は、計画を再確認してください。機能の抽象化に最適な方法を選択していない可能性があります。しかし、Subversion自体以外のソフトウェアには明らかに役に立たない関数をライブラリ間で共有する必要がある場合もあります。そのような場合は、subversion/include/private/.
SubversionはANSI Cを使用しており、GNUコーディング標準に従っています。ただし、関数の名前とパラメーターリストの開き括弧の間にスペースは入れません。Emacsユーザーは、svn-dev.elをロードするだけで適切なインデント動作を得ることができます(ここにあるほとんどのソースファイルは、`enable-local-eval`が適切に設定されている場合、自動的にロードします)。
GNUコーディング標準の詳細については、https://www.gnu.org/prep/standards.htmlをご覧ください。以下は、最も重要な書式設定のガイドラインを示す簡単な例です。パラメーターリストの開き括弧の前にスペースを入れないという例外を含みます。
char * /* func type on own line */ argblarg(char *arg1, int arg2) /* func name on own line */ { /* first brace on own line */ if ((some_very_long_condition && arg2) /* indent 2 cols */ || remaining_condition) /* new line before operator */ { /* brace on own line, indent 2 */ arg1 = some_func(arg1, arg2); /* NO SPACE BEFORE PAREN */ } /* close brace on own line */ else { do /* format do-while like this */ { arg1 = another_func(arg1); } while (*arg1); } }
一般的に、演算子の優先順位を確信している場合でも括弧を多用し、「コードの詰め込み」を避けるためにスペースと改行を惜しまないでください。垂直方向の密度をあまり気にしないでください。画面に追加の行を収めるよりも、コードを読みやすくする方が重要です。
コードとプレーンテキストの散文ファイルの両方で、セクションの区切りには改ページ(Ctrl-L文字、ASCII 12)を使用しています。各セクションは改ページで始まり、改ページの直後にセクションのタイトルが続きます。
これは、`pages-directory`や`narrow-to-page`などのEmacsページコマンドを使用するユーザーを支援します。このような人々はあなたが思うほど少なくなく、もしあなたがその一人になりたいのであれば、.emacsに(require 'page-ext)を追加して、時々C-x C-p C-hと入力してください。
エラーメッセージには、以下の規約が適用されます。
subversion/include/svn_error_codes.hにある一般的なエラーメッセージに追加する情報がある場合にのみ、特定のエラーメッセージを提供してください。
メッセージは大文字で始まります。
メッセージを70文字未満に保つようにしてください。
エラーメッセージをピリオド(「.」)で終わらせないでください。
エラーメッセージに改行文字を含めないでください。
情報の引用は、単一引用符を使用します(例:"'some info'")。
エラーが発生した関数の名前をエラーメッセージに含めないでください。Subversionが「--enable-maintainer-mode」configureフラグを使用してコンパイルされている場合、この情報自体が提供されます。
エラー文字列にパスまたはファイル名を含める場合は、必ずそれらを引用符で囲んでください(例:「'/path/to/repos/userfile'が見つかりません」)。
エラー文字列にパスまたはファイル名を含める場合は、含める前に必ずsvn_dirent_local_style()を使用して変換してください(Subversion APIとの間で受け渡されるパスは、正規形であると想定されているため)。
Subversion固有の省略形を使用しないでください(例:「repo」の代わりに「repository」、「wc」の代わりに「working copy」を使用してください)。
エラーに説明を追加する場合は、次のようにコロンと説明を続けて報告してください。
"Invalid " SVN_PROP_EXTERNALS " property on '%s': " "target involves '.' or '..'".
提案やその他の追加は、次のようにセミコロンの後に追加できます。
"Can't write to '%s': object of same name already exists; remove " "before retrying".
これらの規約の範囲内に留まるようにしてください。そのため、「--」などの他の区切り文字でエラーメッセージの異なる部分を区切らないようにしてください。
また、ローカライゼーションについても読んでください。
(これは、APRプールの仕組みを基本的に理解していることを前提としています。詳細については、apr_pools.hをご覧ください。)
Subversionライブラリを使用するアプリケーションは、Subversion関数を呼び出す前にapr_initialize()を呼び出す必要があります。
Subversionの一般的なプール使用戦略は、次の2つの原則に要約できます。
プールを作成した呼び出しレベルは、そのプールをクリアまたは破棄する唯一の場所です。
境界のない回数を反復処理する場合は、反復処理に入る前にサブプールを作成し、ループ内で使用し、各反復処理の開始時にクリアし、ループが完了したら破棄します。例:
apr_pool_t *iterpool = svn_pool_create(scratch_pool); for (i = 0; i < n; ++i) { svn_pool_clear(iterpool); do_operation(..., iterpool); } svn_pool_destroy(iterpool);
上記ルールをサポートするために、さまざまなプールの有効期間を表す規約として、次のプール名を使用します。
result_pool
:関数の出力が割り当てられるプール。結果プールの宣言は、関数の引数リストに常に記述する必要があり、ローカルブロック内には決して記述しないでください。(ただし、すべての関数に結果プールが必要なわけではありません。)
scratch_pool
:関数ローカルのすべてのデータが割り当てられるプール。このプールも呼び出し元によって提供され、呼び出し元は制御が戻った直後にこのプールをクリアすることを選択できます。
iterpool
:上記の例に従って、ループ内で使用される反復プール。
(注:一部のレガシーコードでは、単一のpool
関数引数を使用しており、これは結果プールとスクラッチプールの両方として機能します。)
ループで境界付けられたデータにiterpoolを使用することにより、関数が(エラーなどが原因で)ループ内から突然戻った場合に、O(N)ではなくO(1)のメモリリークを確実にします。そのため、関数全体で永続化するデータにはサブプールを作成しないでください。代わりに、呼び出し元から渡されたプールを使用してください。そのメモリは、呼び出し元のプールがクリアまたは破棄されたときに再利用されます。呼び出し元がループ内で呼び出し先を呼び出している場合は、各反復処理でプールをクリアするのは呼び出し元の責任であると信じてください。同じロジックが呼び出しスタック全体に伝播されます。
使用するプールは、コードの読者がオブジェクトの有効期間を理解するのに役立ちます。特定のオブジェクトはループの1回の反復でのみ使用されますか、それともループの終わりを超えて存続する必要がありますか?たとえば、プールの選択は、このコードで何が起こっているかについて多くのことを示しています。
apr_hash_t *persistent_objects = apr_hash_make(result_pool); apr_pool_t *iterpool = svn_pool_create(scratch_pool); for (i = 0; i < n; ++i) { const char *intermediate_result; const char *key, *val; svn_pool_clear(iterpool); SVN_ERR(do_something(&intermediate_result, ..., iterpool)); SVN_ERR(get_result(intermediate_result, &key, &val, ..., result_pool)); apr_hash_set(persistent_objects, key, APR_HASH_KEY_STRING, val); } svn_pool_destroy(iterpool); return persistent_objects;
これらの原則が十分に理解される前に書かれた一部のレガシーコードを除いて、Subversionでのほぼすべてのプールの使用は上記のガイドラインに従っています。
そのようなレガシーなパターンの一つに、オブジェクトをプール内に割り当て、そのプールをオブジェクトに格納し、そのプールを(直接または `close_foo()` 関数を介して)解放してオブジェクトを破棄するというものがあります。
例えば
/*** Example of how NOT to use pools. Don't be like this. ***/
static foo_t *
make_foo_object(arg1, arg2, apr_pool_t *pool)
{
apr_pool_t *subpool = svn_pool_create(pool);
foo_t *foo = apr_palloc(subpool, sizeof(*foo));
foo->field1 = arg1;
foo->field2 = arg2;
foo->pool = subpool;
}
[...]
[Now some function calls make_foo_object() and returns, passing
back a new foo object.]
[...]
[Now someone, at some random call level, decides that the foo's
lifetime is over, and calls svn_pool_destroy(foo->pool).]
これは魅力的ですが、プールの使用目的を損なっています。プールの目的は個々の割り当てをそれほど気にせず、むしろ全体的なパフォーマンスとライフタイムグループを重視することです。代わりに、`foo_t` は一般的に `pool` フィールドを持つべきではありません。現在のプールに必要な数の foo オブジェクトを割り当てるだけでよいのです。そのプールがクリアまたは破棄されると、それらはすべて同時に消滅します。
プールの破棄時に、プールに関連付けられたリソースがどのようにクリーンアップされるかの詳細については、例外処理のセクションも参照してください。
要約すると
オブジェクトは独自のプールを持つべきではありません。オブジェクトは、コンストラクタの呼び出し元によって定義されたプールに割り当てられます。呼び出し元はオブジェクトのライフタイムを知っており、プールを介して管理します。
関数は、その操作のためにプールを作成/破棄すべきではありません。呼び出し元から提供されたプールを使用する必要があります。繰り返しますが、呼び出し元は関数がどのように使用されるか、どのくらいの頻度で使用されるか、何回使用されるかなどについてより多くを知っています。したがって、関数のメモリ使用量を管理する必要があります。
たとえば、タイトなループ内で複数回呼び出される関数について考えてみてください。呼び出し元は各反復でスクラッチプールをクリアします。したがって、内部サブプールの作成は不要であり、かなりのオーバーヘッドになる可能性があります。代わりに、関数は渡されたプールを使用する必要があります。
上限のない反復が発生する場合は常に、反復サブプールを使用する必要があります。
上記のすべてを考慮すると、すべての関数にプールを渡すことがほぼ必須となります。オブジェクトはプールを自分自身のために記録せず、呼び出し元は常にメモリを管理することになっているため、各関数は、何らかの隠れた魔法のプールに頼るのではなく、プールを必要とします。限定的なケースでは、オブジェクトはサブパーツを構築できるように、構築に使用されたプールを記録できますが、これらのケースは慎重に検討する必要があります。
プールの使用に関する問題を診断するためのヒントについては、メモリリークの追跡も参照してください。
APRステータスコード (APR_SUCCESS を除く) は、直接比較ではなく、常に APR_STATUS_IS_...() マクロで確認してください。これは、非 Unix プラットフォームへの移植性のために必要です。
さて、Subversion での例外の使い方は次のとおりです。
例外は `svn_error_t` 構造体に格納されます。
typedef struct svn_error_t { apr_status_t apr_err; /* APR error value, possibly SVN_ custom err */ const char *message; /* details from producer of error */ struct svn_error_t *child; /* ptr to the error we "wrap" */ apr_pool_t *pool; /* place to generate message strings from */ const char *file; /* Only used iff SVN_DEBUG */ long line; /* Only used iff SVN_DEBUG */ } svn_error_t;
エラーの *最初の* 作成者である場合は、次のようにします。
return svn_error_create(SVN_ERR_FOO, NULL, "User not permitted to write file");
NULL フィールドに注目してください...これは、このエラーに子がないこと、つまり最下位のエラーであることを示します。
エラーメッセージの書き方に関するセクションも参照してください。
Subversion は、内部的に UTF-8 を使用してデータを保存します。これは「メッセージ」文字列にも適用されます。APR は、現在のロケールでデータを返すことを想定しているため、APR が返すテキストは、メッセージ文字列に含める前に UTF-8 に変換する必要があります。
エラーを *受信* した場合は、3 つの選択肢があります。
自分でエラーを処理します。独自のコードを使用するか、プリミティブな `svn_handle_error(err)` を呼び出すだけです。(このルーチンは、エラーのスタックを巻き戻し、UTF-8 から現在のロケールに変換してメッセージを出力します。)
ルーチンが無視または自分で処理しようとするエラーを受け取った場合は、必ず `svn_error_clear()` を使用してクリーンアップしてください。このようなエラーがクリアされない場合は、*メモリリーク* を構成します。
エラーを返す関数は、出力パラメータを初期化する必要はありません。
エラーをそのまま上位にスローします。
error = some_routine(foo); if (error) return svn_error_trace(error);
実際には、これを行うより良い方法は、同じことを行う `SVN_ERR()` マクロを使用することです。
SVN_ERR(some_routine(foo));
エラーを上位にスローし、新しいエラー構造体に "子" 引数として含めることでラップします。
error = some_routine(foo); if (error) { svn_error_t *wrapper = svn_error_create(SVN_ERR_FOO, error, "Authorization failed"); return wrapper; }
もちろん、子と同じフィールドを持ち、カスタムメッセージを除くラッパーエラーを作成するための便利なルーチンがあります。
error = some_routine(foo); if (error) { return svn_error_quick_wrap(error, "Authorization failed"); }
同様のことは、`SVN_ERR_W()` マクロを使用することによって行うことも(そして行うべきです)できます。
SVN_ERR_W(some_routine(foo), "Authorization failed");
(b) と (c) のケースでは、ルーチンによって割り当てられ、プールに関連付けられているリソースは、プールの破棄時に自動的にクリーンアップされることを知っておくことが重要です。これは、エラーを渡す前にこれらのリソースをクリーンアップする必要がないことを意味します。したがって、`SVN_ERR()` および `SVN_ERR_W()` マクロを使用しない理由はありません。プールに関連付けられたリソースは次のとおりです。
メモリ
ファイル
`apr_file_open` で開かれたすべてのファイルは、プールのクリーンアップ時に閉じられます。Subversion は、その `svn_io_file_*` API でこの関数を使用します。つまり、`svn_io_file_*` または `apr_file_open` で開かれたファイルは、プールのクリーンアップ時に閉じられます。
一部のファイル(たとえば、ロックファイル)は、操作が完了したときに削除する必要があります。APR には、この目的のための `APR_DELONCLOSE` フラグがあります。次の関数は、プールのクリーンアップ時に削除されるファイルを作成します。
`apr_file_open` および `svn_io_file_open`(`APR_DELONCLOSE` フラグが渡された場合)
`svn_io_open_unique_file`(`delete_on_close` で TRUE が渡された場合)
ロックされたファイルは、`svn_io_file_lock` を使用してロックされていた場合、ロック解除されます。
`SVN_ERR()` マクロは、`SVN_ERR__TRACING` が定義されている場合に、ラップされたエラーを作成します。これは、開発者がエラーの原因を特定するのに役立ち、`configure` の `--enable-maintainer-mode` オプションで有効にできます。
場合によっては、呼び出された関数が返すものをそのまま返したい場合があります。通常、自分の関数の最後に返します。結果を直接返すという誘惑を避けてください。
/* Don't do this! */ return some_routine(foo);
代わりに、`svn_error_trace` メタ関数を使用して値を返します。これにより、有効になっているときにスタックトレースが正しく行われることが保証されます。
return svn_error_trace(some_routine(foo));
他のほとんどすべてのプログラミング言語と同様に、C には、攻撃者が予測可能な方法でプログラムを失敗させることができ、多くの場合、攻撃者の利益になる望ましくない機能があります。これらのガイドラインの目的は、Subversion プロジェクトに適用される C の落とし穴を認識させることです。最も熟練した偏執的なプログラマーでも時折間違いを犯すため、同僚のコードをレビューする際には、これらの落とし穴を念頭に置くことをお勧めします。
入力検証とは、合法的な入力を定義し、それ以外のすべてを拒否する行為です。コードは、信頼できないすべての入力に対して入力検証を実行する必要があります。
セキュリティ境界
Subversion サーバーコードのセキュリティ境界は、監査人が境界の品質をすばやく判断できるように、そのように識別する必要があります。セキュリティ境界は、実行中のコードがユーザーが持っていない情報にアクセスできる場合、またはコードが要求を行うユーザーの特権よりも高い特権で実行される場合に存在します。そのような典型的な例は、アクセス制御を実行するコードまたは SUID ビットが設定されたアプリケーションです。
セキュリティ境界への呼び出しを行う関数には、渡された引数の検証チェックを含める必要があります。それ自体がセキュリティ境界である関数は、受信した入力を監査し、不適切な値で呼び出されたときにアラームを出す必要があります。
[### todo: ここに Subversion からのいくつかの例が必要です...]
文字列操作
文字列に書き込む標準 C ライブラリ関数ではなく、`apr_strings.h` で提供されている文字列関数を使用してください。APR 関数は、境界チェックと宛先割り当てを自動的に行うため、より安全です。プレーンな C 文字列関数を使用することが理論的に安全な状況(たとえば、ソースと宛先の長さをすでに知っている場合)があるかもしれませんが、コードが脆弱でなくなり、レビューしやすくなるため、とにかく APR 関数を使用してください。
パスワードの保存
ユーザーがパスワードを秘密に保つのを支援します。クライアントがローカルでパスワードを読み書きする場合、ファイルがモード 0600 であることを確認する必要があります。ファイルが他のユーザーによって読み取り可能な場合、クライアントは、暴露の危険があるため、ファイルモードを変更するようにユーザーに指示するメッセージで終了する必要があります。
アプリケーションの正常な機能を確保するために、一部のリソースは破棄する必要があります。このようなリソースには、特に Windows では開いているファイルを削除できないため、ファイルが含まれます。
ストリームを作成して返す API を作成する場合、バックグラウンドでこのストリームはファイルまたは他のストリームにスタックされる可能性があります。リソースの正しい破棄を確実にするために、ストリームが構築されている場合、構築されている(所有している)ストリームのデストラクタを正しく呼び出す必要があります。
最初に https://svn.haxx.se/dev/archive-2005-12/0487.shtml で、その後 https://svn.haxx.se/dev/archive-2005-12/0633.shtml で、これはファイル、ストリーム、エディター、ウィンドウハンドラーに関してより一般的な用語で議論されました。
グレッグ・ハドソンが言ったように
検討した結果、ここで私たちがあるべき場所を次に示します。
- 基になるオブジェクトから読み取りまたは書き込みを行うストリームは、そのオブジェクトを所有します。つまり、ストリームを閉じると、該当する場合、基になるオブジェクトが閉じます。
- ストリームを作成したレイヤー(関数またはデータ型)は、上記規則が適用される場合を除き、ストリームを閉じる責任があります。
- ウィンドウハンドラーは、奇妙な種類のストリームと見なされ、最後の NULL ウィンドウを渡すことは、ストリームを閉じると見なされます。
apply_textdelta をウィンドウハンドラーの作成と考えると、それほど遠くはないと思います。`svn_stream_from_aprfile` は、その補助ファイル所有しておらず、`svn_txdelta_apply` は、渡されたウィンドウストリームを閉じる責任を誤って負っており、他にもいくつかの逸脱がある可能性があります。
ただし、上記の規則には 1 つの例外があります。ストリームが関数に引数として渡された場合(たとえば、`svn_client_cat2()` の 'out' パラメータ)、そのルーチンはそのリソースを作成しなかったため、ストリームのデストラクタを呼び出すことはできません。
`svn_client_cat2()` がストリームを作成する場合、そのストリームのデストラクタも呼び出す必要があります。上記のモデルでは、そのストリームは 'out' パラメータのデストラクタを呼び出します。しかし、'out' パラメータを破棄する責任は他にあります。これは間違っています。
この問題を解決するために、少なくともストリームの場合には、svn_stream_disown() が導入されました。この関数はストリームをラップし、その上に積み重ねられたストリームが破棄しようとした場合でも、そのストリームが破棄されないようにします。
可変個の引数を受け取り、リストがヌルポインタ定数で終端されることを期待する関数を呼び出す場合(そのような関数の例はapr_pstrcat)、リストを終端するためにNULLシンボルを使用しないでください。コンパイラとプラットフォームによっては、NULLがポインタサイズの定数である場合とそうでない場合があります。そうでない場合、関数は引数リストの末尾を超えてデータを読み取ってしまう可能性があります。
代わりに、SVN_VA_NULL(1.9以降でsvn_types.hで定義) を使用してください。これはヌルポインタ定数であることが保証されています。例を以下に示します。
return apr_pstrcat(cmd->temp_pool, "Cannot parse expression '", arg2, "' in SVNPath: ", expr_err, SVN_VA_NULL);
GNU標準に加えて、Subversionでは以下の規約を使用しています。
ほとんどのSubversion APIへの入力としてパスまたはファイル名を使用する場合は、svn_dirent_internal_style() APIを使用して、Subversionの内部/正規形式に変換してください。または、Subversion APIからパスまたはファイル名を出力として受け取る場合は、svn_dirent_local_style() APIを使用して、プラットフォームで期待される形式に変換してください。
コードのインデントには、タブは決して使用せず、スペースのみを使用してください。タブの表示幅は標準化されておらず、いずれにしてもスペースを使用するインデントを手動で調整する方が簡単です。
行を79桁に制限して、最小限の標準ディスプレイウィンドウでコードが適切に表示されるようにします。(インデント、引用符などによって数桁余分な桁が占められている80桁のテキストブロックを宣言する場合など、各行を2つに分割すると不必要に面倒になる場合は例外があります。)
公開されているすべての関数、変数、および構造体には、libsvn_wcのsvn_wc_adm_openのように、対応するライブラリ名で示さなければなりません。ライブラリプライベートヘッダーファイル(libsvn_wc/wc.hなど)で作成されたライブラリ内部のすべての宣言は、ライブラリのプレフィックスの後に2つのアンダースコア(svn_wc__ensure_directoryなど)で示す必要があります。1つのファイル(libsvn_wc/update_editor.c内の静的関数get_entry_urlなど)にプライベートなすべての宣言は、追加の名前空間装飾を必要としません。ライブラリの外部で使用する必要があるが、公開されていないシンボルは、include/private/ディレクトリにある共有ヘッダーファイルに入れられ、二重アンダースコア表記を使用します。このようなシンボルは、Subversionコアコードでのみ使用できます。
まとめると
/* Part of published API: subversion/include/svn_wc.h */ svn_wc_adm_open() #define SVN_WC_ADM_DIR_NAME ... typedef enum svn_wc_schedule_t ... /* For use within one library only: subversion/libsvn_wc/wc.h */ svn_wc__ensure_directory() #define SVN_WC__BASE_EXT ... typedef struct svn_wc__compat_notify_baton_t ... /* For use within one file: subversion/libsvn_wc/update_editor.c */ get_entry_url() struct handler_baton { /* For internal use in svn core code only: subversion/include/private/svn_wc_private.h */ svn_wc__entry_versioned()
Subversion 1.5より前は、ライブラリの外部で使用する必要があったプライベートシンボルは、二重アンダースコア表記を使用して、パブリックヘッダーファイルに入れられていました。この方法は廃止され、そのようなシンボルはすべて、後方互換性のために維持されているレガシーです。
ユーザーに印刷(または他の方法で利用可能)にされる可能性のあるテキスト文字列では、パスやその他の引用可能なものについては、常にフォワード引用符のみを使用してください。たとえば
$ svn revert foo svn: warning: svn_wc_is_wc_root: 'foo' is not a versioned resource $
以前は、最初の引用符にバックティック(`foo' の代わりに 'foo')を使用する文字列がたくさんありましたが、一部のフォントでは見栄えが悪く、一部の人の自動強調表示も混乱させたため、常にフォワード引用符を使用するという規約に落ち着きました。
Emacsを使用する場合は、必要に応じてsvn-dev.elとsvnbook.elを取得できるように、.emacsファイルに次のようなものを入れてください。
;;; Begin Subversion development section (defun my-find-file-hook () (let ((svn-tree-path (expand-file-name "~/projects/subversion")) (book-tree-path (expand-file-name "~/projects/svnbook"))) (cond ((string-match svn-tree-path buffer-file-name) (load (concat svn-tree-path "/tools/dev/svn-dev"))) ((string-match book-tree-path buffer-file-name) ;; Handle load exception for svnbook.el, because it tries to ;; load psgml, and not everyone has that available. (condition-case nil (load (concat book-tree-path "/src/tools/svnbook")) (error (message "(Ignored problem loading svnbook.el.)"))))))) (add-hook 'find-file-hooks 'my-find-file-hook) ;;; End Subversion development section
もちろん、セットアップに合わせてパスをカスタマイズする必要があります。正規表現をより選択的に文字列照合することもできます。たとえば、ある開発者は次のように述べています。
> Here's the regexp I'm using: > > "src/svn/[^/]*/\\(subversion\\|tools\\|build\\)/" > > Two things to notice there: (1) I sometimes have several > working copies checked out under ...src/svn, and I want the > regexp to match all of them; (2) I want the hook to catch only > in "our" directories within the working copy, so I match > "subversion", "tools" and "build" explicitly; I don't want to > use GNU style in the APR that's checked out into my repo. :-)
私たちは、個々の著者の名前でファイルをマークしないという伝統を持っています(つまり、ソースファイルの先頭に「著者:foo」や「@author foo」のような行を特別な位置に置きません)。これは、縄張り意識を助長しないためです。たとえファイルに1人の著者しかいない場合でも、他の人が自由に編集できるようにしたいと考えています。誰かがファイルに対する個人的な主張を立てているように見えると、人々は不必要に躊躇する可能性があります。
文末と次の文の先頭の間には、2つのスペースを入れます。これは読みやすさを向上させ、エディターの文の移動と操作のコマンドを使用できるようにします。
コード全体で維持されている、言葉にされていない他の多くの規約があります。それらは誰かが意図せずにそれらに従わなかった場合にのみ気付かれます。物事が行われる方法を注意深く観察し、疑問がある場合は質問してください。
すべてのコミットにはログメッセージが必要です。
ログメッセージの対象読者は、Subversionにはすでに精通しているが、この特定のコミットには必ずしも精通していない開発者です。通常、誰かが変更を振り返って読むとき、その変更に関するすべてのコンテキストを頭の中に持っているわけではありません。これは、変更の作成者であっても当てはまります!すべての議論やメーリングリストのスレッドなどは忘れられている可能性があり、変更の内容の手がかりはログメッセージとdiff自体からのみ得られます。人々は驚くほど頻繁に変更を再検討します。たとえば、元のコミットから数か月後、変更がメンテナンスブランチに移植される場合があります。
ログメッセージは変更の導入部です。
ブランチで作業している場合は、ログメッセージの先頭に
On the 'name-of-branch' branch: (Start of your log message)
ログメッセージは、変更の一般的な性質を示す1行で開始し、必要に応じて説明段落を続けます。
これは、開発者がログメッセージの残りの部分を読むための適切な心構えになるのに役立つだけでなく、各コミットの最初の行をIRCのようなリアルタイムフォーラムにエコーする「ASFBot」ボットにも役立ちます。(詳細については、https://wilderness.apache.org/を参照してください)
コミットが1つのファイルに対する1つの簡単な変更である場合は、一般的な説明を省略して、以下に示す標準のファイル名-シンボル形式で詳細な説明に直接進むことができます。
ログメッセージ全体を通して、文節ではなく、完全な文を使用してください。文節はあいまいであることが多く、意味を書き出すのに数秒しかかかりません。「Doc fix」、「New file」、「New function」などの特定の文節は、標準的な慣用句であり、それ以上の詳細はソースコードに記述する必要があるため、許容されます。
ログメッセージには、このコミットで削除されるシンボル名を含む、影響を受けるすべての関数、変数、マクロ、makefileターゲット、文法規則などを名前を付けてください。これは、後でログを検索するのに役立ちます。ワイルドカードで名前を隠さないでください。グロブされた部分は、後で誰かが検索する可能性があるためです。たとえば、これは良くありません。
* subversion/libsvn_ra_pigeons/twirl.c (twirling_baton_*): Removed these obsolete structures. (handle_parser_warning): Pass data directly to callees, instead of storing in twirling_baton_*. * subversion/libsvn_ra_pigeons/twirl.h: Fix indentation.
後で誰かが「twirling_baton_fast」に何が起こったのかを理解しようとしたときに、「_fast」を検索するだけでは見つからない可能性があります。より良いエントリは次のようになります。
* subversion/libsvn_ra_pigeons/twirl.c (twirling_baton_fast, twirling_baton_slow): Removed these obsolete structures. (handle_parser_warning): Pass data directly to callees, instead of storing in twirling_baton_*. * subversion/libsvn_ra_pigeons/twirl.h: Fix indentation.
ワイルドカードは、「handle_parser_warning」の説明では問題ありません。ただし、2つの構造体がログエントリの他の場所でフルネームで言及されている場合に限ります。
ログメッセージにプロパティの変更も含める必要があります。たとえば、トランクの「svn:ignore」プロパティを変更した場合は、ログに次のようなものを入力する可能性があります。
* trunk/ (svn:ignore): Ignore 'build'.
上記は、サブバージョンによって保守される「svn:mergeinfo」のようなものではなく、あなたが保守するプロパティにのみ適用されます。
各ファイルは「*」で始まる独自のエントリを取得し、ファイル内の変更はシンボルごとにグループ化され、シンボルは括弧で囲まれ、コロンが続き、変更を説明するテキストが続きます。変更されたファイルが1つだけの場合でも、この形式に従ってください。一貫性は読みやすさを助けるだけでなく、ソフトウェアがログエントリを自動的に色分けすることもできます。
上記に対する例外として、複数のファイルでまったく同じ変更を加えた場合は、変更されたすべてのファイルを1つのエントリにリストします。たとえば
* subversion/libsvn_ra_pigeons/twirl.c, subversion/libsvn_ra_pigeons/roost.c: Include svn_private_config.h.
変更されたすべてのファイルがソースツリーの奥深くに存在する場合は、変更エントリの前に共通のプレフィックスを書き留めることで、ファイル名エントリを短縮できます。
[in subversion/bindings/swig/birdsong] * dialects/nightingale.c (get_base_pitch): Allow 3/4-tone pitch variation to account for trait variability amongst isolated populations Erithacus megarhynchos. * dialects/gallus_domesticus.c: Remove. Unreliable due to extremely low brain-to-body mass ratio.
変更がイシュートラッカーの特定の問題に関連している場合は、ログメッセージに「issue #N」のような文字列を含めますが、変更の内容を必ず要約してください。たとえば、パッチがissue #1729を解決する場合、ログメッセージは次のようになる可能性があります。
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.
関連する変更をまとめてください。たとえば、svn_ra_get_ansible()を非推奨にして、svn_ra_get_ansible2()を作成する場合、これらの2つのものはログメッセージで互いに近くにある必要があります。
* subversion/include/svn_ra.h (svn_ra_get_ansible2): New prototype, obsoletes svn_ra_get_ansible. (svn_ra_get_ansible): Deprecate.
大規模な変更または変更グループの場合は、ログエントリを空白行で区切られた段落にグループ化します。各段落は、1つの目標を達成する一連の変更である必要があり、各グループは変更を要約する1つまたは2つの文で開始する必要があります。本当に独立した変更は、もちろん個別のコミットで行う必要があります。
誰かがパッチをコミットしている場合、または提案された変更をコミットしている場合に、他の人にクレジットを付与する方法については、「クレジット」を参照してください。
現在のコードを理解するためにログエントリが必要になることは決してありません。ログに重要な説明を書いていることに気付いた場合は、説明するコードとともに、テキストが実際にコメントに属していないかどうかを注意深く検討する必要があります。正しく行う方法の例を次に示します。
(consume_count): If `count' is unreasonable, return 0 and don't advance input pointer.
そして、`cplus-dem.c`の`consume_count`で
while (isdigit((unsigned char)**type)) { count *= 10; count += **type - '0'; /* A sanity check. Otherwise a symbol like `_Utf390_1__1_9223372036854775807__9223372036854775' can cause this function to return a negative value. In this case we just consume until the end of the string. */ if (count > strlen(*type)) { *type = save; return 0; }
これは、たとえば新しい関数が「New Function」というログエントリのみを必要とする理由です。すべての詳細はソースにある必要があります。
変更されたすべてに名前を付ける必要性には、常識的な例外を設けることができます。たとえば、プログラムの残りの部分全体で簡単な変更を必要とする変更(変数の名前変更など)を加えた場合、影響を受けるすべての関数に名前を付ける必要はなく、「すべての呼び出し元が変更された」と言うことができます。シンボルを名前変更する場合は、追跡可能性のために、古い名前と新しい名前の両方に言及することを忘れないでください。例については、r861020を参照してください。
一般的に、識別子で検索してエントリを見つけやすくすることと、網羅的に記述することで時間を浪費したり、読みにくいエントリを作成してしまうことの間には緊張関係があります。上記のガイドラインと最善の判断に基づいて、同僚の開発者に配慮してください。(また、他の人がどのようにログエントリを書いているかを確認するには、"svn log"を使用してください。)
ドキュメントや翻訳に関するログメッセージは、やや緩やかなガイドラインになります。すべてのシンボルを記述する必要はなく、変更が翻訳のような継続的なプロセスにおける単なるインクリメントである場合、すべてのファイル名を記述する必要すらありません。例えば、「マダガスカル語翻訳のさらなる作業」のように、変更を簡単に要約してください。プロジェクトに関わるすべての人が変更を理解できるように、ログメッセージは英語で記述してください。
ブランチをコードの「チェックポイント」として使用しており、レビューの準備ができていないと感じる場合は、'On the 'xxx' branch notice' の後に、ログメッセージの先頭に何らかの通知を記述してください。例えば、
*** checkpoint commit -- please don't waste your time reviewing it ***
また、そのブランチでの後続のコミットをレビューする必要がある場合は、ログメッセージに適切な「svn diff」コマンドを入力してください。差分は、そのブランチ上の隣接しない2つのコミットを含んでいる可能性が高く、レビュー担当者がどのコミットをレビューすべきかを判断するのに時間を費やす必要がないようにするためです。
コードの貢献を、一貫性があり、解析可能な方法で記録することは非常に重要です。これにより、誰が活発に貢献しているのか、そして彼らが何に貢献したのかを把握するスクリプトを作成でき、潜在的な新しいコミッターを迅速に見つけることができます。Subversionプロジェクトでは、これを実現するために、ログメッセージ内に人間が読めるが機械で解析可能なフィールドを使用しています。
他の人が書いたパッチをコミットする場合は、行の先頭に "Patch by: " を使用して、作成者を示してください。
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. Patch by: J. Random <jrandom@example.com>
複数の人がパッチを書いた場合は、それぞれを別の行にリストし、各継続行を空白で始めるようにしてください。コミッターでない場合は、名前が分かっている場合は名前とメールアドレスでリストしてください。完全なコミッターと部分的なコミッターは、COMMITTERS(そのファイルの左端の列)から、正規のユーザー名でリストしてください。さらに、実際に変更をコミットする人に対して、「me」は許容される省略形です。
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. Patch by: J. Random <jrandom@example.com> Enrico Caruso <codingtenor@codingtenor.com> jcommitter me
誰かがバグを発見したり、問題を指摘したが、パッチを書かなかった場合は、"Found by: "(または "Reported by: ")で彼らの貢献を示してください。
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. Found by: J. Random <jrandom@example.com>
誰かが有益な提案をしたが、パッチを書かなかった場合は、"Suggested by: " で彼らの貢献を示してください。
Extend the Contribulyzer syntax to distinguish finds from ideas. * www/hacking.html (crediting): Adjust accordingly. Suggested by: dlr
誰かがパッチをテストドライブした場合は、"Tested by: " を使用してください。
Fix issue #23: random crashes on FreeBSD 3.14. Tested by: Old Platformer (I couldn't reproduce the problem, but Old hasn't seen any crashes since he applied the patch.) * subversion/libsvn_fs_sieve/obliterate.c (cover_up): Account for sieve(2) returning 6.
誰かが変更をレビューした場合は、"Review by: " (または "Reviewed by: " を好む場合はそちらを使用してください) を使用してください。
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. Review by: Eagle Eyes <eeyes@example.com>
1つのフィールドは複数行にわたることができ、1つのログメッセージには任意の組み合わせのフィールドを含めることができます。
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. Patch by: J. Random <jrandom@example.com> Enrico Caruso <codingtenor@codingtenor.com> me Found by: J. Random <jrandom@example.com> Review by: Eagle Eyes <eeyes@example.com> jcommitter
貢献に関する詳細情報は、対応するフィールドの直後の括弧で囲まれた補足情報にリストする必要があります。このような補足情報は、常にすぐ上のフィールドに適用されます。次の例では、読みやすくするためにフィールドの間隔を空けていますが、間隔は任意であり、解析のために必須ではありません。
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. Patch by: J. Random <jrandom@example.com> (Tweaked by me.) Review by: Eagle Eyes <eeyes@example.com> jcommitter (Eagle Eyes caught an off-by-one-error in the basename extraction.)
現在、これらのフィールド
Patch by: Suggested by: Found by: Review by: Tested by:
は、公式にサポートされている唯一のクレジットフィールドです(「サポートされている」とは、スクリプトがそれらを探すことを認識しているという意味です)。これらはSubversionのログメッセージで広く使用されています。今後のフィールドはおそらく "VERB by: " の形式になり、時々、公式のように聞こえるが実際には公式ではないフィールドを使用する人がいるかもしれません。例えば、 "Inspired by: " のいくつかの例があります。これらは問題ありませんが、独自のフィールドを作成するよりも、公式フィールドまたは括弧で囲まれた補足情報を使用するようにしてください。また、報告者がすでにissueに記録されている場合は、 "Reported by: " を使用しないでください。代わりに、単にissueを参照してください。
Subversionの既存のログメッセージを見て、これらのフィールドを実際にどのように使用するかを確認してください。 trunkのワーキングコピーの最上部からのこのコマンドが役立ちます。
svn log | contrib/client-side/search-svnlog.pl "(Patch|Review|Suggested) by: "
注: 一部のコミットメッセージに見られる "Approved by: " フィールドは、これらのクレジットフィールドとは完全に無関係であり、一般的にスクリプトによって解析されません。これは、通常の部分的なコミッターが自分の通常の領域外でコミットを承認した人、または(リリースブランチへのマージの場合)変更のマージに投票した人を示すための標準的な構文にすぎません。
Subversionリポジトリは、https://github.com/apache/subversion/ でGitHubにミラーリングされています。
一部のユーザーはGitHubでプルリクエストを作成する可能性があります。コードがSubversionリポジトリにコミットされる場合は、ログメッセージにプルリクエストを自動的にクローズするためのテキストを含めるようにしてください。
This fixes #NNN in GitHub
コードをコミットせずにプルリクエストを管理するには、ASF IDに接続されたGitHubアカウントを持ち、トリアージ担当者の役割をASFインフラストラクチャによってあなたのアカウントに割り当てる必要があります。
Greg Steinは、`automake` と再帰的なMakefileを使用していたSubversion用のカスタムビルドシステムを作成しました。現在、Makefile.in (これはリビジョン管理されています) から生成された単一のトップレベルのMakefileを使用しています。`Makefile.in` は、`build.conf` から `gen-make.py` スクリプトによって自動的に生成される `build-outputs.mk` を含んでいます。したがって、後者の2つはリビジョン管理されていますが、`build-outputs.mk` はリビジョン管理されていません。
以下に、このシステムについて説明したGregの元のメールと、それをハックするためのアドバイスを示します。
From: Greg Stein <gstein@lyra.org> Subject: new build system (was: Re: CVS update: MODIFIED: ac-helpers ...) To: dev@subversion.tigris.org Date: Thu, 24 May 2001 07:20:55 -0700 Message-ID: <20010524072055.F5402@lyra.org> On Thu, May 24, 2001 at 01:40:17PM -0000, gstein@tigris.org wrote: > User: gstein > Date: 01/05/24 06:40:17 > > Modified: ac-helpers .cvsignore svn-apache.m4 > Added: . Makefile.in > Log: > Switch over to the new non-recursive build system. >... Okay... this is it. We're now on the build system. "It works on my machine." I suspect there may be some tweaks to make on different OSs. I'd be interested to hear if Ben can really build with normal BSD make. It should be possible. The code supports building, installation, checking, and dependencies. It does *NOT* yet deal with the doc/ subdirectory. That is next; I figured this could be rolled out and get the kinks worked out while I do the doc/ stuff. Oh, it doesn't build Neon or APR yet either. I also saw a problem where libsvn_fs wasn't getting built before linking one of the test proggies (see below). Basic operation: same as before. $ ./autogen.sh $ ./configure OPTIONS $ make $ make check $ make install There are some "make check" scripts that need to be fixed up. That'll happen RSN. Some of them create their own log, rather than spewing to stdout (where the top-level make will place the output into [TOP]/tests.log). The old Makefile.am files are still around, but I'll be tossing those along with a bunch of tweaks to all the .cvsignore files. There are a few other cleanups, too. But that can happen as a step two. [ $ cvs rm -f `find . -name Makefile.rm` See the mistake in that line? I didn't when I typed it. The find returned nothing, so cvs rm -f proceeded to delete my entire tree. And the -f made sure to delete all my source files, too. Good fugging thing that I had my mods in some Emacs buffers, or I'd be bitching. I am *so* glad that Ben coded SVN to *not* delete locally modified files *and* that we have an "undel" command. I had to go and tweak a bazillion Entries files to undo the delete... ] The top-level make has a number of shortcuts in it (well, actually in build-outputs.mk): $ make subversion/libsvn_fs/libsvn_fs.la or $ make libsvn_fs The two are the same. So... when your test proggie fails to link because libsvn_fs isn't around, just run "make libsvn_fs" to build it immediately, then go back to the regular "make". Note that the system still conditionally builds the FS stuff based on whether DB (See 'Building on Unix' below) is available, and mod_dav_svn if Apache is available. Handy hint: if you don't like dependencies, then you can do: $ ./autogen.sh -s That will skip the dependency generation that goes into build-outputs.mk. It makes the script run quite a bit faster (48 secs vs 2 secs on my poor little Pentium 120). Note that if you change build.conf, you can simply run: $ ./gen-make.py build.conf to regen build-outputs.mk. You don't have to go back through the whole autogen.sh / configure process. You should also note that autogen.sh and configure run much faster now that we don't have the automake crap. Oh, and our makefiles never re-run configure on you out of the blue (gawd, I hated when automake did that to me). Obviously, there are going to be some tweaky things going on. I also think that the "shadow" builds or whatever they're called (different source and build dirs) are totally broken. Something tweaky will have to happen there. But, thankfully, we only have one Makefile to deal with. Note that I arrange things so that we have one generated file (build-outputs.mk), and one autoconf-generated file (Makefile from .in). I also tried to shove as much logic/rules into Makefile.in. Keeping build-outputs.mk devoid of rules (thus, implying gen-make.py devoid of rules in its output generation) manes that tweaking rules in Makefile.in is much more approachable to people. I think that is about it. Send problems to the dev@ list and/or feel free to dig in and fix them yourself. My next steps are mostly cleanup. After that, I'm going to toss out our use of libtool and rely on APR's libtool setup (no need for us to replicate what APR already did). Cheers, -g -- Greg Stein, http://www.lyra.org/
そして、設定/ビルドシステムを変更またはテストするためのアドバイスを以下に示します。
From: Karl Fogel <kfogel@collab.net> To: dev@subversion.tigris.org Subject: when changing build/config stuff, always do this first Date: Wed 28 Nov 2001 Yo everyone: if you change part of the configuration/build system, please make sure to clean out any old installed Subversion libs *before* you try building with your changes. If you don't do this, your changes may appear to work fine, when in fact they would fail if run on a truly pristine system. This script demonstrates what I mean by "clean out". This is `/usr/local/cleanup.sh' on my system. It cleans out the Subversion libs (and the installed httpd-2.0 libs, since I'm often reinstalling that too): #!/bin/sh # Take care of libs cd /usr/local/lib || exit 1 rm -f APRVARS rm -f libapr* rm -f libexpat* rm -f libneon* rm -f libsvn* # Take care of headers cd /usr/local/include || exit 1 rm -f apr* rm -f svn* rm -f neon/* # Take care of headers cd /usr/local/apache2/lib || exit 1 rm -f * When someone reports a configuration bug and you're trying to reproduce it, run this first. :-) The voice of experience, -Karl
ビルドシステムは、trunkで作業するすべての開発者にとって重要なツールです。場合によっては、ビルドシステムに加えられた変更が1人の開発者にとっては完全にうまく機能しても、他の開発者にとってはビルドシステムを誤って壊してしまうことがあります。
生産性の低下を防ぐために、コミッター(完全または部分的)は、自分の選択したプラットフォームでの開発を効果的に行う能力を妨げるビルドシステムの変更を、過剰反応の非難を恐れることなく、通常のルーティングとして直ちに元に戻すことができます。変更を元に戻すコミットのログメッセージには、なぜ変更を元に戻すのかを説明する注釈を記載する必要があります。また、問題についてdev@で議論を開始するのに適した詳細を記載する必要があります。誰かがコミットメールに返信することを選択した場合に備えてください。
ただし、「デフォルトの復元モード」に入らないように注意する必要があります。問題を迅速に解決できる場合は、そうしてください。そうでない場合は、立ち止まって少し考えてください。それでも解決策がない場合は、変更を元に戻し、その議論をリストに持ち込んでください。
変更が元に戻されたら、元に戻したコミッターの論理に基づいて、元の変更を修正したバージョンが確実に修正されていると確信している場合は、元の変更のコミッターは修正されたバージョンを再コミットする必要があります。または、再コミットする前に、修正されたバージョンを元に戻したコミッターにテストのために送信する必要があります。
Subversionの自動テストフレームワークを使用および追加する方法については、subversion/tests/README および subversion/tests/cmdline/README を参照してください。
ASFインフラストラクチャチームは、BuildBotビルド/テストファームを管理しています。SubversionプロジェクトのBuildbotウォーターフォールは、ここにあります。
ビルドサービスの詳細については、ci2.apache.org にアクセスしてください。
buildbotのビルドとテストの失敗に関する通知を受信したい場合は、notifications@ メーリングリストを購読してください。
Buildbotは、インフラストラクチャリポジトリ、具体的には subversion.py ファイルで構成されています。
From: Karl Fogel <kfogel@collab.net> Subject: writing test cases To: dev@subversion.tigris.org Date: Mon, 5 Mar 2001 15:58:46 -0600 Many of us implementing the filesystem interface have now gotten into the habit of writing the test cases (see fs-test.c) *before* writing the actual code. It's really helping us out a lot -- for one thing, it forces one to define the task precisely in advance, and also it speedily reveals the bugs in one's first try (and second, and third...). I'd like to recommend this practice to everyone. If you're implementing an interface, or adding an entirely new feature, or even just fixing a bug, a test for it is a good idea. And if you're going to write the test anyway, you might as well write it first. :-) Yoshiki Hayashi's been sending test cases with all his patches lately, which is what inspired me to write this mail to encourage everyone to do the same. Having those test cases makes patches easier to examine, because they show the patch's purpose very clearly. It's like having a second log message, one whose accuracy is verified at run-time. That said, I don't think we want a rigid policy about this, at least not yet. If you encounter a bug somewhere in the code, but you only have time to write a patch with no test case, that's okay -- having the patch is still useful; someone else can write the test case. As Subversion gets more complex, though, the automated test suite gets more crucial, so let's all get in the habit of using it early. -K
SVN_DBGデバッグツールは、Cプリプロセッサマクロであり、(デフォルトでは)標準出力、または標準エラー出力にデバッグ出力を送信しながら、SVNテストスイートを妨害しないようにします。
gdbのようなデバッガの代わりになるか、またはデバッガの使用を支援するための追加情報を提供します。デバッガを使用できない状況で特に役立つ可能性があります。
svn_debugモジュールには、呼び出しのファイル:行と、#SVN_DBG_OUTPUT
stdioストリーム(デフォルトでは#stdout)へのprintfのような引数を出力する2つのデバッグ支援マクロが含まれています。
SVN_DBG( ( const char *fmt, ...) ) /* double braces are neccessary */と
SVN_DBG_PROPS( ( apr_hash_t *props, const char *header_fmt, ...) )
SVN_DBG出力の制御
--enable-maintainer-mode
で構成されている場合は常に有効になります。SVN_DBG_QUIET
変数を1に設定します。SVN_DBG
およびSVN_DBG_PROPS
マクロのインスタンスを必ず削除してください。(別名:患者にメスを忘れないでください!)SVN_DBGマクロの定義とコードは、
SVN_DBGマクロの使用を示すサンプルパッチ
Index: subversion/libsvn_fs_fs/fs_fs.c =================================================================== --- subversion/libsvn_fs_fs/fs_fs.c (revision 1476635) +++ subversion/libsvn_fs_fs/fs_fs.c (working copy) @@ -2303,6 +2303,9 @@ get_node_revision_body(node_revision_t **noderev_p /* First, try a cache lookup. If that succeeds, we are done here. */ SVN_ERR(get_cached_node_revision_body(noderev_p, fs, id, &is_cached, pool)); + SVN_DBG(("Getting %s from: %s\n", + svn_fs_fs__id_unparse(id), + is_cached ? "cache" : "disk")); if (is_cached) return SVN_NO_ERROR;
SVN_DBG_PROPSマクロの使用を示すサンプルパッチ
Index: subversion/svn/proplist-cmd.c =================================================================== --- subversion/svn/proplist-cmd.c (revision 1475745) +++ subversion/svn/proplist-cmd.c (working copy) @@ -221,6 +221,7 @@ svn_cl__proplist(apr_getopt_t *os, URL, &(opt_state->start_revision), &rev, ctx, scratch_pool)); + /* this can be called with svn proplist --revprop -r <rev> */ + SVN_DBG_PROPS((proplist,"The variable apr_hash_t *proplist contains: ")); if (opt_state->xml) { svn_stringbuf_t *sb = NULL;
「mod_dav_svn.so」には、Subversion サーバーの主要なロジックが含まれています。これは、mod_dav 内のモジュールとして実行され、mod_dav は httpd 内のモジュールとして実行されます。もし httpd がおそらく動的共有モジュールを使用している場合、mod_dav_svn にブレークポイントを設定する前に、「set breakpoint pending on」を(~/.gdbinit に) 設定する必要があるかもしれません。あるいは、httpd を起動し、中断し、ブレークポイントを設定して、続行することもできます。
% gdb httpd (gdb) run -X ^C (gdb) break some_func_in_mod_dav_svn (gdb) continue
-X スイッチは、-DONE_PROCESS と -DNO_DETACH と同等であり、それぞれ httpd がシングルスレッドとして実行され、tty に接続された状態を保つことを保証します。起動するとすぐに、リクエストを待機状態になります。そこで Ctrl+C を押してブレークポイントを設定します。
問題の原因やブレークポイントを設定する場所を特定するために、Apache のランタイムログを監視するとよいでしょう。
/usr/local/apache2/logs/error_log /usr/local/apache2/logs/access_log
問題の原因やブレークポイントを設定する場所を特定するために、Apache のランタイムログを監視するとよいでしょう。
または、作業コピー内で ./subversion/tests/cmdline/davautocheck.sh --gdb を実行すると、その作業コピー内の mod_dav_svn を使用して httpd が起動します。その後、個々の Python テストをそれに対して実行できます。作業コピー内で ./subversion/tests/cmdline/davautocheck.sh --gdb を実行すると、その作業コピー内の mod_dav_svn を使用して httpd が起動します。その後、個々の Python テストをそれに対して実行できます。./basic_tests.py --url=http://localhost:3691/.
ra_svn のバグは通常、次の暗号化されたエラーメッセージのいずれかによって現れます。
svn: Malformed network data svn: Connection closed unexpectedly
(最初のエラーメッセージは、トンネルモードでユーザーのドットファイルやフックスクリプトによってデータストリームが破損した場合も意味します。 issue #1145 を参照してください。) 最初のエラーメッセージは通常、クライアントをデバッグする必要があることを意味し、2 番目のエラーメッセージは通常、サーバーをデバッグする必要があることを意味します。
ra_svn をデバッグする最も簡単な方法は、--disable-shared --enable-maintainer-mode を指定してビルドすることです。後者のオプションを使用すると、エラーメッセージにはブレークポイントを設定する正確な行が示されます。それ以外の場合は、marshal.c:vparse_tuple() の末尾で "Malformed network data" エラーを返す行番号を調べてください。
クライアントをデバッグするには、単に gdb で起動し、ブレークポイントを設定して、問題のあるコマンドを実行します。
% gdb svn (gdb) break marshal.c:NNN (gdb) run ARGS Breakpoint 1, vparse_tuple (list=___, pool=___, fmt=___, ap=___) at subversion/libsvn_ra_svn/marshal.c:NNN NNN "Malformed network data");
いくつかの役立つ情報があります。
バックトレースは、どのプロトコル交換が失敗しているかを正確に示します。
「print *conn」は、接続バッファを表示します。read_buf、read_ptr、read_end は読み込みバッファを表し、マーシャラーが参照しているデータを表示できます。(read_buf は通常、read_end で 0 終端されていないため、バッファにゴミデータがあると誤って判断しないように注意してください。)
フォーマット文字列は、マーシャラーが何を期待していたかを示します。
デーモンモードでサーバーをデバッグするには、gdb で起動し、ブレークポイントを設定して (通常、クライアントでの「Connection closed unexpectedly」エラーは、サーバーでの「Malformed network data」エラーを示しますが、コアダンプを示す場合もあります)、単一の接続を処理するために "-X" オプションを指定して実行します。
% gdb svnserve (gdb) break marshal.c:NNN (gdb) run -X
次に、問題のあるクライアントコマンドを実行します。そこからは、クライアントをデバッグするのと同じです。
トンネルモードでサーバーをデバッグするのは、さらに面倒です。svnserve の main() の先頭付近に 「{ int x = 1; while (x); }」のようなものを貼り付け、結果の svnserve をサーバーのユーザーパスに配置する必要があります。次に、操作を開始し、サーバー上のプロセスに gdb をアタッチし、「set x = 0」を実行し、必要に応じてコードをステップ実行します。
クライアントとサーバー間のネットワークトラフィックをトレースすることは、デバッグに役立つ場合があります。ネットワークトレースを実行する方法はいくつかあります (このリストは網羅的なものではありません)。
ネットワークトレースを実行するときは、圧縮を無効にするとよいでしょう。—http-compressionパラメーターをservers設定ファイルで確認してください。
Wireshark (以前は「Ethereal」として知られていました) を使用して、会話を盗聴します。
まず、同じ Wireshark セッション内のキャプチャ間では必ず *クリア* を実行してください。そうしないと、1 つのキャプチャ (たとえば、HTTP キャプチャ) からのフィルターが、他のキャプチャ (たとえば、ra_svn キャプチャ) を妨げる可能性があります。
クリアされたら、次の手順を実行します。
キャプチャ メニューを引き下げ、キャプチャフィルター を選択します。
http:// (WebDAV) プロトコルをデバッグする場合は、ポップアップするウィンドウで、「HTTP TCP ポート (80)
」を選択します (これにより、フィルター文字列「tcp port http
」になります)。
svn:// (ra_svn) プロトコルをデバッグする場合は、新規 を選択し、新しいフィルターに名前 (たとえば、「ra_svn」) を付けて、フィルター文字列ボックスに「tcp port 3690
」と入力します。
完了したら、[OK] をクリックします。
もう一度 キャプチャ メニューに移動し、今回は インターフェース を選択し、該当するインターフェース (おそらく、クライアントと同じマシンでサーバーを実行する場合は「ループバック」のインターフェース「lo」) の横にある オプション をクリックします。
該当するチェックボックスをオフにして、プロミスキャスモードをオフにします。
右下の 開始 ボタンをクリックして、キャプチャを開始します。
Subversion クライアントを実行します。
操作が完了したら、停止アイコン (イーサネットインターフェースカード上の赤い X) をクリックします (または、キャプチャ->停止 でも機能するはずです)。これでキャプチャができました。それは行の大きなリストのように見えます。
プロトコル 列をクリックしてソートします。
次に、最初に関連する行をクリックして選択します。通常、これは最初の行だけです。
右クリックして、TCP ストリームのフォロー を選択します。Subversion クライアントの HTTP 変換のリクエスト/レスポンスのペアが表示されます。
上記の指示は、Wireshark のグラフィカルバージョン (バージョン 0.99.6) に固有のものであり、コマンドラインバージョンの「tshark」(Wireshark が Ethereal と呼ばれていた頃の「tethereal」に対応) には適用されません。
別の方法は、Subversion クライアントとサーバーの間にロギングプロキシを設定することです。これを行う簡単な方法は、socat プログラムを使用することです。たとえば、svnserve インスタンスとの通信をログに記録するには、次のコマンドを実行します。
socat -v TCP-LISTEN:9630,reuseaddr,fork TCP4:localhost:svn
次に、URL ベースとして次のものを使用して svn コマンドを実行します。svn://127.0.0.1:9630/; socatは、ポート 9630 から通常の svnserve ポート (3690) にトラフィックを転送し、両方向のすべてのトラフィックを標準エラーに出力し、トラフィックの方向を示す < および > 記号を付加します。
暗号化された https:// 接続から読み取り可能な HTTP をログに記録するには、TLS を使用してサーバーに接続する socat プロキシを実行します。
socat -v TCP-LISTEN:9630,reuseaddr,fork OPENSSL:example.com:443
次に、それをプレーンな http:// 接続のプロキシとして使用します。
svn ls http://example.com/svn/repos/trunk \ --config-option servers:global:http-proxy-host=localhost \ --config-option servers:global:http-proxy-port=9630 \ --config-option servers:global:http-compression=no
socat プロキシはプレーンな HTTP をログに記録しますが、サーバーとのすべてのネットワークトラフィックは TLS を使用して暗号化されます。
http クライアント/サーバーの設定をデバッグしている場合は、Charles や Fiddler などの Web デバッグプロキシを使用できます。
このようなプロキシを設定したら、Subversion がプロキシを使用するように設定する必要があります。これは、http-proxy-hostとhttp-proxy-portパラメーターをservers設定ファイルで確認してください。次のオプションを使用して、コマンドラインでプロキシを指定することもできます。--config-option 'servers:global:http-proxy-host=127.0.0.1' --config-option 'servers:global:http-proxy-port=8888'.
APR プールの使用により、厳密な意味でのメモリリークが発生することはまれです。割り当てたすべてのメモリは最終的にクリーンアップされます。ただし、操作によって必要以上のメモリが使用されることがあります。たとえば、大きなソースツリーのチェックアウトでは、小さなソースツリーのチェックアウトよりも多くのメモリを使用すべきではありません。それが起こる場合は、通常、有効期間が長すぎるプールからメモリを割り当てていることを意味します。
お気に入りのメモリリーク追跡ツールがある場合は、--enable-pool-debug (これにより、すべてのプール割り当てが独自の malloc() を使用するようになります) を使用して設定し、操作の途中で終了するように設定して、そこに移動できます。そうでない場合は、別の方法を示します。
--enable-pool-debug=verbose-alloc を使用して設定します。すべての割り当てでファイルと行の情報が取得されるように、APR と Subversion のすべてを再構築してください。
操作を実行し、stderr をファイルにパイプ処理します。うまくいけば、十分なディスク容量があるでしょう。
ファイルには、次のような多くの行が表示されます。
POOL DEBUG: [5383/1024] PCALLOC ( 2763/ 2763/ 5419) \ 0x08102D48 "subversion/svn/main.c:612" \ <subversion/libsvn_subr/auth.c:122> (118/118/0)
最も重要なのは 10 番目のフィールド (引用符で囲まれたもの) で、この割り当てのプールが作成されたファイルと行番号を示します。そのファイルと行に移動して、プールの有効期間を確認します。上記の例では、main.c:612 は、この割り当てが svn クライアントの最上位プールで行われたことを示しています。これが、操作中に何度も繰り返された割り当てである場合、メモリリークの原因を示します。11 番目のフィールド (括弧で囲まれたもの) は、割り当て自体のファイルと行番号を示します。
Subversion プロジェクトは、Web サイトの改善を歓迎します。ただし、プロセスは、ブラウザで [名前を付けて保存] をクリックし、変更を編集してメールで送信するほど簡単ではありません。まず、多くのページは実際には 3 つ以上のファイルで構成されているため、ブラウザは正しくレンダリングされたコピーを保存しません。
このため、大幅な変更を送信する予定がある場合は、ソースのコピーを入手し、変更を確認するためのテストミラーを設定することをお勧めします。
もちろん、小さな変更の場合は、パッチを視覚的に検査するだけで十分な場合もあります。
Web サイトのソースは、Subversion リポジトリから入手できます。ソースを参照するには、 https://svn.apache.org/repos/asf/subversion/site/ にアクセスしてください。
~/projects/svn
にコピーをダウンロードするには、このページの残りの部分で使用される場所である次のコマンドを使用します。
mkdir -p ~/projects/svn cd ~/projects/svn svn co https://svn.apache.org/repos/asf/subversion/site/ site
別の場所にダウンロードする場合は、そこを指すように Web サーバー設定のパスを調整する必要があります。
Subversion Web サイトでは、Web サーバー内でページを組み立てるために *サーバーサイドインクルード (SSI)* を使用しています。これは、変更を検証するために、Apache 2.2 または Apache 2.4 のいずれかのシステムにインストールされたサーバーに接続された Web ブラウザで関連ページを表示する必要があることを意味します。
次の手順では、Subversion Web サイトのローカルコピーを Unix タイプのシステムで正しくレンダリングする Apache 仮想ホスト を提供する必要があります。これは、システムに応じて、/etc/apache2, /etc/httpd
または同様のディレクトリにある可能性があります。これらの手順は、Apache 2.2 および Apache 2.4 でテストされています。
/home/user/projects/svn/site
ディレクトリにあると仮定します。site/publish
ディレクトリを、メインサーバーまたはVirtualHostのDocumentRootとして使用するようにApacheサーバーを設定します。mod_include.so
が含まれていることを確認してください。Options +Includes
AddOutputFilter INCLUDES .html
すべてをまとめると、VirtualHost構成の例は次のようになります。
<VirtualHost *:8080> ServerAdmin webmaster@localhost DocumentRoot /home/user/projects/svn/site/publish <Directory /home/user/projects/svn/site/publish/> Options +Includes AddOutputFilter INCLUDES .html </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel debug CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
サーバーを再起動またはリロードした後、次のリンクを使用すると、SubversionコミュニティガイドのWeb変更ページのコピーが表示されるはずです:
http://127.0.0.1:8080/docs/community-guide/(none)#web_mirror
Webサイトに大幅な変更を加えるすべてのパッチを検証してください。
このページで推奨されているようにWebサイトのミラーを設定した場合は、コマンドラインを使用して変更したページの正しくレンダリングされたコピーをフェッチします。
wget http://127.0.0.1:8080/docs/community-guide/YOUR_CHANGED_PAGE.html
次に、結果のファイルをHTMLバリデーター(例:W3Cバリデーターサービス)にアップロードします。
プロジェクトのWebページに関するパッチのログメッセージを作成するときは、たとえば
https://subversion.dokyumento.jp/docs/community-guide/some_page.html#section-name
パッチで変更されたファイルの名前をsite/
ディレクトリを基準にしてログメッセージにリストし、追加または変更されたセクションのアンカーを次のようにリストします。
* docs/community-guide/some_page.html (section-name): fixed issue xyz
Subversionのパッチ要件の詳細については、プロジェクトの一般的なパッチガイドラインおよびログメッセージガイドラインに従ってください。
以下のアドバイスは、Subversionメーリングリストでの長年の経験に基づいており、それらのリストで最も頻繁に見られる問題に対処しています。これはメーリングリストのエチケットに関する完全なガイドではありません。必要に応じて、インターネットで簡単に見つけることができます。
メーリングリストに投稿するときにこれらの規則に従うと、投稿が読まれ、回答される可能性がはるかに高くなります。
迷ったときは、dev@subversion.apache.orgではなく、users@subversion.apache.orgにメールしてください。users@リストには、多くの経験豊富な人々(Subversionのメンテナーの一部を含む)がいます。彼らはあなたの質問に答えることができるかもしれません。また、バグを見つけたと思われる場合は、それが本当にバグであるかどうかを判断できます。新機能を提案したい場合でも、users@に投稿する必要があります。多くの機能提案は以前に議論されたアイデアであり、users@subversion.apache.orgメーリングリストの誰かが、あなたの提案がそうであるかどうかを通常は伝えることができます。
users@で回答が得られなかった後の最後の手段として、dev@に投稿しないでください。2つのリストには異なる役割があります。users@はサポートフォーラムであり、dev@は開発ディスカッションリストです。users@でサポートに関する質問に回答が得られないのは残念ですが、それがdev@への質問に適しているということにはなりません。
もちろん、メールがSubversionのバグの可能性に関するもので、users@で反応がなかった場合は、dev@で質問してもかまいません。バグは開発トピックです。そして、パッチは常にdev@に直接送信する必要があります。
トピックに非常に熱心なときは、メールスレッド内のすべてのメッセージに返信したくなることがあります。これはしないでください。メーリングリストはすでに高トラフィックであり、すべてのメッセージにフォローアップすると、ノイズが増えるだけです。
代わりに、メールスレッド全体を読み、あなたが言いたいことを慎重に考え、返信するメッセージを1つ選択し、次にあなたの考えを述べます。トピックが分岐し始めた場合にのみ、スレッド内の2つの別々のメッセージに返信するのが理にかなっている場合があります。
72列を超える行を使用しないでください。多くの人がメールを読むために80列のターミナルを使用しています。テキストを72列で記述することで、将来の返信で引用文字が追加されても、テキストの折り返しを強制することなく、スペースを確保できます。もちろん、72列の制限はメッセージの散文部分にのみ適用されます。パッチを投稿する場合は、パッチに関するセクションを参照してください。
一部のメーラーでは、一種の自動的な行の折り返しが行われます。つまり、メールを作成するときに、表示には実際には存在しない改行が表示されます。メールがリストに到達すると、思っていた改行は含まれていません。メールエディターでこれが発生する場合は、調整できる設定を探して、真の改行を表示するようにしてください。
各文の最初の文字を大文字にし、段落を使用します。画面出力やその他の種類の例を示す場合は、散文から明確に分離するようにオフセットします。これらのことを行わないと、メールは可能な限り読みにくくなり、多くの人がまったく読まなくなるでしょう。
リスト投稿に応答するときは、メールリーダーの「フォローアップ」、「全員に返信」、または「グループ返信」機能を使用してください。そうしないと、メールは元の投稿の作成者にのみ送信され、リスト全体には送信されません。プライベートに返信する理由がない限り、リストに応答する方が常に良いので、誰もが見て学ぶことができます。(また、投稿にプライベートな応答を頻繁に受け取る多くの人が、代わりにこれらの応答をリストに送ってほしいと表明しています。)
Subversionメーリングリストは、次のものを変更しません。返信先ヘッダーをリストへの応答をリダイレクトするように設定します。それらは残します返信先元の送信者が持っていたものに設定されています。https://www.unicom.com/pw/reply-to-harmful.htmlにリストされている理由、特に「最小限の損害の原則」および「家に帰る道が見つからない」セクションを参照してください。時々、誰かがなぜ返信先ヘッダーを設定しないのかを尋ねる投稿をします。その人は時々、https://marc.merlins.org/netrants/reply-to-useful.htmlに言及します。これは、返信先フィールドを変更することに賛成する議論を提供します。リスト管理者は両方のドキュメントを認識しており、議論の両側にメリットがあることを理解していますが、最終的には返信先ヘッダーを変更しないことを選択しました。このトピックを再開しないでください。
既存の投稿に返信して新しいスレッド(件名)を開始しないでください。代わりに、手動でリストアドレスを書き出す必要があっても、新しいメールを開始してください。既存の投稿に返信すると、メールリーダーは、投稿をそのスレッドのフォローアップとしてマークするメタデータを含める場合があります。件名ヘッダーを変更しても、これを防ぐには十分ではありません。多くのメールリーダーは、投稿を誤ったスレッドに入れるのに十分なメタデータを保持します。これが起こると、一部の人は投稿を見ないだけでなく(そのスレッドを無視しているため)、スレッドを読んでいる人はトピックから外れた投稿で時間を無駄にします。これを回避する最も安全な方法は、「返信」を使用して新しいトピックを開始しないことです。
(問題の根本原因は、一部のメールインターフェイスが「返信」機能によって生成されたメッセージが新しいメッセージとは異なることを示していないことです。このようなプログラムを使用する場合は、その開発者に機能拡張リクエストまたはパッチを送信して、区別を示すようにすることを検討してください。)
スレッドを保持したまま件名ヘッダーを変更する必要がある場合(おそらくスレッドが他のトピックに迷い込んだため)、次のように、古い件名を括弧で囲んで新しい件名で投稿します。
Blue asparagus | |_ Re: Blue asparagus | |_ Yellow elephants (was: Re: Blue asparagus) <-- ### switch ### | |_ Re: Yellow elephants
トップポストに対して反射的に人を責めないでください。「トップポスト」とは、応答テキストを、引用されたテキストとインターリーブしたり、その下に配置したりするのではなく、その上に配置することです。通常、引用されたテキストは応答を理解するための重要なコンテキストを提供するため、トップポストは妨げになります。時々、人々はインターポストまたはボトムポストをする方が良い場合にトップポストを行い、他の人がこのことで彼らを責めます。責める必要がある場合は、優しく責め、このような些細な問題を指摘するためだけに余分な投稿をする必要はありません。トップポストの方が好ましい状況もあります。たとえば、応答が短く一般的で、引用された長いテキスト全体に適用される場合です。したがって、トップポストは常に判断の呼びかけであり、いずれにしても、不適切に行われた場合でも大きな不便さではありません。
悪い引用習慣で人を燃やす方法ではなく、引用方法に関するアドバイスを探してここに来た場合は、https://www.netmeister.org/news/learn2quote.html(ドイツ語:http://www.afaik.de/usenet/faq/zitieren/download/zitieren-alles.html)を参照してください。
パッチの送信方法については、こちらを参照してください。コードを修正するだけでなく、これらのWebページを修正するパッチも送信できることに注意してください。WebページのレポジトリURLはhttps://svn.apache.org/repos/asf/subversion/site/です。
可能な場合は、ASCIIまたはISO-8859テキストを使用してください。テキストのみのメールリーダーには不透明な可能性のあるHTMLメール、リッチテキストメール、またはその他の形式を投稿しないでください。言語に関して:英語のみのポリシーはありませんが、英語で投稿することで最良の結果が得られるでしょう。これは、最も多くのリスト参加者が共有する言語です。
Subversionは完璧なソフトウェアではありません。他のソフトウェアと同様に、バグが含まれ、機能が不足しており、改善の余地があります。ほとんどのソフトウェアプロジェクトと同様に、Subversionプロジェクトでは、ソフトウェアの既知の未解決の問題を管理するために問題追跡ツールを使用しています。しかし、おそらくほとんどのソフトウェアプロジェクトとは異なり、問題追跡ツールを比較的デブリがない状態に保とうとしています。Subversionの問題について聞きたくないわけではありません。結局のところ、壊れていることを知らないものを修正することはできません。混乱した問題追跡ツールは、助けになるよりもむしろ妨げになることがわかっています。
このメールは、すべてを語っています(ただし、最近はdev@リストに投稿する前にusers@リストに投稿する必要があります)。
From: Karl Fogel <kfogel@collab.net> Subject: Please ask on the list before filing a new issue. To: dev@subversion.tigris.org Date: Tue, 30 Jul 2002 10:51:24 (CDT) Folks, we're getting tons of new issues, which is a Good Thing in general, but some of them don't really belong in the issue tracker. They're things that would be better solved by a quick conversation here on the dev list. Compilation problems, behavior questions, feature ideas that have been discussed before, that sort of thing. *Please* be more conservative about filing issues. The issues database is physically much more cumbersome than email. It wastes people's time to have conversations in the issues database that should be had in email. (This is not a libel against the issue tracker, it's just a result of the fact that the issues database is for permanent storage and flow annotation, not for real-time conversation.) If you encounter a situation where Subversion is clearly behaving wrongly, or behaving opposite to what the documentation says, then it's okay to file the issue right away (after searching to make sure it isn't already filed, of course!). But if you're a) Requesting a new feature, or b) Having build problems, or c) Not sure what the behavior should be, or d) Disagreeing with current intended behavior, or e) Not TOTALLY sure that others would agree this is a bug, or f) For any reason at all not sure this should be filed, ...then please post to the dev list first. You'll get a faster response, and others won't be forced to use the issues database to have the initial real-time conversations. Nothing is lost this way. If we eventually conclude that it should be in the issue tracker, then we can still file it later, after the description and reproduction recipe have been honed on the dev list. Thank you, -Karl
以下は、Subversionへの問題の報告または機能拡張の要求時に遵守をお願いするポリシーです。
まず、それが本当にバグであることを確認してください。Subversionが期待どおりに動作しない場合は、ドキュメントやメーリングリストのアーカイブを調べて、それが期待どおりに動作するはずだという証拠を探してください。もちろん、Subversionがデータを破壊したり、モニターから煙が出たりするような常識的なことなら、自分の判断を信じて構いません。しかし、確信が持てない場合は、まずユーザーメーリングリスト(users@subversion.apache.org)で質問するか、IRC(irc.libera.chat, channel #svn)(WebインターフェースまたはMatrix)で質問してください。
また、バグトラッカーを検索して、すでに誰かがこのバグを報告していないかを確認してください。
それがバグであり、私たちがまだそれを認識していないことが確認できたら、最も重要なことは、簡単な説明と再現手順を作成することです。たとえば、最初に発見したバグが10コミットにわたる5つのファイルに関わる場合、1つのファイルと1つのコミットだけで発生するように試みてください。再現手順が簡単であればあるほど、開発者がバグを再現して修正できる可能性が高くなります。
再現手順を作成する際は、バグを発生させるために行ったことを文章で説明するだけではいけません。代わりに、実行した正確なコマンドのシーケンスと、その出力をそのまま書き出してください。これを行うには、コピー&ペーストを使用してください。ファイルが関係する場合は、ファイルの名前と、関連性があると思われる場合はその内容を含めるようにしてください。最も良いのは、再現手順をスクリプトとしてパッケージ化することです。それは私たちにとって非常に役立ちます。以下に、そのようなスクリプトの例を示します。Unix系のシステムおよびBourneシェル用のrepro-template.sh、またはWindowsシェル用のrepro-template.bat(Paolo Compieta氏提供)。他のシステム用の同様のテンプレートスクリプトの貢献も歓迎します。
簡単な健全性チェック:あなたは*最新版*のSubversionを実行していますよね? :-) おそらくバグはすでに修正されています。最新のSubversion開発ツリーに対して再現手順をテストする必要があります。
再現手順に加えて、バグを再現した環境の完全な説明も必要です。それはつまり、
これらすべてが揃ったら、レポートを書く準備が整いました。まず、バグが何であるかを明確に説明することから始めます。つまり、Subversionがどのように動作することを期待していたか、そして実際にどのように動作したかを対比して説明します。あなたにとってはバグが明白に見えるかもしれませんが、他の人にとってはそうではないかもしれないので、推測ゲームは避けるのが最善です。次に、環境の説明と再現手順を続けてください。原因についての推測やバグを修正するためのパッチを含めることもできます。それは素晴らしいことです。 パッチ提出ガイドラインを参照してください。
この情報をすべてdev@subversion.apache.orgに投稿してください。または、すでにそこに連絡して問題を提出するように求められた場合は、問題追跡システムにアクセスして、そこの指示に従ってください。
ありがとうございます。効果的なバグレポートを提出するには多くの作業が必要なことは承知していますが、優れたレポートは開発者の時間を何時間も節約し、バグを修正する可能性を大幅に高めることができます。
バグがSubversion自体にある場合は、users@subversion.apache.orgにメールを送ってください。バグとして確認されたら、誰か(おそらくあなた自身)がそれを問題追跡システムに入力できます。(または、バグについてかなり確信がある場合は、開発リストdev@subversion.apache.orgに直接投稿してください。ただし、確信がない場合は、まずusers@に投稿することをお勧めします。そこでは、発生した動作が予期されたものかどうかを教えてくれます。)
バグがAPRライブラリにある場合は、次の両方のメーリングリストに報告してください。 dev@apr.apache.org、dev@subversion.apache.org。
バグがNeon HTTPライブラリにある場合は、以下に報告してください。 neon@webdav.org、dev@subversion.apache.org。
バグがApache Serf HTTPライブラリにある場合は、以下に報告してください。 dev@serf.apache.org、dev@subversion.apache.org。
バグがApache HTTPD 2.xにある場合は、次の両方のメーリングリストに報告してください。 dev@httpd.apache.org、dev@subversion.apache.org。Apache httpdの開発者メーリングリストはトラフィックが多いため、バグレポートの投稿が見過ごされる可能性があります。 https://httpd.apache.org/bug_report.htmlでバグレポートを提出することもできます。
バグがあなたのカーペットにある場合は、抱きしめて温かくしてください。
問題追跡システムのマイルストーンは、Subversion開発者がどのように取り組みを組織し、相互に、またSubversionユーザーベースとコミュニケーションをとるかという重要な側面です。主に高度な問題のトリアージを行う際に使用される一部のマイルストーンを除き、プロジェクトの問題追跡システムのマイルストーンは、リリースバージョン番号とそのバリエーションを反映するように命名される傾向があります。マイルストーンは、問題の状態に応じてわずかに異なる目的で使用されるため、これらの区別を理解することが重要です。
オープンな問題(ステータスがOPEN, IN PROGRESS、またはREOPENED)の場合、マイルストーンは、開発者がその問題の解決を目標としているSubversionリリースを示します。一般的に、MINORVERSION-considerのような形式のマイルストーンを使用して、問題の解決がMINORVERSION.0でリリースしたいものの候補であることを示します。たとえば、Subversion 1.9.0に追加できる可能性があり、追加すべきだと考える機能は、1.9-considerのマイルストーンを取得します。当然のことながら、これらのリリースターゲットの精度は、将来を見れば見るほど悪化します。そのため、ユーザーはそれらを開発者コミュニティからの拘束力のある約束として*扱わない*ようにしてください。
常に、「次の大きなリリース」に向けた作業がコミュニティで行われています。そのリリースが形になり始めると、開発者はどの問題がリリースに「必須」であるか(「リリースの妨げ」とも呼ばれます)、どの問題が「あると便利」であるか、どの問題が将来のリリースに延期されるべきかについて、より良く把握できるようになります。問題のマイルストーンは、これらの決定の結果を実行するために使用されるメカニズムです。リリースの妨げであると見なされる問題は、MINORVERSION-considerマイルストーンからMINORVERSION.0マイルストーンに移動されます。「あると便利」なものは、MINORVERSION-considerマイルストーンに残されます。リリースから延期された問題は、ANOTHERMINORVERSION-considerまたはunscheduledのいずれかでマイルストーンが変更されます。これは、問題がいつ対処されるかについて明確な推測があるかどうかによって異なります。
前の例を続けると、Subversion 1.9.0の(予定)開発が進むにつれて、開発者はリリース用に計画した機能を評価します。その機能なしではSubversion 1.9をリリースすべきではないと判断した場合、そのマイルストーンを1.9-considerから1.9.0に変更します。その機能をリリースしたいが、それをコミットしたくない場合は、マイルストーンを1.9-considerのままにします。また、1.9.xリリースシリーズで機能を実装しないことがわかっている場合は、問題のマイルストーンを別のもの(1.10-considerなど)に変更します。
の精度MINORVERSION.0マイルストーンは非常に重要です。開発者は、主要なリリースサイクルの最終日にそれらの問題を使用して作業に集中する傾向があるためです。
修正された問題(ステータスがRESOLVEDで、解決策がFIXED)の場合、問題のマイルストーンは新しいユーティリティを引き受けます。つまり、その問題の解決策を最初に含むSubversionリリースバージョンを追跡します。特定の問題のターゲットリリースバージョンに関係なく、解決されたら、そのマイルストーンは、その解決策を最初に含むリリースの正確なバージョン番号を反映する必要があります。
その他のクローズされた問題(「オープン」ではなく、「修正」されなかった問題)の場合、問題のマイルストーンはほとんど意味をなさない傾向があります。問題自体が重複しているため、または無効または不正確なレポートであるために実質的に無視されている場合、トラッカーフィールドを維持しようとする意味はほとんどありません。
これらの状態間で問題を移行する場合は注意が必要です。解決されたオープンな問題は、その変更を最初に反映するSubversionリリースを反映するようにマイルストーンを調整する必要があります。以前のリリースストリームにバックポートされた解決済みの問題は、以前のリリースのバージョン番号を指すようにマイルストーンを調整する必要があります。最後に、解決済みの問題がREOPENEDになった場合、問題がリリースの妨げであるかどうか(MINORVERSION.0)またはそうでないか(MINORVERSION-consider)を考慮してマイルストーンを再評価する必要があります。このような状況では、問題が修正されたと解決される前に使用されていたマイルストーンを確認するために、問題の変更履歴を参照すると役立つ場合があります。
問題が提出されると、特別なマイルストーン「---」、つまり*未設定のマイルストーン*に移行します。これは、誰かがそれらを確認して、何をすべきかを決定する機会を得るまで問題が存在する保留領域です。
未設定のマイルストーンの問題は、マイルストーンでソートすると最初にリストされ、*問題のトリアージ*は、すべてを徹底的に調べるプロセスです。オープンな問題(未設定のマイルストーンから開始)、どれを今すぐ修正するのに十分重要か、別のリリースまで待つことができるか、既存の問題の重複であるか、すでに解決済みであるかなどを決定します。オープンなままになる各問題について、タイプ、サブコンポーネント、プラットフォーム、OS、バージョン、キーワード(存在する場合)など、さまざまなフィールドが適切に設定されていることを確認することも意味します。
プロセスの概要は次のとおりです(この例では、1.5が次のリリースであるため、緊急の問題はそこに移動します)。
for i in issues_marked_as("---"): if issue_is_a_dup_of_some_other_issue(i): close_as_dup(i) elif issue_is_invalid(i): # A frequent reason for invalidity is that the reporter # did not follow the "buddy system" for filing. close_as_invalid(i) elif issue_already_fixed(i): version = fixed_in_release(i) move_to_milestone(i, version) close_as_fixed(i) elif issue_unreproducible(i): close_as_worksforme(i) elif issue_is_real_but_we_won't_fix_it(i): close_as_wontfix(i) elif issue_is_closeable_for_some_other_reason(i): close_it_for_that_reason(i) # Else issue should remain open, so DTRT with it... # Set priority, environment, component, etc, as needed. adjust_all_fields_that_need_adjustment(i) # Figure out where to put it. if issue_is_a_lovely_fantasy(i): move_to_milestone(i, "blue-sky") if issue_is_not_important_enough_to_block_any_particular_release(i): move_to_milestone(i, "nonblocking") elif issue_resolution_would_require_incompatible_changes(i): move_to_milestone(i, "2.0-consider") elif issue_hurts_people_somewhat(i): move_to_milestone(i, "1.6-consider") # or whatever elif issue_hurts_people_a_lot(i): move_to_milestone(i, "1.5-consider") elif issue_hurts_and_hurts_and_should_block_the_release(i): move_to_milestone(i, "1.5")
このドキュメントは、Subversion開発者がセキュリティ問題にどのように対応するかに関する情報です。問題を報告するには、セキュリティレポート手順を参照してください。
Subversionの最初の役割は、データの安全性を保つことです。そのため、Subversion開発コミュニティはセキュリティを非常に重視しています。そのことを示す一つの方法として、私たちは暗号やセキュリティの専門家であるふりをしません。Subversionのために独自のセキュリティメカニズムをたくさん書くのではなく、代わりに、その分野の知識を持つ人々が提供するセキュリティライブラリやプロトコルと相互運用できるようにSubversionを教育することを好みます。例えば、Subversionはワイヤ暗号化をOpenSSLのようなものに委ねます。認証と基本的な認可は、Cyrus SASLやApache HTTP Server、およびその豊富なモジュールコレクションによって提供されるメカニズムに委ねます。サードパーティのライブラリやAPIを使用することでセキュリティ専門家の知識を活用できる限り、今後もそうしていきます。
このドキュメントでは、セキュリティ上の影響がある可能性があると分類される問題を検知または発見した場合に、私たちが取る手順について説明します。これは、コミッター向けのApacheのガイドラインを補完するものです。
セキュリティ問題については、private@subversion.apache.org + security@apache.orgで議論する必要があります。security@subversion.apache.orgは、これら2つのリストを対象とする便利なエイリアスです。(たとえば、security@httpd.a.oとは異なり、これはメーリングリストではないため、個別に登録/登録解除することはできません。)
過去のセキュリティアドバイザリのリストは、https://subversion.dokyumento.jp/security/で公開しています。
進行中の問題は、PMCのプライベートリポジトリで追跡します。https://svn.apache.org/repos/private/pmc/subversion/security
私たちは公開された手順に従うことを目指しています。
通常、ASFが推奨する手順に従います。また、通常、事前に選択された当事者への事前通知も行います。この詳細は、PMCのプライベートリポジトリで管理されています。
また、How to Roll Releases in Privateに記載されている別の手順も使用する場合があります。現時点では、通常この手順は使用しません。
このドキュメントは、一般に、具体性が増す順に3つの部分に分けることができます。
Subversionのリリース管理者は、release.pyという名前のPythonスクリプトに体系化された一連の手順を使用します。このスクリプトは、リリースプロセスの自動化された手順のほとんどを実行するために使用できます。詳細については、-hオプションを指定して実行してください。
以下のプロジェクト固有のガイドラインに加えて、リリース管理者を目指す人は、一般的なApacheリリースポリシーも読むと良いでしょう。 時には少しパッチワークのように見えるかもしれませんが、一般的なベストプラクティスと、Subversionがより大きなASFエコシステムにどのように適合するかについて、良いアイデアを得ることができます。
Subversionは、「MAJOR.MINOR.PATCH」のリリース番号を使用します。「偶数==安定版、奇数==不安定版」の慣習は使用しません。修飾されていないトリプレットはすべて安定版リリースを示します。
1.0.1 --> first stable patch release of 1.0 1.1.0 --> next stable minor release of 1.x after 1.0.x 1.1.1 --> first stable patch release of 1.1.x 1.1.2 --> second stable patch release of 1.1.x 1.2.0 --> next stable minor release after that
リリースの順序は半非線形です。1.0.3は1.1.0の後に出る可能性があります。ただし、パッチラインが廃止されたことを宣言し、次のマイナーリリースにアップグレードするように指示するため、長期的には番号付けは基本的に線形になります。
番号は複数の桁を持つ場合があります。たとえば、1.7.19は1.7.xラインの19番目のパッチリリースです。これは、1.7.2の3年後、1.7.20の3か月前にリリースされました。
Subversionのリリースは、バージョン番号に続くテキストで修飾される場合があり、これらはすべてプリリリースプロセスのさまざまなステップを表します。安定性の低い順から高い順に
修飾子 | 意味 | 例 | の出力svn --version |
---|---|---|---|
Alpha | 問題があるか、問題があることを予想していますが、関心のある個人からのテストを求めます。 | subversion-1.7.0-alpha2 | version 1.7.0 (Alpha 2) |
Beta | 問題があるとは思っていませんが、念のため注意してください。 | subversion-1.7.0-beta1 | version 1.7.0 (Beta 1) |
RC(リリース候補) | このリリースは、最終的な提案バージョンになるための候補です。重大なバグが見つからなければ、-rcタグが削除され、このリリースの内容が安定版として宣言されます。 | subversion-1.7.0-rc4 | version 1.7.0 (Release Candidate 4) |
「make install」subversion-1.7.0-rc1を実行すると、もちろん、あたかも「1.7.0」であるかのようにインストールされます。修飾子はリリースのメタデータです。後続のプリリリースリリースで前のリリースを上書きし、最終リリースで最後のプリリリースを上書きする必要があります。
作業コピービルドの場合、心配する必要のあるtarball名はありませんが、「svn --version」は特別な出力を生成します。
version 1.7.1-dev (under development)
バージョン番号は、プロジェクトが目指している次のバージョンです。重要なことは、「開発中」と言うことです。これは、ビルドが作業コピーから作成されたことを示しており、バグレポートで役立ちます。
正式な安定化期間に入る前に、新機能の広範なテストを実施したい場合は、AlphaおよびBetaのtarballをリリースすることがあります。「alpha1」、「alpha2」などのリリースがあった場合でも、Betaリリースを行う必要はありません。「rc1」に直接ジャンプすることもできます。ただし、Betaが役立つ状況もあります。たとえば、UIの決定に確信がなく、正式なリリース候補に固める前に、より広範なユーザーフィードバックを得たい場合などです。
AlphaとBetaは、テストを手伝いたい人、および最終リリース前に互換性のない変更がある可能性があることを理解している人のみが対象です。署名要件は、リリースマネージャーの裁量に委ねられています。通常、RMはプラットフォームごとに1つまたは2つの署名のみを必要とし、署名者に対して、テストで軽微な障害が明らかになっても、他の人によるテストを行う価値があるほどコードが十分に堅牢であると考える限り、署名できることを伝えます。RMは、署名者に署名とともにエラーの説明を含めるように要求する必要があります。これにより、AlphaまたはBetaリリースが発表されたときに問題を公開できます。
AlphaまたはBetaが公に発表される場合、配布パッケージ担当者はパッケージングをしないように強く警告する必要があります。良い例については、Hyrum K. Wrightからのこのメールを参照してください。
(以下に詳述されている)当社の互換性ルールは、最終的なx.y.0バージョンが承認され、リリースされた後にのみ適用され始めます。 trunkまたはAlpha/Beta/RCプリリリースに表示されたAPI、ワイヤプロトコル、およびオンディスクフォーマットは、一切の互換性の約束の対象ではありません。そうする正当な理由が見つかった場合は、最終リリースまで任意に変更する可能性があります。不快に感じるインターフェースまたはシリアル化フォーマットを完全に削除することさえあります。
これは、永続データ(作業コピーとリポジトリ)にとって特に問題です。最終リリースで、レガシーフォーマット用のアップグレードパス(コードパスまたは指定されたスクリプト)を提供しない可能性があるためです。(もちろん、プリリリースをテストする開発者やユーザーの利益のために、そのようなスクリプトを提供する可能性がありますが、そうする義務はありません。)したがって、プリリリースは、長期的な安全保管を目的としたデータで決して信頼しないでください。
同時に、API設計のバグを指摘するのに最適な時期は、リリースされて既成事実になる前、つまり、初期設計およびプリリリース段階であることを読者に思い出させたいと思います。
リリースまたは候補リリースが、コード以外の問題(パッケージングの不具合など)のために迅速に再発行する必要がある場合は、tarballがまだ署名によって承認されていない限り、同じ名前を再利用してもかまいません。ただし、署名付きの標準配布エリアにアップロードされている場合、または再発行がユーザーが実行する可能性のあるコードの変更が原因である場合は、古い名前を破棄して、次の名前を使用する必要があります。
リリース予定のtarballがユーザーに公開および発表される前に古い名前が破棄された場合、破棄された名前は非公開リリースと見なされ、ドキュメント(CHANGESやタグのログメッセージなど)を更新してその旨を反映する必要があります。(例については、1.8.7を参照してください。)破棄されたリリースのタグとtarballはリポジトリの履歴に残りますが、一般的な使用はサポートされていません(それどころか、リリースを妨げるバグがあることがわかっています)。
Subversionは厳格な互換性に従い、APRと同じガイドライン(https://apr.apache.org/versioning.htmlを参照)に、後述するいくつかの拡張機能を加えています。これらのガイドラインは、さまざまな形式のクライアント/サーバーの相互運用性を確保し、ユーザーがMAJOR.MINOR Subversionリリース間で明確なアップグレードパスを確保できるようにするために定められています。
互換性は、APIやABIからコマンドラインの出力形式に至るまで、さまざまな軸に及びます。私たちは、既存のアーキテクチャを新しい機能をサポートするために変更する必要性と、現在のユーザーを可能な限り最大限にサポートする必要性のバランスを取ろうとしています。基本的な考え方は次のとおりです。
同じMAJOR.MINORラインの異なるパッチリリース間でのアップグレード/ダウングレードは、決してコードを壊しません。バグフィックスが消えたり再出現したりする可能性がありますが、APIのシグネチャとセマンティクスは同じままです。(もちろん、セマンティクスはバグフィックスに適切な些細な方法で変更される可能性がありますが、呼び出しコードの調整を強制するような方法ではありません。)
同じメジャーラインの新しいマイナーリリースへのアップグレードは、新しいAPIが出現する可能性がありますが、APIを削除することはありません。古いマイナー番号で記述されたコードは、そのラインのそれ以降のすべてのマイナー番号で動作します。ただし、新しいAPIを利用する新しいコードが記述されている場合、その後のダウングレードは機能しない可能性があります。
(時折、古いAPIの動作をわずかに変更する必要があるバグが見つかります。これは通常、さまざまなコーナーケースやその他のまれな領域でのみ現れます。これらの変更は、各MAJOR.MINORリリースのAPIエラッタとして文書化されています。)
メジャー番号が変更されると、すべてが当てはまらなくなります。これはAPIを完全にリセットする唯一の機会であり、インターフェースを無意味に削除しないように努めますが、それを少し整理するために利用します。
Subversionは、APRガイドラインを拡張して、クライアント/サーバーの互換性の問題をカバーしています。
サーバー(またはクライアント)のパッチまたはマイナー番号リリースは、同じメジャーラインのクライアント(またはサーバー)との互換性を損なうことはありません。ただし、リリースで提供される新しい機能は、接続の反対側に対応するアップグレードがないとサポートされない場合があります。特にra_svnコードを更新する場合は、次の原則に従ってください。
フィールドは任意のタプルに追加できます。古いクライアントはそれらを単に無視します。(現在、マーシャリングの実装では、タプルのオプション部分に数値またはブール値を配置することはできませんが、それを変更してもプロトコルには影響しません。)
API呼び出しに情報が追加されたときに、このメカニズムを使用できます。
接続確立時に、クライアントとサーバーは機能キーワードのリストを交換します。
パイプラインの導入やAPI呼び出しからの情報の削除など、より複雑な変更にこのメカニズムを使用できます。
新しいコマンドを追加できます。サポートされていないコマンドを使用しようとすると、チェックして対処できるエラーが発生します。
プロトコルのバージョン番号を上げて、古いクライアントまたはサーバーの正常な拒否を許可したり、クライアントまたはサーバーが古い方法で処理する必要がある場合を検出できるようにしたりできます。
このメカニズムは最後の手段であり、機能キーワードの管理が難しすぎる場合に使用します。
ワーキングコピーとリポジトリの形式は、同じマイナーシリーズのすべてのパッチリリースで後方および前方互換性があります。それらは同じメジャーシリーズのすべてのマイナーリリースで前方互換性があります。ただし、マイナーリリースでは、以前のマイナーリリースでは機能しないワーキングコピーまたはリポジトリを作成することが許可されています。「作成」は「アップグレード」と「作成」の両方を意味します。
時折、Subversionでセキュリティの問題が報告または発見され、リリース時に特別な扱いが必要になることがあります。一般的なリリースプロセスは同じであり、開発者がこれらの問題をどのように扱うかの詳細は他の場所で説明されています。
Subversionはバイナリパッケージを配布せず、代わりにサードパーティのパッケージャーに依存しています。幸いなことに、多くの個人や企業がこの点で努力を惜しまず、私たちは彼らの努力に感謝しています。
あなたがサードパーティのパッケージャーである場合、バグ修正またはその他の変更がユーザーにとって重要であり、標準のSubversionリリースサイクルよりも早くそれらをユーザーに届けたい場合があります。または、対象ユーザーにメリットをもたらす一連のパッチをローカルで管理している場合もあります。可能な場合は、パッチプロセスを使用して変更を受け入れ、trunkに適用して、通常のSubversionリリーススケジュールでリリースすることをお勧めします。
ただし、Subversion開発者コミュニティに広く受け入れられない変更を行う必要があると感じる場合や、未リリースの機能に早期アクセスを提供する必要がある場合は、以下のガイドラインに従ってください。これらは、ユーザーコミュニティでの混乱を防ぎ、配布と公式のSubversionリリースの両方を可能な限り成功させることを目的としています。
まず、ASF商標ポリシーに従っていることを確認してください。カスタムリリースによって引き起こされる可能性のある混乱を減らすために、リリースを標準のSubversionリリースと区別する必要があります。
次に、パブリックSubversionリポジトリにブランチを作成して、変更を追跡し、カスタム変更をメインラインSubversionにマージできるようにすることを検討してください。(まだお持ちでない場合は、コミットアクセスをリクエストしてください。)
第三に、カスタムリリースがメインラインSubversionには関係のないバグレポートを生成する可能性が高い場合は、カスタムリリースのユーザーと連絡を取り合って、それらのレポートを傍受およびフィルタリングできるようにしてください。しかし、もちろん、最良の選択肢は、そもそもそのような状況にないことです。カスタムリリースがメインラインSubversionから逸脱するほど、混乱を招きます。カスタムリリースを行う必要がある場合は、できるだけ一時的かつ逸脱しないようにしてください。
新しい、改良されたバージョンのAPIが導入された場合、少なくとも次のメジャーリリース(2.0.0)までは互換性のために古いAPIが残ります。ただし、古いAPIを非推奨としてマークし、新しいAPIを指し示すことで、可能な限り新しいAPIで記述するようにユーザーに知らせます。非推奨にする場合は、非推奨が導入された後のリリースについて言及し、新しいAPIを指し示します。可能であれば、古いAPIドキュメントを新しいAPIドキュメントへの差分に置き換えます。たとえば
/** * Similar to svn_repos_dump_fs3(), but with a @a feedback_stream instead of * handling feedback via the @a notify_func handler * * @since New in 1.1. * @deprecated Provided for backward compatibility with the 1.6 API. */ SVN_DEPRECATED svn_error_t * svn_repos_dump_fs2(svn_repos_t *repos, svn_stream_t *dumpstream, svn_stream_t *feedback_stream, svn_revnum_t start_rev, svn_revnum_t end_rev, svn_boolean_t incremental, svn_boolean_t use_deltas, svn_cancel_func_t cancel_func, void *cancel_baton, apr_pool_t *pool);
メジャーリリース番号が変更されると、一連の「最良の」新しいAPIは通常、以前のすべてのAPIを置き換え(その機能を引き継ぐと仮定)、元のAPIの名前を引き継ぎます。したがって、1.1.xで「svn_repos_dump_fs
」を非推奨としてマークしても、2.0.0に「svn_repos_dump_fs
」がないという意味ではなく、関数のシグネチャが異なるという意味です。つまり、1.1.xではsvn_repos_dump_fs2
(またはsvn_repos_dump_fs3
など)が保持するシグネチャになります。番号付きサフィックス名は消え、単一の(光沢のある新しい)svn_repos_dump_fs
が再び登場します。
この置換戦略に対する1つの例外は、古い関数にどうやら全く満足できない名前がある場合です。非推奨はそれを修正する機会です。新しいAPIに完全に新しい名前を付け、古いAPIを非推奨としてマークし、新しいAPIを指し示します。次に、メジャーバージョン変更時に、古いAPIを削除しますが、新しいAPIの名前は古い名前に変更しません。新しい名前で問題ないからです。
マイナーおよびメジャー番号リリースは、リリース前に安定化期間を経て、リリース後はメンテナンス(バグ修正)モードになります。リリースプロセスを開始するために、最新のtrunkに基づいて「A.B.x」ブランチを作成します。
新しいA.B.0リリースの安定化期間は通常4週間続き、保守的なバグ修正を行い、重大な問題を発見することができます。安定化期間は、バージョンA.B.0-rc1のリリース候補tarballで始まります。ブロッキングバグが修正されると、さらなるリリース候補tarballが作成される場合があります。たとえば、一連の言語バインディングが壊れていることが判明した場合、言語バインディングがテストできるように、修正されたときに新しいリリース候補を作成するのが賢明です。
A.B.xブランチが作成されたら、ソースコードの変更が直接コミットされることはありません。変更は、次のセクションで説明されているプロセスによって投票された後、trunkからA.B.xブランチにバックポートされます。
安定化期間の最終週の初めに、最後のリリース候補以降に保留中の重大な変更がある場合は、新しいリリース候補tarballを作成する必要があります。安定化期間の最終週は、重大なバグ修正のために予約されています。軽微なバグの修正は、A.B.1リリースに延期する必要があります。重大なバグとは、エッジケースではないクラッシュ、データ破損の問題、重大なセキュリティホール、または同様に深刻なものです。
状況によっては、安定化期間が延長されます。
バグを修正するために潜在的に不安定になる可能性のある変更を加える必要がある場合は、4週間の安定化期間全体が再開されます。潜在的に不安定になる可能性のある変更とは、Subversionの多くの部分に予測不可能な方法で影響を与える可能性のある変更や、大量の新しいコードを追加することを伴う変更です。互換性のないAPI変更(新しいリリースがA.0.0リリースの場合にのみ最初に許可される)は、潜在的に不安定になる可能性のある変更と見なす必要があります。
安定化期間の最終週に重大なバグ修正が行われた場合、最終週が再開されます。最終的なA.B.0リリースは、1週間前に作成されたリリース候補と常に同じです(以下で説明する例外を除きます)。
A.B.0リリースがリリースされた後、バグ修正が必要な場合は、パッチリリース(A.B.1、A.B.2など)が続きます。パッチリリースは、保守的な変更のみがラインに入力されるため、4週間の浸漬は必要ありません。
特定の種類のコミットは、浸漬期間を再開することなくA.B.0に入力したり、テストスケジュールやリリース日に影響を与えることなく、後続のリリースに入力したりすることができます。
投票なし
次のものへの変更STATUSファイルを削除することを忘れないでください。
ドキュメントの修正。
リリースのロールおよびリリースブランチの作成と保守にリストされている手順など、リリース簿記の通常の変更。
次のものへの変更dist.shリリースマネージャーによる、または承認されたもの。
次のメッセージ翻訳への変更.poファイル、または新しいファイルの追加.poファイル。
投票あり
次のみに影響するものtools/, packages/、またはbindings/.
書式文字列「%
」コードとその引数が変更されていない限り、エラーメッセージや使用メッセージなどの印刷された出力への変更。
注:メッセージ翻訳の変更に関する要件は、Cコードのテキストメッセージよりも緩いです。.poファイルのフォーマット指定子を変更することは、その有効性を機械的にチェックできるため(GNU gettextのmsgfmtの-cフラグを使用)。これは、GNU gettextが使用中の場合、ビルド時に行われます。
当然のことながら、コアコードの変更には投票が必要であり、変更が十分にテストされていない可能性があるため、浸漬期間またはテスト期間が再開されます。
A.B.xラインへの変更は、まずA.B.x/STATUSファイルで提案する必要があります。各提案は、短い識別ブロック(たとえば、trunkまたは関連ラインのコミットのリビジョン番号、または問題番号)、変更の簡単な説明、A.B.xにあるべき理由の最大1行の正当性、いくつかのメモ/懸念、および最後に投票で構成されます。メモと懸念は、読者が方向性を把握するのに役立つ簡単な要約を目的としています。実際の議論にはSTATUSファイルを使用しないでください。代わりにdev@を使用してください。
次に例を示します。おそらくエントリが最も複雑になる場合です。
* r98765 (issue #56789) Make commit editor take a closure object for future mindreading. Justification: API stability, as prep for future enhancement. Branch: 1.8.x-r98765 Notes: There was consensus on the desirability of this feature in the near future; see thread at http://... (Message-Id: blahblah). Merge with --accept=mc. Concerns: Vetoed by jerenkrantz due to privacy concerns with the implementation; see thread at http://... (Message-Id: blahblah) Votes: +1: ghudson, bliss +0: cmpilato -0: gstein -1: jerenkrantz
誰でも投票できますが、完全にコミットする人と、関係する分野の一部のコミット者のみが拘束力のある投票を行います。コミット者が拘束力のない投票(たとえば、一部のコミット者が指名された分野外の変更に投票するなど)を行う場合、次のように投票を拘束力のないと注釈を付ける必要があります。
* r31833 svndumpfilter: Don't match prefixes to partial path components. Fixes #desc4 of issue #1853. Votes: +1: danielsh, hwright +1 (non-binding): stylesen
この区別は、あらゆる種類の投票(バックポート投票、リリース投票、そして神話的なコンセンサスに達しなかったことによる投票)で行われますが、その理由は異なります。リリース投票では、この区別はリリースがASFの法的保護に入るために法的に義務付けられていますが、バックポート投票では、これは助言的な区別に近いです。結局のところ、誰かが正当な理由で変更に-1票を投じた場合、その人の認定は問題ではありません。その分析が正しければ、変更はバックポートされません。同様に、変更が必要な数の拘束力のある+1票を受けられなかったとしても、拘束力のない+1票がいくつかあれば、承認されるのに役立つ可能性があります。
言い換えれば、バックポートプロセスの目的は、不安定化を引き起こす変更がパッチリリースに入るのを防ぐことです。投票は、各変更に一定量のレビューを受けさせることで、その目的に役立ちます。カルマは譲渡できないため、「レビュー量」は拘束力のある投票数で測定しますが、これまでと同様に、誰もがプロセスに意見を述べ、耳を傾けてもらうことができます。
変更に対する投票者の意見は、+1、-1、+0、または-0としてエンコードされます。
「拒否権」を定義するか、定義を参照してください
拒否権(つまり、-1)を行使する場合は、懸念事項フィールドに理由を述べ、リストでの議論があれば、URL/メッセージIDを含めてください。スレッドがコミット時に利用できない場合は、後でリンクを追加できます。
-0票は、変更にやや反対であることを意味します。dev@で理由を述べるか、括弧内に要約してください。ただし、コンセンサスの妨げにはなりません。
変更に+1票を投じることは、原則としてそれを承認することを意味するだけではありません。それは、変更を徹底的にレビューし、それが正しく、可能な限り非破壊的であると判断したことを意味します。リリースブランチにコミットされると、ログメッセージには、元の作成者とコミットを行った人に加えて、賛成票を投じたすべての人の名前が含まれます。これらの人々はすべて、バグに対して同等に責任があると見なされます。コミッターは、自分が知らないことを知り、軽率に+1票を投じないことが信頼されています。
パッチをレビューして気に入ったが、いくつかの懸念事項がある場合は、「+1(概念)」と書いて、懸念事項についてリストで質問できます。一般的な考えは気に入っているが、パッチを注意深くレビューしていない場合は、「+0」と書くことができます。これらの投票は合計にはカウントされませんが、変更を追跡していて、さらに時間を費やす意思がある人を特定するのに役立つ可能性があります。
非LTS(「通常」)リリースラインの場合、変更は2つの+1と拒否権なしを受け取ると承認されます。(拘束力のある投票のみがカウントされます。上記を参照。)
LTSリリースラインの場合、変更は3つの+1と拒否権なしを受け取ると承認されます。(拘束力のある投票のみがカウントされます。上記を参照。)
上記にかかわらず、任意のリリースラインについて、コアコードではない領域(たとえば、tools/、packages/、bindings/、テストスクリプトなど)のみに影響し、ビルドシステムに影響を与えない変更は、その領域のフルコミッターまたは部分コミッターからの1つの+1、少なくとも他のコミッターからの1つの+0または「コンセプト+1」、および拒否権なしで承認されます。
目標は、すべてのレビュー担当者が領域メンテナーと同じ量の専門知識を持っていることを要求せずに、変更を少なくとも2組の目で確認することです。これにより、「はい、これらの変更を細部まで理解しており、テストしました」と主張することを強制されることなく、一般的な正気、正確なコメント、明らかなミスなどをレビューできます。
変更を提案する前にSTATUS、マージ競合が発生しないことを確認するために、ブランチにマージしてみてください。競合が発生した場合は、変更をマージして競合を解決したリリースブランチから新しい一時ブランチを作成してください。ブランチの名前はA.B.x-rYYYYである必要があります。ここで、YYYYはSTATUSファイルでの変更の最初のリビジョンです。のSTATUSファイルに、一時ブランチの存在に関するメモをBranch: A.B.x-rYYYYまたはBranch: ^/subversion/branches/A.B.x-rYYYYヘッダーの形式で追加します(この正確な形式を使用します。スクリプトが解析します)。変更にさらなる作業が必要な場合は、これらのリビジョンをブランチにマージできます。この変更のエントリがから削除されたらSTATUS、/branchesディレクトリが乱雑にならないように、この一時ブランチも削除する必要があります。
一時ブランチは、トランクからの変更のバックポートではない変更をA.B.xブランチに加える必要があるまれな場合にも使用されます。
別のノミネーションがマージされるまでマージ競合を引き起こすエントリをノミネートする場合は、ノミネートにそれを記述してください。エントリに「Depends:」ヘッダーを記述します。これにより、1時間ごとの「マージ競合のあるノミネーションを検出する」ビルドボットジョブがグリーンになります。(「Depends:」ヘッダーの値は解析されません。)
tools/dist/nominate.plスクリプト(トランク内)は、新しいノミネーションを追加するプロセスを自動化します。同じスクリプトには、ノミネーションのレビューと投票を行うのに役立つREPLループもあります。tools/dist/README.backport(トランク内)を参照してください。
注:STATUS一時ブランチに関する変更(投票を含む)は、常にメインリリースブランチに保持されます。
実際のリリース前に、翻訳者にメールを送信して.poファイルの更新をリクエストしてください。メールアドレスは、COMMITTERSファイル(トランク内)から、次のようなコマンドを使用して取得してください
sed -e '/^ *Translat.*:$/,/:$/!d' -e 's/^ *[^ ]* *\([^>]*>\).*/\1/;t;d' COMMITTERS
によって生成された翻訳ステータスレポートを含めてください
./tools/po/l10n-report.py
これは、すべてのローカライズされた文字列がリリース用の最終形式で安定した後、翻訳者が作業を行うのに十分な時間があるように、実際のリリースに先立って行う必要があります。目安として、リリース予定日の少なくとも1週間前、できればそれ以上前に通知を送信してください。新しいブランチからの最初のリリースの場合のように、多くの文字列が変更されている場合は、さらに時間を置いてください。
したがって、リリースブランチが安定し、リリースをロールするための準備をしています。ローリングプロセスの詳細は、release.pyヘルパースクリプトによって自動化されます。このスクリプトを実行するには、Subversionトランクのワーキングコピーが必要です。実行release.py -hして、利用可能なサブコマンドのリストを取得します。
実際にアーカイブをロールする前に、ホワイトルームローリング環境をセットアップする必要があります。この環境には、一部のビルドツールのプリスティンバージョンが含まれている必要があります。
このソフトウェアの配布版は、移植性のない方法でパッチが適用されていることが多いため(例:Debianのlibtoolパッチ:#291641、#320698)、使用しないことが重要です。tools/dist/release-lines.yamlに記載されているバージョン番号は、通常、A.B.0リリースまでの期間に、最新の安定したアップストリームリリースになるように再検討して増やす必要があります。A.B.xシリーズ内のバージョンを変更する場合は、慎重に検討する必要があります。
Autoconf、Libtool、SWIG:Subversion RMの職務のための特別なビルドツールを格納するディレクトリを選択します。たとえば/opt/svnrmです。ソフトウェアの3つの部分を構成、ビルド、インストールします。次のコマンドを使用しますrelease.py build-envコマンド。
mkdir -p /opt/svnrm && cd /opt/svnrm && $SVN_SRC_DIR/tools/dist/release.py build-env X.Y.Z
ローリングスクリプトには、次のコマンドも利用可能である必要がありますpax, xgettext, m4、およびpython -c 'import yaml'.
これらをOSパッケージからインストールします。(Debianシステムでは、それはapt install pax gettext m4 python-yaml subversion.)
リリースをロールする ¶:
get-deps.shがリリースブランチで動作することを確認してください。
./release.py roll X.Y.Z 1234tarballを作成する:実行release.pyが完了すると、/opt/svnrm/deploy
ディレクトリ内にtarballが作成されます。
a) tar zxvf subversion-X.Y.Z.tar.gz; cd subversion-X.Y.Z b) ./configure See INSTALL, section III.B for detailed instructions on configuring/building Subversion. If you installed Apache in some place other than the default, as mentioned above, you will need to use the same --prefix=/usr/local/apache2 option as used to configure Apache. You may also want to use --enable-mod-activation, which will automatically enable the required Subversion modules in the Apache config file. c) make d) make check e) make install (this activates mod_dav) f) make davcheck For this, start up Apache after having configured according to the directions in subversion/tests/cmdline/README. Make sure, that if you maintain a development installation of apache, that you check the config file and update it for the new release area where you're testing the tar-ball. (Unless you rename the tree which gets extracted from the tarball to match what's in httpd.conf, you will need to edit httpd.conf) g) make svncheck First, start up svnserve with these args: $ subversion/svnserve/svnserve -d -r \ `pwd`/subversion/tests/cmdline -d tells svnserve to run as a daemon -r tells svnserve to use the following directory as the logical file system root directory. After svnserve is running as a daemon 'make svncheck' should run h) Then test that you can check out the Subversion repository with this environment: subversion/svn/svn co https://svn.apache.org/repos/asf/subversion/trunk i) Verify that the perl, python, and ruby swig bindings at least compile. If you can't do this, then have another developer verify. (see bindings/swig/INSTALL for details) Ensure that ./configure detected a suitable version of swig, perl, python, and ruby. Then: make swig-py make check-swig-py sudo make install-swig-py make swig-pl make check-swig-pl sudo make install-swig-pl make swig-rb make check-swig-rb sudo make install-swig-rb j) Verify that the javahl bindings at least compile. If you can't do this, then have another developer verify. (see subversion/bindings/javahl/README for details) Ensure that ./configure detected a suitable jdk, and then possibly re-run with '--enable-javahl', '--with-jdk=' and '--with-junit=': make javahl sudo make install-javahl make check-javahl k) Verify that the ctypes python bindings at least compile. If you can't do this then have another developer verify. (see subversion/bindings/ctypes-python/README for details) Ensure that ./configure detected a suitable ctypesgen, and then possibly re-run with '--with-ctypesgen': make ctypes-python sudo make install-ctypes-python make check-ctypes-python l) Verify that get-deps.sh works and does not emit any errors. ./get-deps.sh
tarballの1つまたは両方をテストする
GnuPGを使用してリリースに署名するrelease.py sign-candidates X.Y.Zrelease.pyを使用してリリースに署名する
gpg -ba subversion-X.Y.Z.tar.bz2 gpg -ba subversion-X.Y.Z.tar.gz gpg -ba subversion-X.Y.Z.zipこれにより、次のコマンドと同等のコマンドが実行されます
対応する.ascファイルにgpg署名が追加されます。
Subversion操作最終リリースを反映するsvn_version.h
release.py create-tag X.Y.Z 1234
でタグを作成します。これは次を使用して行います
注:リリース候補の場合でも、必ずタグを作成してください。create-tagSTATUSと最終リリースを反映するは、元のブランチの
ファイルのバージョン番号を上げます。1.0.2を行ったばかりの場合、両方のファイルに1.0.3の適切な値が含まれている必要があります。
release.py post-candidates 1.7.0
tarball、署名、およびチェックサムをhttps://dist.apache.org/repos/dist/dev/subversionにコミットします。この手順を自動化するrelease.pyサブコマンドがあります
候補をテストおよび署名に利用できることを発表する
Subject: Subversion X.Y.Z up for testing/signing The X.Y.Z release artifacts are now available for testing/signing. Please get the tarballs from https://dist.apache.org/repos/dist/dev/subversion and add your signatures there. Thanks!
このようなメールをdev@リストに送信してください
#svn-devのトピックを「X.Y.Zはテスト/署名のために利用可能です」と記述するように調整します。
リリースに署名する理由 ¶
Subversionリリースは、グローバルなコンテンツ配信ネットワーク(CDN)を介して配布されます。(これは、2021年後半に以前のASFミラーネットワークに取って代わりました。それでも、ASFリリースをミラーリングし続けることを選択する他の組織が存在する可能性があります。)
Subversionのリリースが正式に公開されるには、以下が必要です。
初期のtarballを作成する際、リリース管理者は最初の署名セットも作成します。tarball自体はpeople.apache.orgでビルドされる可能性がありますが、署名がそこで生成されないことが重要です。tarballへの署名には秘密鍵が必要であり、ASFハードウェアへの秘密鍵の保存は強く推奨されません。tarballに署名した後(以下の手順を使用)、リリース管理者は署名を予備の配布場所にアップロードし、tarballと同じディレクトリに配置する必要があります。
PMCのメンバーだけでなく、熱心なコミュニティメンバーも、予備の配布場所からtarballをダウンロードし、テストを実行して、署名を提供することが推奨されます。これらの署名の公開鍵は、id.apache.orgを通じてASF LDAPインスタンスに含まれている必要があります。(SubversionコミッターとPMCメンバーの現在の公開鍵のリストは、毎日LDAPから自動生成されます。)リリース管理者は、リリースを発表する前に、少なくとも5日間署名を待つことが推奨されます。これにより、バージョンをテストする誰もが、発表前にリリースの署名を完了できます。
tarballに署名するということは、それについて特定のことを主張することです。署名を発表する際には、tarballが正しいことを検証するために行った手順をメールに記載してください。たとえば、リポジトリ内の適切なタグに対してコンテンツを検証するなどです。以下を実行することも良い考えです。make checkすべてのRAレイヤーとFSバックエンドに対して、バインディングをビルドしてテストすることも良いでしょう。
リリース候補を入手するには、https://dist.apache.org/repos/dist/dev/subversionの作業コピーをチェックアウトします。tarballに対するリリース管理者のPGP署名を検証します。release.pyはこの手順を自動化します。
release.py get-keys release.py --target /path/to/dist/dev/subversion/wc check-sigs 1.7.0-rc4
tarballを検証、抽出、テストした後、gpgを使用して、armor化された分離署名を作成して署名する必要があります。.ascファイルに署名を追加するには、次のようなコマンドを使用します。
gpg -ba -o - subversion-1.7.0-rc4.tar.bz2 >> subversion-1.7.0-rc4.tar.bz2.ascrelease.pyスクリプトはこの手順を自動化できます。
release.py --target /path/to/dist/dev/subversion/wc sign-candidates 1.7.0-rc4
署名を追加した後、ローカルで変更した.ascファイルをdist.apache.orgリポジトリにコミットします。
ダウンロードしてテストした.tar.bz2ファイルがある場合、.tar.gzファイルを個別にダウンロードしてテストしなくても、同じ内容で署名することが可能です。そのための秘訣は、.bz2ファイルを展開し、gzipを使用して次のようにパックすることです。
bzip2 -cd subversion-1.7.0-rc4.tar.bz2 \ | gzip -9n > subversion-1.7.0-rc4.tar.gz
結果のファイルは、リリース管理者によって生成されたファイルと同一である必要があり、したがって上記のように署名できます。ファイルが同一であることを確認するには、チェックサムまたはリリース管理者の署名のいずれかを使用できます。これらは両方ともtarballとともに提供する必要があります。
ただし、チェックサムが同一でない場合、ファイル署名が間違っている、またはファイルが改ざんされたというわけではありません。リリース管理者と同一のgzipバージョンを持っていない可能性も十分にあります。
tarballが作成され、すべての署名が作成および検証された後、リリースは公開の準備が整います。このセクションでは、Subversionリリースを公開するために必要な手順の概要を説明します。
Subversionアーティファクトは、グローバルなコンテンツ配信ネットワーク(CDN)を通じて配布されます。ソースコードのダウンロードページは、適切なダウンロードリンクを選択するのをユーザーが自動的に支援します。通常、プロジェクトの配布ディレクトリには、サポートされているリリースラインの最新の安定版リリースのみをホストします。一方、以前のすべてのSubversionリリースは、アーカイブで入手できます。
リリースをCDNにアップロードするには
release.py move-to-dist 1.7.0これにより、tarball、署名、およびチェックサムが^/dev/subversionから^/release/subversionに移動します。コンテンツ配信ネットワーク(CDN)が新しいリリースを取得するのに約15分かかります。アーカイブも自動的にリリースを取得します。以下を実行してもmove-to-dist署名ファイルが移動しますが、コミッターは依然として^/release/subversionに新しい署名をコミットできます。ただし、それらの署名がCDNに表示されるまでに最大15分かかります。15分が経過してコミットされてから15分が経過していない限り、そのような署名をリリース発表に含めることはできません。
この時点で、リリースは一般公開されている可能性がありますが、CDNが取得するまで発表を控えることをお勧めします。15分の期間が経過し、CDNが同期するのに十分な時間が経過した後、リリース管理者は発表を送信し、以下で説明するようにSubversion Webサイトへの変更を公開します。
また、次の場所から古いリリースを整理するのに良いタイミングです。^/release/subversion; サポートされている各リリースラインの最新リリースのみがそのディレクトリにある必要があります。少なくとも24時間^/release/subversionで利用可能だったリリースは、引き続きアーカイブで利用可能です。以下のコマンドを使用すると、古いリリースを整理できます。
release.py clean-dist
reporter.apache.orgで新しいリリースのバージョン番号を送信します。次のコマンド
curl -u USERNAME "https://reporter.apache.org/addrelease.py?date=`date +%s`&committee=subversion&version=VERSION&xdate=`date +%F`"はリリースを追加します。おそらくrelease.pyに追加する必要があります。
以下の手順では公開されたWebサイトを直接更新することを示していますが、次の場所で変更を準備することができます。^/subversion/site/stagingその場合
からキャッチアップマージを実行します。^/subversion/site/publish.
への変更をコミットします。^/subversion/site/stagingおよびhttps://subversion-staging.apache.orgで結果を確認します。
公開する準備ができたら、変更を^/subversion/site/publishにマージバックします(マージの準備ができていないステージングに対する他の変更がある場合に備えて、マージを確認します)。
プレリリース(アルファ/ベータ/rc)を含むすべてのリリースについて
編集^/subversion/site/publish/download.html最新のリリースを記載します。使用release.py write-downloads表を生成します。これが安定版リリースである場合は、以下を更新します。[version]または[supported]eztマクロ定義(例:[define version]1.7.0[end]); これがプレリリースである場合は、<div id="pre-releases">; これはプレリリースを廃止する1.x.0リリースである場合は、コメントアウトします。
新しいニュース項目を^/subversion/site/publish/news.htmlリリースを発表します。同じ項目を^/subversion/site/publish/index.htmlのニュースリストにも追加し、そのページから最も古いニュース項目を削除します。使用release.py write-newsカスタマイズする必要があるテンプレートニュース項目を生成します。ニュース項目には、発表メールへのリンクを含める必要があるセクションがあります。今のところコメントアウトされており、リンクは後で追加されます。リリース日より前にテンプレートを生成した場合は、日付が正しいことを確認してください。
また、これが安定版リリースX.Y.Z(アルファ/ベータ/rcではない)である場合
次の場所に新しいリリースを一覧表示します。^/subversion/site/publish/doap.rdf
サポートされている各マイナーリリースに対して、<created>と<revision>が現在のリリース日とパッチリリース番号に更新された<release>セクションが必要です。ファイル内の他のものは変更しないでください(特に、<Project>の下の<created>は、Subversionプロジェクトが作成された日付です)。
次の場所に新しいリリースを一覧表示します。^/subversion/site/publish/docs/release-notes/release-history.html
さらに、これが新しいマイナーリリースX.Y.0である場合
^/subversion/site/publish/docs/release-notes/index.htmlの「サポートされているバージョン」セクションで、コミュニティのリリースサポートレベルを更新します。
更新supported_release_linesをrelease.pyで更新し、必要に応じて古い行を削除します。
次の場所から「ドラフト」警告を削除します。^/subversion/site/publish/docs/release-notes/X.Y.html
次の場所にバージョン付きドキュメントスナップショットを作成または更新します。^/site/publish/docs/api/X.Yと^/site/publish/docs/javahl/X.Y、およびこれらのディレクトリの兄弟である「latest」シンボリックリンクが常に最新のリリースシリーズのディレクトリを指していることを確認してください。
例
VER=1.12 DOCS_WC=~/src/svn/site/staging/docs TAG_BUILD_DIR=~/src/svn/tags/$VER.x/obj-dir cd $TAG_BUILD_DIR make doc cp -a doc/doxygen/html $DOCS_WC/api/$VER cp -a doc/javadoc $DOCS_WC/javahl/$VER for D in $DOCS_WC/api $DOCS_WC/javahl; do svn add $D/$VER rm $D/latest && ln -s $VER $D/latest done svn ci -m "In 'staging': Add $VER API docs." $DOCS_WC/api $DOCS_WC/javahl
インデックスページのAPIドキュメントへのリンクを更新しますdocs/index.html#api。
リリース日に「publish」への変更をコミットします(または「staging」から「publish」に変更をマージします)。
新しいマイナーリリース(1.x.0と番号付け)には、プレスリリースが付属する場合があります。プレスリリースのすべての詳細は、private@リストで、press@a.oと連携して処理されます。
大まかなルールとして、浸透の開始時にprivate@ / press@でスレッドを開始します。press@に短すぎる警告を与えるよりも、長すぎる警告を与える方が良いです。
過去のものを参考にして、リリース発表を記述します。発表にはURLとチェックサムを含めることを忘れないでください!release.py write-announcementサブコマンドは、特定の状況に合わせてカスタマイズできるテンプレート発表を作成します。リリースがセキュリティ問題を修正する場合は、--securityフラグを渡して、出力に正しい件名、Cc、および説明を生成します。
このリリースでコミュニティのサポートレベルが変更される場合は、発表を生成するために使用する前に、release.pyのrecommended_release変数を必ず更新してください。
@apache.orgメールアドレスから発表を送信します。(announce@へのメールは、他のアドレスから送信された場合、バウンスされます。最良の結果を得るには、コミッターメールページの説明に従い、公式メールリレー経由でメッセージを送信してください。)メールクライアントがURLを複数行に折り返さないようにしてください。
注:リリース発表のリンクが有効であることを確認するために、リリースを発表する前にWebサイトを更新します。リリースを発表した後、リリース発表メールへのリンクがWebサイトに追加されます。
リリース発表が投稿されるannounce@メーリングリストは2つあります。Subversionプロジェクトのannounce@subversion.apache.orgリストと、ASF全体のannounce@apache.orgリストです。ASF全体のannounce@リストへのメッセージが拒否される可能性があります。これにより、次のような件名行のモデレーション通知が生成されます。announce@apache.orgの返送。メーリングリストソフトウェアにメッセージを拒否するように指示したモデレーターは、拒否メッセージに自分の名前を署名することを怠る可能性があり、拒否は匿名になり、拒否の根拠が無効になる可能性があります。いずれにせよ、落ち着いて拒否をdev@メーリングリストに転送して、プロジェクトがそれについて何かする必要があるかどうかを議論できるようにしてください。(必要に応じて、announce@メーリングリストのモデレーターには、announce-owner@ハンドルを介して連絡できます。)
次のようなさまざまなSubversion関連のIRCチャネルのトピックを更新します。#svnと#svn-devlibera.chatで。
これがX.Y.0リリースである場合は、サポートステータスが変更されたブランチのSTATUSファイルの一番上にあるコミュニティサポートレベルを更新します。これは通常X.Y.x/STATUS, X.$((Y-1)).x/STATUSそして、新しいリリースがLTSリリースである場合、サポートされている最も古いLTSブランチのSTATUSファイルも同様です。
更新^/subversion/site/publish/news.htmlと^/subversion/site/publish/index.htmlリリース告知メールへのリンクをアンコメントして追加します。
これで、リリース管理者は$favorite_beverageを堪能する時間です。
新しいリリースブランチは、新しいメジャーリリースおよびマイナーリリースごとに作成されます。したがって、たとえば、バージョン2.0.0またはバージョン1.3.0をリリースする準備をするときに、新しいリリースブランチが作成されます。ただし、1.3.1(パッチバージョンのインクリメント)をリリースする準備をするときは、1.3.0の時点で作成されたリリースブランチが使用されます。
パッチリリースを準備している場合、作成するリリースブランチはありません。現在のマイナーバージョンシリーズのリリースブランチで中断したところから再開するだけです。
新しいリリースブランチを作成する必要があるタイミングは、せいぜい曖昧です。一般的に、新しいマイナーバージョンを6か月ごとにリリースするという緩やかなスケジュールがあります。したがって、前のマイナーリリースから約4か月後が、ブランチを提案するのに良い時期です。ただし、これは開発中の機能によって柔軟に変更されることを忘れないでください。
ロードマップを確認してください。ブランチングの前に、未解決の項目に対処する必要がありますか?
現行の安定ブランチのSTATUSファイルで、未解決の-0および-1の投票を確認してください。新しいブランチに含める予定のコードに反対はありましたか?(たとえそうであっても、ブランチングを妨げるべきではありませんが、リリースブランチをロールする前に問題を解決するために議論を開始する必要があります。)
ツリー全体の機械的な変更を行います。(機械的でない変更は、レビューのために以前に行われている必要があります。)これにより、後でマージが容易になります。例には、末尾の空白の削除、エラーリークの修正、Cヘッダーのインバリアントの修正(別のケース)、コードの検索と置換などがあります。(これは、静的解析などの定期的なハウスキーピングタスクを行うのにも良いタイミングです。)
新しいAPIと変更されたAPIを、設計とスタイル(Doxygenマークアップ、ドキュメント化されていないパラメーター、非推奨、公開/非公開ステータスなど)について確認します。
abi-laboratory.pro Subversionが役立つ場合があります。
現行のマイナーリリースに対する互換性テストを実行します。
新しいリリースブランチを作成することに人々が同意したら、リリース管理者は次のいずれかの手順で作成します(A.Bを、準備しているバージョン(例:1.3、または2.0)に置き換えてください)。
リリースブランチを作成するためのほとんどの作業は、tools/dist/release.pyによって自動化できます。
一時的なチェックアウトを行う、空のディレクトリでこれを実行します。
release.py --verbose create-release-branch A.B.0
以前に実行していない場合は、プロジェクトWebサイトのリリースノートテンプレートを作成します。
release.py --verbose write-release-notes A.B.0 > .../docs/release-notes/A.B.html svn add .../docs/release-notes/A.B.html svn ci -m "Add release notes template." .../docs/release-notes/A.B.html
このセクションのほとんどのステップは、tools/dist/release.pyによって自動化できます(上記を参照)が、リリース管理者が手動で実行する場合に備えて、ここに文書化されています。
サーバー側のコピーで新しいリリースブランチを作成します。
svn cp ^/subversion/trunk \ ^/subversion/branches/A.B.x \ -m "Create the A.B.x release branch."
編集subversion/include/svn_version.hトランクで、そこのバージョン番号を増やします。これらの変更をまだコミットしないでください。
トランクのバージョン番号は、作成したばかりのブランチのすぐ後に続くメジャー/マイナーバージョンを常に反映します(例:2.0.xブランチの場合は2.1.0、1.3.xブランチの場合は1.4.0)。
編集subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.javaトランクでインクリメントしますSVN_VER_MINORこれらの変更をまだコミットしないでください。
編集subversion/tests/cmdline/svntest/main.pyトランクでインクリメントしますSVN_VER_MINORこれらの変更をまだコミットしないでください。
編集トランクからのトランクで、今後のリリース用に新しいセクションを追加します。まだ存在しない場合は、将来作成される次のマイナーリリース用の新しいセクションも追加します。各セクションは次から始まります。
Version A.B.0 (?? ??? 20XX, from /branches/A.B.x) https://svn.apache.org/repos/asf/subversion/tags/A.B.0
リリース日は今のところ空白のままにします。ロールするまでこの状態のままになります。
次のようなログメッセージでこれらの変更をコミットします。
Increment the trunk version number to A.$((B+1)), and introduce a new CHANGES section, following the creation of the A.B.x release branch. * subversion/include/svn_version.h, subversion/bindings/javahl/src/org/apache/subversion/javahl/NativeResources.java, subversion/tests/cmdline/svntest/main.py (SVN_VER_MINOR): Increment to $((B+1)). * CHANGES: New section for A.$((B+1)).0.
新しいSTATUSリリースブランチ上のファイルを作成します。
すべてのbuildbotビルダーが新しいリリースブランチをビルドしていることを確認します。
https://svn.apache.org/repos/infra/infrastructure/buildbot/aegis/buildmaster/master1/projects/subversion.confのMINOR_LINESリストにA.Bを追加します。
テンプレートのリリースノートドキュメントを作成します。site/publish/docs/release-notes/A.B.html
適切なアクセス権を持つ人に、A.B.xブランチをバックポートマージボットに追加するように依頼します。
リリースが通常かLTSかを決定し、その決定をlts_release_linesのtools/dist/release-lines.yamlrelease.pyに記録します。
バックポートマージボットは、svn-qavm1マシンで、svnsvnローカルユーザーアカウントで、svn-roleSubversionアカウント名を使用してコミットを行います。
現在、この構成では、マシンの管理者アクセス権を持つ人が、ブランチセットの変更を管理する必要があります。
ボットは、WCディレクトリが次の場所にある各ブランチA.B.xで承認されたバックポートをマージします。~svnsvn/src/svn/A.B.x .
そこのチェックアウトは、(たとえば、sudoで)次のように実行することで作成されました。svnsvnユーザーとして、
svn checkout --depth=empty https://svn-master.apache.org/repos/asf/subversion/branches ~svnsvn/src/svn svn up ~svnsvn/src/svn/A.B.x # for each supported branch
リポジトリURLはsvn-master.a.oバックポートマージャーがsvn ci && svn upループで実行し、svn upは、コミットしたリビジョンに更新されると想定しているためです。これは、ミラーから更新する場合(および保証されていません)svn.a.oがミラーを指している可能性があります)。buildbotスレーブも、同じ理由でこれを行います。
各ブランチは、WCルートのサブディレクトリにあります。新しいブランチを追加するには、ソースツリーに次のものを入力します。svn up:
sudo -H -u svnsvn svn up ~svnsvn/src/svn/A.B.x
サポートされなくなったブランチを削除するには、svn up -r0:
sudo -H -u svnsvn svn up -r0 ~svnsvn/src/svn/Z.Z.x
設定に関するその他の注意事項は、machines/svn-qavm1/およびSubversion PMCのプライベートリポジトリにあります。また、過去の化身に関する歴史的な注意事項は、machines/.
リリースブランチが作成されると、そこで開発が行われることは決してありません。許可されている変更は、次のようなさまざまな簿記ファイルに対して行われたものだけです。STATUS、およびトランクからマージされた変更です。まれに、リリースブランチ固有の問題に対処するために、A.B.xブランチからフィーチャーブランチが作成される場合があります(たとえば、トランクには影響しないバグを修正する場合)。
トランクからの変更のマージを承認または拒否するために使用されるプロトコルは、すべてのSubversion開発者にとって興味深いものであり、リリース安定化セクションで文書化されています。
はトランクからのファイルは、プロジェクトの変更ログファイルです。リリース前に、最後のリリース以降のすべての変更をリストするために、最新の状態にする必要があります。
以下に、手動プロセスについて説明します。部分的な自動化については、次を参照してください。
release.py write-changelog
パッチリリースの場合、これは非常に簡単です。最後の「ゴールデン」リビジョン以降のブランチのコミットログを調べ、興味深いすべてのマージをメモするだけです。マイナーリリースとメジャーリリースの場合、これはより複雑です。最後のリリースブランチがフォークされてからのトランクのコミットログをたどり、そこにあるすべての変更をメモする必要があります。手順は同じですが、はるかに長く、以前のリリースブランチにすでにバックポートされ、そこからリリースされている変更セットをフィルタリングする必要があるため、やや複雑になります。
はトランクからのは、常にトランクで編集してから、必要に応じてリリースブランチにマージする必要があることに注意してください。すべてのリリースのすべての変更が、今後の参照のために、トランクのトランクからのファイルに文書化されていること、および将来のリリースブランチに以前のすべての変更ログの合計が含まれていることが非常に重要です。
各変更の箇条書きを簡潔に、できれば1行以下にしてください。これは難しい場合がありますが、ドキュメント全体の読みやすさが向上します。自問自答してみてください。説明に複数行必要な場合、詳細になりすぎていませんか?
実行しますsvn log --stop-on-copy ^/subversion/branches/A.B.xこれは、A.B.xブランチへのバックポートを含め、A.B.xラインに対して行われたすべての変更を提供します。次に、以前のメジャー/マイナーブランチのマイクロリリースですでにリリースされている変更のログを削除する必要があります。実行しますsvn log -q --stop-on-copy以前のリリースブランチで、リビジョン番号を解析してメインのログ出力から削除するスクリプトを作成します。(カールとベンは以前、emacsマクロを使用してそれを行っていましたが、より一般的なスクリプトを作成することを提案しています。)(更新:最近では、svn mergeinfo --show-revs eligible関連するリビジョンのセットを取得することが簡単になるはずです。マイナーブランチをソースとして使用し、以前のマイナーブランチをターゲットとして使用します。)
古いものから新しいものへ、ログを読み、ポイントを要約していきます。重要なのは、記述する詳細レベルを知ることです。すべての小さなコミットについて言及する必要はありませんが、あまり一般的になりすぎることも避ける必要があります。新しいセクションを開始する前に、トランクからのファイルの数ページを読み、フィルターレベルを設定して、一貫性を保ちます。
リリース安定化の一部として、トランクからのは、バグ修正がリリースブランチに移植されたときに更新する必要があります。一般的に、リビジョンまたはリビジョンのグループ(つまり、STATUSの項目)をリリースブランチにマージする場合は、上記の同じガイドラインに従って、トランクのトランクからのにも項目を追加する必要があります。次に、このリストはパッチリリースが行われるときにリリースブランチにマージされます。
実際には、修正がリリースブランチにバックポートされるたびに、CHANGESは更新されません。通常、リリース管理者は、パッチリリースを行うための最初のステップの1つとしてCHANGESを更新します。
CHANGESに記載する必要があるバックポートのリストを取得する便利な方法は、Subversion Webサイトの次のパッチリリースで登場を生成するのと同じツールを使用することです。これは、upcoming.pyにあるhttps://svn.apache.org/repos/asf/subversion/site/toolsのスクリプトです。現在の作業ディレクトリがマイナーブランチの作業コピーのルートである間に実行します。
翻訳は2つの領域に分けられています。1つ目は、接続しているクライアントに送信されるサーバーメッセージの翻訳です。この問題は、今のところ先送りにされています。2つ目は、クライアントとそのライブラリの翻訳です。
gettext パッケージは、メッセージを翻訳するためのサービスを提供します。これは、xgettext ツールを使用して、翻訳のためにソースから文字列を抽出します。これは、_()、N_()、および Q_() マクロの引数を抽出することで機能します。_() は、関数呼び出しが許可されているコンテキスト (通常は静的初期化子を除くすべて) で使用されます。N_() は、_() が使用できない場合に使用されます。N_() でマークされた文字列は、コード内で参照されるたびに gettext 翻訳ルーチンに渡す必要があります。例として、subversion/svn/help-cmd.c でヘッダーとフッターがどのように処理されるかを見てください。Q_() は、単数形と複数形を持つメッセージに使用されます。
_()、N_()、および Q_() マクロに加えて、U_() も、翻訳されない文字列をマークするために使用されます。これは、内部エラーメッセージを翻訳しても一般的に役に立たないためです。これは、ほとんどのユーザーが絶対に見るべきではない、あいまいなエラーメッセージ (Subversion のバグまたは非常に特殊なリポジトリの破損によって引き起こされる) にのみ影響を与えるはずです。U_() を使用する理由は、gettext 呼び出しが単に忘れられたのではないことを明示的に示すためです。
gettext ルーチン (*gettext または *dgettext) を直接呼び出す場合は、Subversion コードのほとんどがライブラリコードであることを念頭に置いてください。したがって、デフォルトのドメインは必ずしも Subversion 独自のドメインではありません。ライブラリコードでは、gettext 関数の dgettext バージョンを使用する必要があります。ドメイン名は、PACKAGE_NAME の定義で定義されています。
ローカライゼーションに必要なすべての設定は、svn_private_config.h (*nix の場合) および svn_private_config.hw (Windows の場合) の ENABLE_NLS 条件によって制御されます。
#include "svn_private_config.h"
ローカライゼーションが必要なファイルでは、最後のインクルードとして必ず以下を追加してください。
また、_()、Q_() および *gettext() 呼び出しの戻り値は UTF-8 エンコードされていることに注意してください。これは、プログラム出力として書き込まれる現在のロケールに翻訳する必要があることを意味します。
GNU gettext マニュアル (https://www.gnu.org/software/gettext/manual/html_node/gettext_toc.html) は、「プログラムソースの準備」セクションで、翻訳可能なプログラムの作成に関する追加情報を提供します。そのヒントは主に文字列の構成に適用されます。
現在利用可能な翻訳は、リポジトリの po セクションにあります。まだ利用できない翻訳を開始したい場合は、dev@subversion.apache.org にお問い合わせください。翻訳に関する議論は、そのリストで行われます。
Makefile のビルドターゲット locale-gnu-* (po ファイルの管理に使用) には、GNU gettext 0.13 以降が必要です。これは、*.po ファイルを *.mo ファイルにコンパイルしたい人にとっての要件ではないことに注意してください。
新しい翻訳を開始する前に、Subversion 開発メーリングリストに連絡して、重複した作業にならないようにしてください。また、このプロジェクトでは、複数の人がメンテナンスしている翻訳を強く推奨していることに注意してください。あなたの意図をリストにメールで送信することで、サポーターを見つけるのに役立つかもしれません。
その後、次の手順を実行する必要があります。
./autogen.sh
を実行します。./configure
を実行します。make locale-gnu-pot
を実行します。subversion/po
ディレクトリで、msginit --locale LOCALE -o LOCALE.po
を実行します。LOCALE は、ロケールを識別するために使用される ll[_LL] 言語および国コードです。手順 (2) と (3) で Makefile が生成され、手順 (4) で subversion/po/subversion.pot
が生成されます。
Subversion プロジェクトには、ファイルに名前を入れないというポリシーがあるため、以下に説明する2つの変更を適用してください。
新しく生成された .po ファイルのヘッダーは次のようになります。
# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
そのブロックを次のテキストに置き換えてください。
# <Your language> translation for subversion package # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # https://apache.dokyumento.jp/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License.
.po ファイルの最初の翻訳ブロックには、次のような 2 行が含まれています。
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
それらを次の 2 行に置き換えてください。
"Last-Translator: Subversion Developers <dev@subversion.apache.org>\n" "Language-Team: YOUR LANGUAGE <dev@subversion.apache.org>\n"
ドキュメント化予定
issue #1977 を参照してください。
メーリングリストに送信したり、リポジトリにコミットしたりする前に、po ファイルが「コンパイル」されていることを確認してください。これは、次の手順で (Makefile ベースのシステムで) 実行できます。
./autogen.sh
を実行します。./configure
を (適切な引数を付けて) 実行します。make locale
を実行します。autogen.sh ステップは重要です。これにより、新しい po ファイルが 'locale' ビルドターゲットの依存関係として追加されるためです。ただし、手順 1 と 2 は、新しい翻訳を追加した後に一度だけ必要になることに注意してください。
大きな po ファイルをメーリングリストにメールで送信しないでください。dev@subversion.apache.org には、低速な回線を使用しており、大きなファイルをメールで受信したくないサブスクライバーがたくさんいます。代わりに、ダウンロード用に po ファイルをインターネットのどこかに配置し、URL を投稿してください。利用できるサイトがない場合は、dev@ で問い合わせてください。誰かが場所を見つけるのに協力してくれるでしょう。
もちろん、Subversion リポジトリへのコミットアクセス権がある場合は、他のすべての要件が満たされていると仮定して、そこに po ファイルをコミットできます。
ビルドシステムの Makefile ベースの部分には、既存の po ファイルのメンテナンスを容易にするための make ターゲットが含まれています。GNU gettext を使用したシステムで po ファイルを更新するには、次を実行します。
make locale-gnu-po-update
特定の言語のみを更新するには、次を使用できます。
make locale-gnu-po-update PO=ll
ここで、ll は拡張子なしの po ファイルの名前です (つまり、PO=sv)。
.po の更新は、2 回のコミットを使用して行うことをお勧めします。1 回は "make locale-gnu-po-update" の後、もう 1 回は翻訳が完了した後です。これには 2 つの利点があります。
gettext(1)
は、他の翻訳者による結果の差分の確認を困難にする、多数の行番号の変更を生成します。2 回コミットすることで、すべての行番号の変更が最初のコミットに格納され、2 回目のコミットには、余分なゴミのない実際のすべての翻訳が含まれます。trunk での po ファイルの編集は非常に簡単ですが、これらの変更をリリースブランチに転送する場合は少し複雑になります。プロジェクトの方針は、リリースブランチで直接変更を行わないことです。ブランチにコミットされるすべては、trunk からマージする必要があります。これは po ファイルにも適用されます。svn merge
を使用してジョブを実行すると、gettext によって行われた行番号と文字列の書式設定の変更により、競合やファジーメッセージが発生する可能性があります。
svn merge
を使用してブランチを更新するときに存在する複雑さを解消します。次のルールが適用されます。make locale-gnu-po-update
上記の一覧は、ブランチの po ファイルで許可されるすべての操作の完全な列挙です。
YY.po の trunk リビジョン X からブランチワーキングコピーにメッセージをマージするには、次のコマンドを使用できます。
svn cat -r X ^/subversion/trunk/subversion/po/YY.po | \ po-merge.py YY.po
一部の gettext 実装では、プロジェクトを通じて取得したか、ローカルで作成したかに関係なく、mo ファイルが UTF-8 を使用してエンコードされていることを確認する必要があります。この要件は、Subversion が内部で UTF-8 を使用していること、一部の実装がアクティブなロケールに翻訳すること、および bind_textdomain_codeset()
が実装間で移植可能ではないという事実から生じます。
一部の gettext 実装では、管理データを保持するために msgid "" (空の文字列) を持つセクションを使用します。提案されているヘッダーの1つは「Last-Translator:」フィールドです。Subversion プロジェクトには、特定のファイルに貢献者の名前を記載せず、リポジトリログメッセージでクレジットを付与するポリシーがあるため、このフィールドに自分の名前を入力する必要はありません。
一部のツールでは、po ファイルを有効と見なすためにこのフィールドが必要なため (つまり、Emacs PO モード)、このフィールドに "dev@subversion.apache.org" を入力できます。
プロジェクトでは、引用符の使用を標準化しています。一部の翻訳チームも同じことを行っています。ロケールに翻訳チームがない場合、または引用符を標準化していない場合は、このガイドの他の場所にあるプロジェクトガイドラインに従ってください。もしそうなら、彼らに従ってください:-)