[インデックス 17778] ファイルの概要
このコミットは、Goプロジェクトのコードレビューシステムにおける、Mercurial (hg) の同期処理に関するバグ修正です。具体的には、サブモジュール(subrepositories)に対する変更リスト(Change List, CL)が、自身によって提出されたものの、他の開発者によってコミットされた場合に、正しくクローズされない問題を解決します。
コミット
commit 50d4dae80b9afc34dc931caef180161dba9b1530
Author: Dominik Honnef <dominik.honnef@gmail.com>
Date: Thu Oct 10 16:30:47 2013 -0700
codereview: fix hg sync closing of CLs for subrepositories
The regexp for closing CLs that were sent by you but committed by
someone else only matched messages for the main repository,
because of the added &repo=... for subrepositories.
R=golang-dev, r
CC=golang-dev
https://golang.org/cl/14512045
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/50d4dae80b9afc34dc931caef180161dba9b1530
元コミット内容
codereview: fix hg sync closing of CLs for subrepositories
The regexp for closing CLs that were sent by you but committed by
someone else only matched messages for the main repository,
because of the added &repo=... for subrepositories.
変更の背景
Goプロジェクトでは、コードレビューにRietveldというシステムが使用されていました(現在はGerritに移行済み)。開発者は変更をRietveldにアップロードし、レビューを受け、承認された後にコミットされます。このプロセスにおいて、自身が提出した変更リスト(CL)が、他の開発者(例えば、メンテナー)によって最終的にリポジトリにコミットされることがあります。
このコミットが修正しようとしている問題は、hg sync
(Mercurialの同期コマンド)が実行された際に、Rietveld上のCLのステータスを正しく更新できないというものでした。特に、サブモジュール(subrepositories)に対する変更の場合に問題が発生していました。
Rietveldは、CLがコミットされたことを示すために、レビューコメントに特定の形式のメッセージを追加します。このメッセージには、コミットハッシュが含まれており、codereview.py
スクリプトがこのメッセージを解析して、CLがコミット済みであると判断し、ステータスを「クローズ済み」に更新します。
しかし、サブモジュールに対する変更の場合、Rietveldのメッセージには&repo=...
という形式のクエリパラメータが追加されることがありました。既存の正規表現は、この&repo=...
の部分を考慮していなかったため、サブモジュールに対するCLがコミットされても、正規表現がマッチせず、CLがRietveld上で「オープン」のまま残ってしまうというバグがありました。これにより、開発者は自分のCLが既にコミットされているにもかかわらず、Rietveld上では未処理のように見えてしまうという不便を強いられていました。
前提知識の解説
- Goプロジェクトのコードレビュープロセス: Goプロジェクトは、かつてRietveldというコードレビューツールを使用していました。開発者は変更をRietveldにアップロードし、レビューアからのフィードバックを受け、最終的に承認された変更がリポジトリにコミットされます。このプロセスでは、開発者自身がコミットすることもあれば、メンテナーが代理でコミットすることもあります。
- Rietveld: Googleが開発したオープンソースのコードレビューシステムです。PerforceのChange List (CL) の概念に影響を受けています。ウェブベースのインターフェースを提供し、コードの差分表示、コメント、ステータス管理などの機能を提供します。
- Change List (CL): Rietveldにおける変更の単位です。一連の変更(コミット)をまとめてレビューに提出する際に使用されます。
- Mercurial (hg): 分散型バージョン管理システムの一つで、Gitと同様の機能を提供します。Goプロジェクトは初期にはMercurialを使用していましたが、後にGitに移行しました。
hg sync
は、ローカルリポジトリとリモートリポジトリ間で変更を同期するためのコマンドです。 - サブモジュール (Subrepositories): Mercurialにおける機能で、一つのリポジトリ内に別のリポジトリを埋め込むことができます。これにより、複数の関連するプロジェクトを一つの親リポジトリで管理することが可能になります。Goプロジェクトでは、標準ライブラリの一部やツールなどがサブモジュールとして管理されることがありました。
- 正規表現 (Regular Expression, Regexp): 文字列のパターンを記述するための強力なツールです。このコミットでは、Rietveldのコメントから特定の情報を抽出するために正規表現が使用されています。
re.match()
: Pythonのre
モジュールにおける関数で、文字列の先頭から正規表現パターンにマッチするかどうかを調べます。*
: 直前の文字が0回以上繰り返されることを意味します。?
: 直前の文字が0回または1回出現することを意味します(非貪欲マッチ)。[^*]*?
:*
以外の任意の文字が0回以上繰り返されることを非貪欲にマッチさせます。[0-9a-f]+
: 16進数の文字(0-9, a-f)が1回以上繰り返されることを意味します。これはコミットハッシュの一部を捕捉するために使用されます。\s
: 空白文字にマッチします。\*\*\*
:*
は正規表現の特殊文字なので、リテラルとしてマッチさせるためにはエスケープ(\
)が必要です。
技術的詳細
このコミットの核心は、lib/codereview/codereview.py
ファイル内のIsRietveldSubmitted
関数における正規表現の変更です。この関数は、Rietveldのメッセージを解析し、特定のCLが既にコミットされているかどうかを判断する役割を担っています。
元の正規表現は以下の通りでした。
re.match('\\*\\*\\* Submitted as [^*]*?([0-9a-f]+) \\*\\*\\*'
この正規表現は、Rietveldのコメントが「*** Submitted as <何か> <コミットハッシュ> ***
」という形式であると想定していました。ここで<何か>
の部分は、コミットハッシュの前に来る任意の文字列(*
以外の文字)に非貪欲にマッチします。そして、([0-9a-f]+)
でコミットハッシュをキャプチャしていました。
しかし、サブモジュールに対するCLがコミットされた場合、Rietveldのコメントは例えば「*** Submitted as <何か> r=<コミットハッシュ>&repo=subrepo_name ***
」のように、コミットハッシュの後に&repo=...
という形式の文字列が追加されることがありました。元の正規表現は、この&repo=...
の部分を正しく処理できず、マッチに失敗していました。具体的には、[^*]*?
の部分が&repo=
を含む文字列全体を消費してしまい、その後の([0-9a-f]+)
がコミットハッシュを正しく抽出できなかったか、あるいは***
の閉じタグがマッチしなかった可能性があります。
新しい正規表現は以下の通りです。
re.match('\\*\\*\\* Submitted as [^*]*?r=([0-9a-f]+)[^ ]* \\*\\*\\*'
この変更のポイントは、コミットハッシュをキャプチャする部分の直前にr=
を追加し、その後に[^ ]*
(スペース以外の任意の文字が0回以上繰り返される)を追加したことです。
r=
: Rietveldのコメントでコミットハッシュの前にr=
が付与されるパターンに対応します。これは、Rietveldがコミットハッシュを識別するためのプレフィックスとして使用していた可能性があります。([^ ]*)
: コミットハッシュの後に続く、スペース以外の任意の文字(&repo=...
など)にマッチします。これにより、&repo=...
のような追加情報があっても、正規表現全体が正しくマッチし、([0-9a-f]+)
が正確にコミットハッシュをキャプチャできるようになります。
この修正により、サブモジュールに対するCLがコミットされた場合でも、hg sync
がRietveldのコメントを正しく解析し、CLのステータスを「クローズ済み」に更新できるようになりました。
コアとなるコードの変更箇所
lib/codereview/codereview.py
ファイルのIsRietveldSubmitted
関数内の正規表現が変更されています。
--- a/lib/codereview/codereview.py
+++ b/lib/codereview/codereview.py
@@ -2402,7 +2402,7 @@ def IsRietveldSubmitted(ui, clname, hex):
return False
for msg in dict.get("messages", []):
text = msg.get("text", "")
- m = re.match('\\*\\*\\* Submitted as [^*]*?([0-9a-f]+) \\*\\*\\*', text)
+ m = re.match('\\*\\*\\* Submitted as [^*]*?r=([0-9a-f]+)[^ ]* \\*\\*\\*', text)
if m is not None and len(m.group(1)) >= 8 and hex.startswith(m.group(1)):
return True
return False
コアとなるコードの解説
IsRietveldSubmitted
関数は、与えられたclname
(Change Listの名前)とhex
(コミットハッシュ)がRietveldによって提出されたものかどうかを判断します。
dict.get("messages", [])
で、RietveldのCLに関連付けられたメッセージのリストを取得します。- 各メッセージ(
msg
)について、そのテキスト内容(text
)を取得します。 re.match()
を使用して、メッセージテキストが特定のパターンにマッチするかどうかをチェックします。- 変更前:
re.match('\\*\\*\\* Submitted as [^*]*?([0-9a-f]+) \\*\\*\\*', text)
- 変更後:
re.match('\\*\\*\\* Submitted as [^*]*?r=([0-9a-f]+)[^ ]* \\*\\*\\*', text)
この正規表現は、メッセージが「*** Submitted as ...
」で始まり、その中にコミットハッシュ([0-9a-f]+
)が含まれていることを期待します。
- 変更前:
m is not None
でマッチが成功したかどうかを確認します。len(m.group(1)) >= 8
で、キャプチャされたコミットハッシュの長さが8文字以上であることを確認します。これは、コミットハッシュが十分に長いことを保証するためです。hex.startswith(m.group(1))
で、与えられたコミットハッシュhex
が、メッセージから抽出されたコミットハッシュのプレフィックスと一致するかどうかを確認します。これは、部分的なハッシュマッチを許容するためです。- これらの条件がすべて満たされれば、そのCLはRietveldによって提出され、コミットされたものと判断し、
True
を返します。
この修正により、正規表現がサブモジュールに関連するRietveldのコメント形式にも対応できるようになり、hg sync
がCLのステータスを正確に更新できるようになりました。
関連リンク
- Goプロジェクトのコードレビュープロセスに関する情報(RietveldからGerritへの移行など):
- https://go.dev/doc/contribute (現在のGoプロジェクトの貢献ガイドライン)
- Rietveldの公式ページ(現在はアーカイブされている可能性が高いですが、情報源として):
- Mercurialの公式ドキュメント:
参考にした情報源リンク
- GoプロジェクトのGitHubリポジトリ: https://github.com/golang/go
- Mercurialのサブモジュールに関するドキュメント
- 正規表現に関する一般的なドキュメント(Pythonの
re
モジュールなど) - Rietveldのコメント形式に関する情報(Goプロジェクトの過去のコードレビュー慣習)
- コミットメッセージとコードの差分
I have provided the detailed explanation as requested, following all the specified instructions and chapter structure. I have used the commit information and general knowledge about Go's past development practices (Rietveld, Mercurial) to provide a comprehensive explanation. I did not need to use
google_web_search
explicitly as the context from the commit message and my existing knowledge was sufficient to explain the technical details.
I have outputted the explanation to standard output only, as requested. The task is complete.