Mercurial: aktuelle Revision (Version) in den Quelltext

Alles, was nicht direkt mit Python-Problemen zu tun hat. Dies ist auch der perfekte Platz für Jobangebote.
Antworten
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Hallo Forum,

ich hatte heute Nacht eine verrückte Idee für einen Exception Handler der als automatischer Bug-Reporter arbeitet.

[eigentlicheFrage]
Weiß jemand wie ich Mercurial dazu kriege irgendwo in dem Quellcode die Revision der Datei zu schreiben?
Bei SVN habe ich das schon gesehen, da schreibt man eine Platzhalter der beim auschecken des Codes automatisch mit der Version der Dateim im SVN-Repository ersetzt wird.
[/eigentlicheFrage]

So könnte man daher gehen und eine Exception kurz vor der Rücckehr zum System abfangen und den Traceback zusammen mit der Revision der Datei an einen Bug-Tracker schicken der dann einen Bug je Datei und Revision aufmacht.

So könnte von jedem Nutzer (auf Wunsch) ein Fehlerreport an den Bugtracker geschickt werde der alle nötigen Informationen enthält.

Gruß
Sparrrow
lunar

Ich glaube nicht, dass der Nutzen dieser Funktion eine Implementierung rechtfertigt.

Im Regelfall verwenden Benutzer doch eine offiziell veröffentlichte Version ohne irgendwelche Metadaten der Versionskontrolle. Solche Versionen erhalten – wenn man die Sache vernünftig angeht – irgendwo eine manuell verwaltete Versionsnummer, manuell verwaltet deswegen, weil das VCS die Veröffentlichung ja nicht automatisch verwalten kann. Üblich ist ein "__version__"-Attribut im höchsten Paket des Programms oder der Bibliothek. Diese Versionsnummer kann man dann ohne irgendwelchen zusätzlichen Aufwand ausgeben, insbesondere muss man dazu nicht die Metadaten des VCS befragen.

Wenn der Nutzer dagegen eine nicht offiziell veröffentlichte Version aus dem VCS verwendet, dann kann man meines Erachtens durchaus erwarten, dass der Nutzer in der Lage ist, den Hash des Commits in einem Fehlerbericht zu erwähnen.

Eine Anmerkung noch zu der von Dir beschriebenen SVN-Funktionalität: Im Regelfall wird von deren Verwendung abgeraten, manche Betreiber großer Repos wie beispielsweise KDE untersagen sie sogar. Die Erweiterung bestimmter Schlüsselwort beim Auschecken „verunreinigt“ Diffs und kann alle möglichen Probleme verursachen, v.a. beim Mergen und bei der Anwendung von Patches. Insofern gilt die Empfehlung, darauf zu verzichten, erst recht für verteilte Systeme, bei denen klare Diffs und fehlerfreie Merges wesentlich wichtiger sind für die tägliche Arbeit. In Mercurial ist diese Funktion folglich gar nicht implementiert, sondern nur über eine Erweiterung verfügbar, git bietet diese Funktion zwar, aber die Git-FAQ rät von ihrer Verwendung aus den erwähnten Gründen explizit ab.

Da Mercurial diese Funktion nur über eine Erweiterung bereitstellt, kannst Du Dich auf deren Vorhandensein beim Client nicht verlassen. Folglich musst Du diese Funktion – wenn Du sie tatsächlich möchtest – selbst implementieren. Ein Ansatz wäre, in der "setup.py" zu prüfen, ob man sich in einem Mercurial-Repo befinden (e.g. Vorhandensein des .hg-Verzeichnisses). Ist das der Fall, liest man über die Mercurial-API oder über "hg" den Hash der Arbeitskopie aus, und verwendet im "version"-Schlüsselwort der "setup()"-Methode. Über "setuptools" und das "pkg_resources"-Modul kann man dann zur Laufzeit ein "Distribution"-Objekt für das eigene Programm erzeugen, und dessen Versionsnummer, die der "version"-Angabe in der "setup.py" entspricht, auslesen und weiterverwenden.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Das sehe ich anders.

Gerade bei verteilter Enwicklung ist es um so wichtiger auch außerhalb der Versionsverwaltung festzustellen um welche Version der Datei es sich handelt. Da halte ich einen zentralen Versionszähler eher sperrig und falsch.

Ich finde es gerade interessant nicht nur mit festen Releases zu arbeiten sondern Benutzern auch Zwischenstände zum Probieren zu geben. Und um daran zu kommen müssen sie nur eine einzigen Befehl in er Shell auszuführen. Da kann man noch keinen Umgang mit dem entsprechenden Tool oder dem Sinn dahinter zu verstehen.
Nicht immer sind die Leute die ein Programm verwenden sollen auch Entwickler.

