私はPythonでMercurialリビジョン番号/ ID(番号ではなくハッシュです)をプログラムで取得しようとしています。
その理由は、次のようにWebサイトのcss/jsファイルに追加したいからです。
<link rel="stylesheet" href="example.css?{% Mercurial_revision "example.css" %}" />
そのため、スタイルシートに変更が加えられるたびに、新しいURLが取得され、古いキャッシュバージョンは使用されなくなります。
[〜#〜]または[〜#〜] Mercurialの適切なドキュメントがどこにあるか知っている場合python module、それも役に立ちます。どこにも見つからないようです。
サブプロセスを使用して、hgノードを取得するコマンドを実行することになりました。 APIが同じままであることが保証されていないため、このソリューションを選択しましたが、bashインターフェイスはおそらく次のようになります。
import subprocess
def get_hg_rev(file_path):
pipe = subprocess.Popen(
["hg", "log", "-l", "1", "--template", "{node}", file_path],
stdout=subprocess.PIPE
)
return pipe.stdout.read()
使用例:
> path_to_file = "/home/jim/workspace/lgr/pinax/projects/lgr/site_media/base.css"
> get_hg_rev(path_to_file)
'0ed525cf38a7b7f4f1321763d964a39327db97c4'
確かに公式のAPIはありませんが、他の拡張機能、特にhgにバンドルされている拡張機能を読むことで、ベストプラクティスについてのアイデアを得ることができます。この特定の問題に対して、私は次のようなことをします:
from Mercurial import ui, hg
from Mercurial.node import hex
repo = hg.repository('/path/to/repo/root', ui.ui())
fctx = repo.filectx('/path/to/file', 'tip')
hexnode = hex(fctx.node())
更新ある時点でパラメータの順序が変更され、次のようになりました。
repo = hg.repository(ui.ui(), '/path/to/repo/root' )
このドキュメント という意味ですか?
そのページに記載されているように、officialAPIはありません。これは、いつでも変更する権利を留保しているためです。 。しかし、最後のいくつかのバージョンでの変更のリストを見ることができます、それはそれほど広範囲ではありません。
更新された、よりクリーンなサブプロセスバージョン(.check_output()
を使用、Python 2.7/3.1)で追加、Djangoの設定ファイルで使用)大まかなエンドツーエンドのデプロイメントチェック(HTMLコメントにダンプします):
import subprocess
HG_REV = subprocess.check_output(['hg', 'id', '--id']).strip()
起動を妨げるような奇妙な問題が発生したくない場合は、try
でラップできます。
try:
HG_REV = subprocess.check_output(['hg', 'id', '--id']).strip()
except OSError:
HG_REV = "? (Couldn't find hg)"
except subprocess.CalledProcessError as e:
HG_REV = "? (Error {})".format(e.returncode)
except Exception: # don't use bare 'except', mis-catches Ctrl-C and more
# should never have to deal with a hangup
HG_REV = "???"
Python 2を使用している場合は、 hglib
。
Python 3、申し訳ありません。おそらく hgapi
を使用している場合は何を使用すればよいかわかりません。
Mercurialには2つの公式APIがあります。
hglib
( wiki 、 PyPI )パッケージを使用して通信できます。 Mercurialチーム。subprocess
、 hgapi
などで話しかけることができます。インストール:
pip install python-hglib
使用法:
import hglib
client = hglib.open("/path/to/repo")
commit = client.log("tip")
print commit.author
hglib wikiページ のその他の使用法情報。
それはMercurialチームによって維持されており、MercurialチームがMercurialとのインターフェースに推奨するものだからです。
Mercurialのwikiから 、Mercurialとのインターフェースに関する次のステートメント:
サードパーティのコードの大部分では、Mercurialの公開され、文書化された、安定したAPIであるコマンドラインインターフェイスを使用するのが最善の方法です。または、 CommandServer またはそれに基づくライブラリを使用して、高速で安定した言語に依存しないインターフェイスを取得します。
コマンドサーバーページから:
[コマンドサーバーにより]サードパーティのアプリケーションとライブラリがパイプを介してMercurialと通信できるため、コマンドごとの起動のオーバーヘッドがなくなります。次に、ライブラリはコマンドの生成と解析をカプセル化して、これらのコマンドに言語に適したAPIを提示できます。
前述のように、MercurialコマンドサーバーへのPythonインターフェイスはhglib
です。
ちなみに、コマンドラインインターフェイスのコマンドごとのオーバーヘッドは冗談ではありません。私はかつて、hg
を介してsubprocess
を使用して、たとえば、状況をマージします。プロジェクト全体を通して、スイートのランタイムは5〜30秒の間に留まり、ほぼすべての時間がhg
呼び出しに費やされました。
Pythonフック関数のシグネチャは次のようになります:
# In the hgrc:
# [hooks]
# preupdate.my_hook = python:/path/to/file.py:my_hook
def my_hook(
ui, repo, hooktype,
... hook-specific args, find them in `hg help config` ...,
**kwargs)
ui
とrepo
は、前述の非公式の非公式の一部です 内部API 。それらが関数argsにあるという事実は、特定のブランチ間のマージを禁止するpreupdate
フックのこの例のように、それらを使用するのに非常に便利です。
def check_if_merge_is_allowed(ui, repo, hooktype, parent1, parent2, **kwargs):
from_ = repo[parent2].branch()
to_ = repo[parent1].branch()
...
# return True if the hook fails and the merge should not proceed.
フックコードがそれほど重要ではなく、公開していない場合は、推奨されていない非公式の内部APIを使用することを選択できます。フックが公開している拡張機能の一部である場合は、hglib
を使用することをお勧めします。
試してみてください キーワード拡張
FWIWは、すべてのページ/ビューレンダリングでその値をフェッチしないようにするために、デプロイでそれをsettings.py
ファイルに配置するだけです。そうすれば、Mercurialや別のプロセスにアクセスするオーバーヘッドなしにsettings.REVISION
を参照できます。サーバーをリロードせずにこの値を変更したことはありますか?
OPがやりたかったのと同じことをしたかったので、hg id -i
スクリプトから(そのリポジトリ内の単一のファイルではなく、リポジトリ全体のヒントリビジョンを取得します)、popenを使用したくなかったので、brendan
のコードで開始しましたが、そうではありませんでした私が欲しかったもの。
だから私はこれを書いた...コメント/批評を歓迎します。これにより、16進数のチップ回転が文字列として取得されます。
from Mercurial import ui, hg, revlog
# from Mercurial.node import hex # should I have used this?
def getrepohex(reporoot):
repo = hg.repository(ui.ui(), reporoot)
revs = repo.revs('tip')
if len(revs)==1:
return str(repo.changectx(revs[0]))
else:
raise Exception("Internal failure in getrepohex")