[Python3] git revision auslesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
MoonKid
User
Beiträge: 105
Registriert: Mittwoch 10. Dezember 2014, 16:24

Ich möchte die git-revision meines eigenene Scripts auslesen können.
Auf der bash sieht das so aus

Code: Alles auswählen

git log -n 1 --format=%h
Wie realisiere ich das mit Python3. GitPython läuft nicht mit Python3.

subprocess scheint eine Möglichkeit zu sein, um Dinge auf der system-shell ausführen zu können, richtig?

Code: Alles auswählen

import subprocess as sp
sp.check_output('git log -n 1 --format=%h', shell=True, universal_newlines=True)
Problem ist hier das '\n' am Ende. Das bekomme ich in der Ausgabe nicht weg.

Gäbe es generell noch andere Möglichkeiten?
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@MoonKid: der Aufruf muß

Code: Alles auswählen

import subprocess
subprocess.check_output(['git' ,'log' ,'-n', '1', '--format=%h'])
lauten, und wie man einen Zeilenumbruch in einem String wegbekommt, solltest Du inzwischen wissen. Stringoperationen gehören zu den absoluten Grundlagen; die Lektüre dieser Dokumentation würde ich Dir dringend empfehlen.
MoonKid
User
Beiträge: 105
Registriert: Mittwoch 10. Dezember 2014, 16:24

An den Ton hier im Forum muss ich mich noch gewöhnen und daran, mich selbst konkreter auszudrücken.

Na klar, weiß ich wie man string-Manipulationen macht. Diese Nachbearbeitung wollte ich aber vermeiden und eher herausfinden, wie das '\n' da von subprocess in den String reinkommt und dies verhindern. Versteh die Logik nicht, warum escape-sequencen da mir reinkommen.

Das mit der Parameter-Liste von check_output() habe ich der Doku auch schon entnommen. Der Sinn (in meinem Fall!) war mir aber nicht klar. Ich baue hier ja keinen Aufruf zusammen, sondern der ist statisch. Warum sollte ich ihn also nicht als ganzen String übergeben?

"Das muß so..." ist kein Argument, verschreckt jeden Newbie und ist zudem auch noch unhöflich. Das höre ich hier zu oft, auch bei anderen Themen. Das kenne ich so aus anderen IT-Bereichen (Software, Sprachen, ...) nicht. Selbst auf den berüchtigten unix-Newsgroups war der Ton zwar meist sch...., aber es wurden wenigstens Begründungen oder Links geboten.

Bitte begründen, oder auf relevanten Doku-Teil verlinken. Warum soll ich meinen Aufruf in eine String-Liste zerlegen?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Durch `subprocess` kommt da keine Escapesequenz rein, sondern "git" schliesst seine Ausgabe mit newline ab, wie es das als Konsolenprogramm auch tun sollte. Wenn du das nicht haben willst, dann musst du es eben entfernen.

Das `subprocess` einen String statt einer Liste von Argumenten zu uebergeben, ist keine Frage des Geschmacks, sondern eine Sicherheitsluecke, weil das auch ein `shell=True` nach sich zieht. Darum ist das ein "das muss so". Siehe die ganzen tief roten Abschnitte in der `subprocess` Dokumentation, u.a. hier
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

MoonKid hat geschrieben:Versteh die Logik nicht, warum escape-sequencen da mir reinkommen.
Weil sie mit zur Ausgabe gehören. Ein Fehlen wäre eher überraschend.
MoonKid hat geschrieben:Warum sollte ich ihn also nicht als ganzen String übergeben?
Weil du dich dann nicht mehr selber um das Escapen kümmern brauchst und weil damit unübersichtliches Formatieren gespart wird.
MoonKid hat geschrieben:"Das muß so..." ist kein Argument, verschreckt jeden Newbie und ist zudem auch noch unhöflich. Das höre ich hier zu oft, auch bei anderen Themen.
Doch, das ist ein Argument. Das muss so gemacht werden, weil das dem Interface und dem Zweck des Moduls entspricht. Hättest du die Dokumentation gelesen, dann wäre dir das auch aufgefallen. Da steht ganz oben eine Warnung.
MoonKid hat geschrieben:Bitte begründen, oder auf relevanten Doku-Teil verlinken. Warum soll ich meinen Aufruf in eine String-Liste zerlegen?
In die Dokumentation kannst du doch selber schauen, da steht fast immer drin warum etwas so und nicht anders verwendet werden soll.
Das Leben ist wie ein Tennisball.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