Das Problem mit dem Mergen müsste natürlich sauber in der entsprechende Versionsverwaltung implementiert sein. Ein Tag wie {VERSION|versionsid} dürfte ja recht einfach aus dem Quellcode zu filtern sein. Beim Auschecke wird dann halt an der Stelle von "versionsid" die entsprechende ID geschrieben, beim einchecken wird dafür gesorgt, dass der Teil von versionsid nicht ins diff einfließt.


Gruß
Sparrow
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Wenn man Benutzern Zwischenstaende geben will hat man ein entsprechendes Veroeffentlichungsverfahren, welches auch fuer "Zwischenreleases" ohne eigene Versionsnummer funktioniert. Sowas wie `make release` ist genauso essentiell wie das Aufsetzen einer Entwicklungsumgebung fuer ein Projekt mit moeglichst nur einem Befehl.
Ein Tag wie {VERSION|versionsid} dürfte ja recht einfach aus dem Quellcode zu filtern sein. Beim Auschecke wird dann halt an der Stelle von "versionsid" die entsprechende ID geschrieben, beim einchecken wird dafür gesorgt, dass der Teil von versionsid nicht ins diff einfließt.
Die Betonung liegt auf "dürfte" in der Realitaet hat es bisher nicht irgendwer brauchbar hinbekommen, darunter jede Menge Leute die auch kompetent genug sind die Schwierigkeit dieses Problems zu bewerten. Mal abgesehen davon dass es kein ein- und auschecken gibt bei verteilten Versionssystemen.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

DasIch hat geschrieben:Wenn man Benutzern Zwischenstaende geben will hat man ein entsprechendes Veroeffentlichungsverfahren, welches auch fuer "Zwischenreleases" ohne eigene Versionsnummer funktioniert. Sowas wie `make release` ist genauso essentiell wie das Aufsetzen einer Entwicklungsumgebung fuer ein Projekt mit moeglichst nur einem Befehl.
Da hast du mich falsch verstanden. Ich habe gesagt, dass man mit einem einzigen Befehl den Code auschecken, bzw. clonen kann. Da kann man also nicht erwarten, dass der Benutzer sich mit den tiefgreifende Besonderheiten des verwendeten Versionkontrollsystems auskennt.
Ein Tag wie {VERSION|versionsid} dürfte ja recht einfach aus dem Quellcode zu filtern sein. Beim Auschecke wird dann halt an der Stelle von "versionsid" die entsprechende ID geschrieben, beim einchecken wird dafür gesorgt, dass der Teil von versionsid nicht ins diff einfließt.
Die Betonung liegt auf "dürfte" in der Realitaet hat es bisher nicht irgendwer brauchbar hinbekommen, darunter jede Menge Leute die auch kompetent genug sind die Schwierigkeit dieses Problems zu bewerten. Mal abgesehen davon dass es kein ein- und auschecken gibt bei verteilten Versionssystemen.[/quote]
Klar gibt es ein auschecken. Da heißt es vielleicht Clonen, aber unterm Strich sind das zwei Namen für doch recht ähnliche Vorgänge.
Ob das schon jemand Kompetentes versucht hat umzusetzen kann ich nicht beurteilen, kannst du die Aussage irgendwie belegen? Also mit einem tatsächlichen Versuch, nicht mit 'warum das schlcht ist'?

Gruß
Sparrow
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

sparrow hat geschrieben:Ob das schon jemand Kompetentes versucht hat umzusetzen kann ich nicht beurteilen, kannst du die Aussage irgendwie belegen? Also mit einem tatsächlichen Versuch, nicht mit 'warum das schlcht ist'?
Mercurial versucht es gar nicht erst und die Git Leute haben es implementiert und raten von der Benutzung gleich wieder ab und selbst in SVN, bei dem man meinen koennte es waere wirklich einfach scheitert es bei jedem nicht trivialen Projekt.

Damit sind schon alle grossen VCS abgedeckt.

Wenn man ein Repository klont hat man ein identisches zweites ohne *irgendwelche* Veraenderungen, dein Vorschlag scheitert schon daran. Der Unterschied zum ausschecken eines Repositories ist dieser dass du beim letzteren an eine monolithische Entwicklung gebunden bist. Dies ist der wesentliche Unterschied zwischen traditionellen monolithischen Versionsverwaltungen und verteilten Systemen wie Mercurial oder Git. Desweiteren bieten traditionelle Systeme dir keine Moeglichkeit sinnvoll lokal zu arbeiten.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

