Frage

Ich versuche, die Quecksilber-Revisionsnummer / id (es ist ein Hash keine Zahl) programmatisch in Python zu erhalten.

Der Grund dafür ist, dass ich es auf die css / js Dateien auf unserer Website hinzufügen möchte wie folgt:

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

So dass, wenn eine Änderung des Sheet gemacht wird, wird es eine neue URL bekommen und nicht mehr die alte Cache-Version verwenden.

ODER , wenn Sie wissen, wo gute Dokumentation für die Quecksilber- Python-Modul finden , die auch hilfreich sein würden. Ich kann nicht scheinen, es überall zu finden.

Meine Lösung

endete ich mit subprocess bis zu nur einen Befehl ausführen, der die hg Knoten bekommt. Ich habe mich für diese Lösung, weil die api nicht garantiert gleich bleiben, aber die Bash-Schnittstelle wird wahrscheinlich:

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()

Beispiel für die Verwendung:

> path_to_file = "/home/jim/workspace/lgr/pinax/projects/lgr/site_media/base.css"
> get_hg_rev(path_to_file)
'0ed525cf38a7b7f4f1321763d964a39327db97c4'
War es hilfreich?

Lösung

Es ist wahr, es gibt keine offizielle API, aber Sie können durch das Lesen anderer Erweiterungen eine Vorstellung von Best Practices erhalten, insbesondere solche mit hg gebündelt. Für dieses spezielle Problem, würde ich so etwas tun:

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())

Aktualisieren An einem gewissen Punkt der Parameter geändert, um, jetzt ist es wie folgt aus:

   repo = hg.repository(ui.ui(), '/path/to/repo/root' )

Andere Tipps

Haben Sie meinen dieser Dokumentation ?
Beachten Sie, dass, wie in dieser Seite angegeben ist, gibt es keinen offizielle API, weil sie nach wie vor das Recht vor, sie jederzeit zu ändern. Aber Sie können die Liste der Änderungen in den letzten Versionen sehen, es ist nicht sehr umfangreich ist.

Eine aktualisierter, saubere subprocess Version (verwendet .check_output(), hinzugefügt in Python 2.7 / 3.1), die ich in meinen Django-Einstellungen verwende Datei für eine rohe End-to-End-Bereitstellung Prüfung (ich es in eine HTML-Kommentar-Dump):

import subprocess

HG_REV = subprocess.check_output(['hg', 'id', '--id']).strip()

Sie können es in einem try wickeln, wenn beim Starten des Systems zu verhindern, nicht einige seltsame Schluckauf wollen:

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 = "???"

gibt einen Versuch das Stichwort Erweiterung

Wenn Sie Python 2 verwenden, können Sie hglib .

Ich weiß nicht, was zu verwenden, wenn Sie Python verwenden 3, sorry. Wahrscheinlich hgapi .

Der Inhalt dieser Antwort

  • Mercurial APIs
  • Wie verwenden hglib
  • Warum hglib ist die beste Wahl für Python 2 Benutzer
  • Wenn Sie einen Haken schreiben, die interne Schnittstelle entmutigt ist furchtbar bequem

Mercurial APIs

Mercurial hat zwei offizielle APIs.

  1. Der Mercurial Befehlsserver. Sie können es von Python 2 unter Verwendung des hglib ( Wiki , PyPI ) Paket, das von dem Mercurial Team gehalten wird.
  2. Mercurial Kommandozeilen-Schnittstelle. Sie können über subprocess oder hgapi , etc. zu jagen.

Wie verwenden hglib

Installation:

pip install python-hglib

Verbrauch:

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

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

Weitere Verwendungsinformationen auf der hglib Wikiseite .

Warum hglib ist die beste Wahl für Python 2 Benutzer

Weil es durch das Mercurial-Team gehalten wird, und es ist das, was das Mercurial-Team für die Anbindung mit Mercurial empfehlen.

Von Mercurial Wiki , die folgende Erklärung mit Mercurial auf Schnittstellen:

  

Für die überwiegende Mehrheit der Dritten Code, der beste Ansatz ist Mercurial veröffentlicht wurde, dokumentiert und eine stabile API zu verwenden: die Befehlszeilenoberfläche. Alternativ können Sie die CommandServer oder die Bibliotheken, die darauf beruhen, eine schnelle, stabile, Sprache zu erhalten -neutrale Schnittstelle.

Von der Befehlsserver Seite:

  

[Der Befehlsserver ermöglicht] Anwendungen von Drittanbietern und Bibliotheken mit Mercurial über ein Rohr zu kommunizieren, der die pro-Befehl Start-up-Overhead beseitigt. Bibliotheken können dann den Befehl Generation kapseln und Parsen eine sprach entsprechende API auf diese Befehle zu präsentieren.

Der Python Schnittstelle zum Mercurial Befehlsserver, wie gesagt, ist hglib.

Der pro-Befehl Overhead der Befehlszeilenschnittstelle ist kein Witz, nebenbei bemerkt. Ich baute einmal eine sehr kleine Test-Suite (nur ca. 5 Tests), die hg über subprocess zum Erstellen, begehen, zu begehen, eine Handvoll repos mit z.B. verschmelzen Situationen. Während des gesamten Projekts blieb die Laufzeit der Suite zwischen 5 bis 30 Sekunden, wobei fast alle Zeit in den hg Anrufe ausgegeben.

Wenn Sie einen Haken schreiben, die interne Schnittstelle entmutigt ist furchtbar bequem

Die Signatur eines Funktions Python Haken ist wie folgt:

# 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 und sind ein Teil der vorher erwähnten discouraged nicht offizielle interne API . Die Tatsache, dass sie genau dort in der Funktion args sind macht sie furchtbar bequem, wie in diesem Beispiel eines preupdate Haken zu verwenden, die Verschmelzungen zwischen bestimmten Zweigen nicht zulässt.

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.

Wenn Ihr Haken Code nicht so wichtig ist, und Sie veröffentlichen es nicht, könnten Sie wählen die entmutigte inoffizielle interne API verwenden. Wenn Ihr Haken part einer Erweiterung, die Sie veröffentlichen, eine bessere Nutzung hglib.

FWIW zu vermeiden, diesen Wert zu holen auf jeder Seite / Ansicht machen, ich habe nur mein deploy es in die settings.py Datei setzen. Dann kann ich settings.REVISION ohne den ganzen Aufwand für den Zugriff auf Mercurial und / oder einen anderen Prozess verweisen. Haben Sie jemals diesen Wert ändern w / o Nachladen Ihre Server?

Ich wollte wollte die OP, das Gleiche tun hg id -i aus einem Skript tun, zu erhalten (aktuelle Revision des gesamten REPOSITORY bekommt, nicht von einer einzigen Datei in diesem Repo), aber ich wollte nicht verwenden, popen, und die Code von brendan hat mich begonnen, war aber nicht das, was ich wollte.

Also schrieb ich diese ... Kommentare / Kritik willkommen. Dies wird die Spitze rev in hex als String zurück.

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")
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top