MoonKid hat geschrieben: Bitte begründen, oder auf relevanten Doku-Teil verlinken. Warum soll ich meinen Aufruf in eine String-Liste zerlegen?
Wenn man schon den Ton hier kritisiert, dann sollte man aber imho auch nicht so eine Frage stellen! In der Doku zum ``subprocess`` Modul wird das doch beschrieben! :twisted:

Und die solltest Du ja wohl auch selber gefunden und gelesen haben, oder? ;-)

Ok, nur dritter... aber egal, ich lasse es zur Betonung mal stehen :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
MoonKid
User
Beiträge: 105
Registriert: Mittwoch 10. Dezember 2014, 16:24

cofi hat geschrieben:Siehe die ganzen tief roten Abschnitte in der `subprocess` Dokumentation, u.a. hier
War in meiner 3.4-Doku nicht zu finden. Zugegenbermaßen ist mein Englisch auch nicht das beste und ich habe den exakten Sinn von shell=True/False nicht verstanden. Dachte mir jedoch, dass es hierbei z.B. um Umgebungsvariablen der Shell(bash) geht, weil der Aufruf mit False nicht funktioniert hatte.

Aber Danke, deine Erklärung ist sehr hilfreich. Das Sicherheitsargument verstehe ich sehr gut.

Dann wiederum frage ich mich, warum es überhaupt "meine" Möglichkeit gibt? Könnte man ja auch verhindern mit exceptions (auf string-liste prüfen, auf strings mit leerzeichen prüfen). Aber das stell ich mir wahrscheinlich zu einfach vor. ;)
MoonKid
User
Beiträge: 105
Registriert: Mittwoch 10. Dezember 2014, 16:24

Hyperion hat geschrieben:In der Doku zum ``subprocess`` Modul wird das doch beschrieben!
Nicht mal dort wird es beschrieben, sondern nur auf einen Sicherheitshinweis verlinkt.

Naja, ich lese nicht die gesamte Modul-Doku wenn ich eine Methode daraus brauche. Das shell injection Ding war einfach out-of-my-range.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

MoonKid hat geschrieben:Dann wiederum frage ich mich, warum es überhaupt "meine" Möglichkeit gibt?
Damit man die Möglichkeit hat, falls man sie braucht. Manchmal ist es gewollt, dass die Shell Dinge interpretiert. "*" zum Beispiel, um alle Dateien aufzulisten. Meistens will man das aber nicht.
MoonKid hat geschrieben:Könnte man ja auch verhindern mit exceptions (auf string-liste prüfen, auf strings mit leerzeichen prüfen). Aber das stell ich mir wahrscheinlich zu einfach vor. ;)
Das geht nicht. Dafür müsste das Programm wissen, was du willst und was richtig ist. Wenn das bekannt wäre, dann müsstest du aber kein Programm mehr schreiben, denn damit legst du ja gerade fest, was du möchtest.
MoonKid hat geschrieben:Naja, ich lese nicht die gesamte Modul-Doku wenn ich eine Methode daraus brauche. Das shell injection Ding war einfach out-of-my-range.
Du musst auch nicht alles lesen, sondern nur die relevanten Sachen. Also die Übersichten und den Abschnitt zu der verwendeten Funktionen. Und ersteres hast du halte nicht gelesen. Wenn dann etwas nicht so ist wie erwartet, dann solltest du nicht überrascht sein. Blind Funktionen zu übernehmen, ohne deren komplettes Verhalten zu kennen, ist eben nicht besonders zu empfehlen.
Das Leben ist wie ein Tennisball.
MoonKid
User
Beiträge: 105
Registriert: Mittwoch 10. Dezember 2014, 16:24

Aber mal zurück zur eigentlichen Frage.

Mir ist nämlich grundsätzlich nicht wohl dabei auf die shell zu hüpfen.
Gibt es einen anderen Weg, um die aktuelle git-revision herauszufinden?
GitPython läuft nicht mit Python3. Ist das die einzige git-lib?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Sollte doch für 3.x gehen, steht zumindest hier..
Das Leben ist wie ein Tennisball.
MoonKid
User
Beiträge: 105
Registriert: Mittwoch 10. Dezember 2014, 16:24

Ah es lag mal wieder an den Ubuntu-14.04-reps. Da war noch GitPython0.3.2* drin.
Mit pip3 konnte ich das neuste problemlos installieren.
Antworten