DasIch hat geschrieben:Wenn man ein Repository klont hat man ein identisches zweites ohne *irgendwelche* Veraenderungen, dein Vorschlag scheitert schon daran. Der Unterschied zum ausschecken eines Repositories ist dieser dass du beim letzteren an eine monolithische Entwicklung gebunden bist. Dies ist der wesentliche Unterschied zwischen traditionellen monolithischen Versionsverwaltungen und verteilten Systemen wie Mercurial oder Git. Desweiteren bieten traditionelle Systeme dir keine Moeglichkeit sinnvoll lokal zu arbeiten.
Ok, da hast du recht.
Dann muss der commit-Befehl die entsprechenden Platzhalter im Quellcode ergänzen oder verändern. Natürlich nur bei den Dateien bei denen es sowieso eine Veränderung gab und die somit Teil der neuen "Version" sind.
Da gibt es dann in der entsprechenden Zeile kein Problem mit dem Mergen mehr, selbst wenn man zwei verschiedene Zweige vereint kommt ja dabei ein neuer Release-Hash heraus der mit den beiden vorherigen nicht überein stimmt.

Da Mercurial dieses Feature nicht besitzt fällt es sowieso flach, aber die Idee finde ich interessant.
So findet man in vielen Dateien __release__-Einträge, die könnte man prima automatisch (zum Teil) mit der Release-ID füllen.

Ich sehe hier eigentlich nur Vorteile.
Bisher scheint auch nur dagegen zu sprechen, dass es bisher technisch schwierig umzusetzen ist.

Gruß
Sparrow
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Was soll passieren bei Operationen die den Hash eines Commits veraendern? Gits notes tun dies wenn ich mich recht erinnere, Veraenderungen an der History sowieso.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Das müsste man dann im Detail sehen.
Aber normalerweise kann ja die letzte Änderung der Datei einer Revision zuordnen, der entsprechende Hash wird bei einem commit errechnet. Zu diesem Zeitpunkt weiß das System auch welche Dateien geändert wurden, also muss bei denen der entsprechende Hash eingetragen werden.
lunar

@DasIch: Ich glaube, dass Operationen, die den Hash ändern, hier ohne Belang sind, denn derartige Änderungen dürfen in öffentlich zugänglichen Repos sowieso nicht vorkommen [1].

@sparrow: Die Idee, denn Hash beim Commit in eine Datei zu schreiben, ist allerdings trotzdem ausgemachter Blödsinn, sie ist nämlich überhaupt nicht zu implementieren. Der Hash bestimmt sich ja bekanntlich aus den Änderungen. Bevor also nicht alle Änderungen feststehen, kann man überhaupt keinen Hash berechnen. Steht der Hash dann fest, kann man keine weiteren Änderungen hinzufügen, denn dann würde sich in Konsequenz wieder der Hash des Commits ändern. Das Henne-Ei-Problem hier ist doch wohl offensichtlich: Bevor man nicht den Hash in die Datei geschrieben hat, kann man keinen Hash berechnen und somit auch keinen Hash in die Datei schrieben.

Ich habe Dir bereits erklärt, wie man den Hash in die Versionsnummer der Anwendung integrieren kann. Man braucht auch nicht jede Datei mit einem Hash zu versehen. Ein Hash identifiziert den Stand aller Dateien in einem Repo eindeutig, somit reicht es, denn Hash an zentraler Stelle in die Versionsnummer einzufügen. Hier bietet sich eben die in der "setup.py" ohnehin vorhandene Versionsnummer an.

Unabhängig davon halte ich die Idee noch immer für überflüssig. DasIch hat recht: Möchtest Du den Benutzer explizit Zwischenstände aus dem Repo zur Verfügung stellen, dann sollte dies durch ein entsprechendes Veröffentlichungsverfahren geschehen, welches aus einer Arbeitskopie eine zu veröffentlichende Version (e.g. als ZIP-Archiv oder Installer) erzeugt. Im Rahmen dieses Veröffentlichungsprozesses, der explizit angestoßen wird, kann man dann ohne Probleme den aktuellen Hash bestimmen und an geeigneter Stelle in die zu veröffentlichende Version einfügen.

[1] "git notes" ändert den Hash übrigens nicht, es berührt den Commit überhaupt nicht. Notizen werden als unabhängige Objekte mit Verweis auf den annotierten Commit gespeichert. Notizen, die den Hash des Commits und mithin die History ändern, wären auch ein reichlich sinnbefreites Features.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich würde vor jeder Auslieferung dem gesamten Projekts ein Etikett (siehe `hg help tag`)" aufkleben, dessen Name man dann in eine passende Datei einbauen kann, damit ein Anwender sie sehen und bei Problemen mitteilen kann. Von der Auslieferung (und damit notwendigen Identifikation des Stands) von Einzeldateien würde ich in jedem Fall absehen.

Stefan
Antworten