30

Pythonでプログラムでmercurialリビジョン番号/ ID(数値ではなくハッシュ)を取得しようとしています。

その理由は、私たちのウェブサイトの css/js ファイルに次のように追加したいからです:

<link rel="stylesheet" href="example.css?{% mercurial_revision "example.css" %}" />

そのため、スタイルシートに変更が加えられるたびに新しい URL が取得され、キャッシュされた古いバージョンは使用されなくなります。

または、mercurial python モジュールの適切なドキュメントがどこにあるかを知っていれば、それも役に立ちます。どこにも見つからないようです。

私の解決策

サブプロセスを使用して、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'
4

7 に答える 7

15

確かに公式の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' )
于 2009-07-20T16:06:03.057 に答える
8

このドキュメンテーションのことですか?
そのページに記載されているように、いつでも変更する権利を留保しているため、公式の API はありません。ただし、最近のいくつかのバージョンでの変更点のリストを見ることができますが、それほど広範囲ではありません。

于 2009-07-20T13:49:47.697 に答える
6

更新された、よりクリーンなサブプロセス バージョン ( .check_output()Python 2.7/3.1 で追加された 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 = "???"
于 2014-02-24T22:50:00.763 に答える
4

Python 2 を使用している場合は、hglib.

Python 3 を使用している場合、何を使用すればよいかわかりません。申し訳ありません。おそらくhgapi

この回答の内容

  • Mercurial の API
  • hglib の使い方
  • Python 2 ユーザーにとって hglib が最適な理由
  • あなたがフックを書いているなら、その落胆した内部インターフェースは非常に便利です

Mercurial の API

Mercurial には 2 つの公式 API があります。

  1. Mercurial コマンド サーバー。hglibMercurial チームによって管理されている( wikiPyPI ) パッケージを使用して、Python 2 から対話することができます。
  2. Mercurial のコマンドライン インターフェイス。subprocess、 、 、またはそのようなものを介して話しかけることができますhgapi

hglib の使い方

インストール:

pip install python-hglib

使用法:

import hglib
client = hglib.open("/path/to/repo")

commit = client.log("tip")
print commit.author

hglib wiki ページの使用法の詳細。

Python 2 ユーザーにとって hglib が最適な理由

これは Mercurial チームによって維持されており、Mercurial チームが Mercurial とのインターフェースとして推奨しているものだからです。

Mercurial の wiki から、Mercurial とのインターフェースに関する次のステートメント:

大多数のサード パーティ コードの場合、最善の方法は、Mercurial の公開され、文書化された、安定した API、つまりコマンド ライン インターフェイスを使用することです。または、 CommandServerまたはそれに基づくライブラリを使用して、高速で安定した、言語に依存しないインターフェイスを取得します。

コマンド サーバー ページから:

[コマンド サーバーにより] サードパーティのアプリケーションとライブラリは、パイプを介して Mercurial と通信できるため、コマンドごとの起動オーバーヘッドがなくなります。その後、ライブラリはコマンドの生成と解析をカプセル化して、言語に適した API をこれらのコマンドに提供できます。

前述のように、Mercurial コマンド サーバーへの Python インターフェイスはhglib.

ところで、コマンド ライン インターフェイスのコマンドごとのオーバーヘッドは冗談ではありません。私はかつて非常に小さなテスト スイート (約 5 つのテストのみ) を構築しました。このテスト スイートは、作成、コミットごとのコミット、マージなどの状況での少数のリポジトリの作成に使用されましたhgsubprocessプロジェクト全体を通して、スイートの実行時間は 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)

uirepo前述の推奨されない非公式の内部APIの一部です。それらが関数の引数のすぐそこにあるという事実は、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

于 2015-03-01T23:12:55.677 に答える
3

キーワード拡張子を試してみてください

于 2009-07-20T13:14:48.087 に答える
0

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")
于 2012-11-26T16:08:18.160 に答える