Wollten Sie schon immer ein Modul in Python erstellen, das git
verwendet?
Ich habe. Dies ist ein laufendes Projekt.
Dieses Mal werde ich also mit dem Thema ** Parsing Gits Commit-Protokoll mit Python ** schreiben.
Um ein Modul zu verwenden, das git verwendet, müssen Sie zuerst die Ausgabe des Befehls git abrufen. Erstellen wir also eine Git-Funktion, die die Ausgabe des Befehls git mithilfe des Subprozessmoduls abruft.
git.py
from subprocess import Popen, PIPE
class GitError(BaseException):
"""Tritt auf, wenn ein Fehler im Erfassungsergebnis der Git-Funktion auftritt"""
pass
def git(cmd, *args):
"""Holen Sie sich das Ausführungsergebnis von git und geben Sie es zurück"""
proc = Popen(
("git", cmd) + args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
out, err = proc.communicate()
if len(err) == 0:
return out[:-1]
else:
raise GitError(err)
Um den Inhalt der Funktion kurz zu erläutern (Zeilennummern in Klammern), importieren Sie die Variablen "Popen" und "PIPE" aus dem Unterprozessmodul (1) und definieren Sie den Prozess von "git" mit der Funktion "Popen". (8 ~ 9) Führt den Prozess aus, der durch die ** communic ** -Methode der Popen-Klasse definiert wurde. Bei der Ausführung ** werden das Ausgabeergebnis der Standardausgabe und das Ausgabeergebnis des Standardfehlers in einem Taple zurückgegeben **, sodass das Ausgabeergebnis der Standardausgabe und das Ausgabeergebnis des Standardfehlers mit der Variablen out und der Variablen err erfasst werden. .. (10) Überprüfen Sie danach, ob ein Standardfehler vorliegt, und wenn ja, "GitError" Erhöhen Sie die Klasse. Wenn nicht, wird das Standardausgabeergebnis unverändert zurückgegeben.
Es ist ungefähr so. Als nächstes rufen wir das Commit-Protokoll mit dieser Git-Funktion ab.
Vorher habe ich noch etwas zu tun. Erstellen Sie eine Commit-Klasse **, in der die analysierten ** Commit-Protokolle gespeichert sind.
commit.py
class Commit(object):
"""Klasse, die den Hashwert von Commit, Autor, Datum und Uhrzeit, Commit-Kommentar und zusammengeführten Daten enthält, wenn diese zusammengeführt werden"""
def __init__(self, commithash, author, date, comment, merge_data=None):
self.commithash = commithash
self.author = self._get_user_obj(author)
self.date = date
self.comment = comment
self.merge_data = merge_data
def _get_user_obj(self, author_string):
if " " in author_string:
lines = author_string.split(" ")
name = lines[0]
email = lines[1][1:-1]
return User(name, email)
else:
return User(author_string)
def __repr__(self):
return "CommitObject(%s)" % self.commithash
Erstellen Sie eine Klasse, die von der integrierten Objektklasse erbt.
Die Daten, die das Commit-Objekt enthalten soll, sind
Diese sind. Die Methode __init__
nimmt also jedes als Argument und bewertet die Self-Klasse.
Die Methode "_get_user_obj" fügt die Committer-Informationen ursprünglich als "Author [email protected]" in das Commit-Objekt ein. Die Rolle besteht also darin, diese Zeichenfolge in die Informationen "Autor" und "E-Mail" zu unterteilen. Die Klasse, die diese beiden Informationen enthält, ist die Klasse ** User **.
user.py
class User(object):
"""Behalten Sie den Namen und die E-Mail-Adresse des Committers"""
def __init__(self, name, email=None):
self.name = name
self.email = email
def __repr__(self):
return "UserObject(name='%s', email='%s')" % (
self.name, self.email)
def __str__(self):
return self.__repr__()
Diese Klasse ist einfach. Es ist nur eine Klasse für den Autor, E-Mails zu speichern.
Beginnen wir zuerst mit dem Code.
parser.py
from dateutil import parser as dateparser
def get_commits():
"""Holen Sie sich das Commit-Protokoll aus der Shell, machen Sie es zu einem Commit-Objekt und geben Sie es als Liste zurück"""
commits = []
commits_string = git("log")
# analyzing
commitlines = commits_string.split("\n\n")
commits_string_list = []
while 0 < len(commitlines):
commits_string_list.append(
"\n".join(commitlines[0:2]))
commitlines = commitlines[2:]
# parse
for commitline in commits_string_list:
commitdata = parse_commit(commitline)
commits.append(
Commit(**commitdata))
return commits
def parse_commit():
"""Analysiert das von der Shell erhaltene Festschreibungsprotokoll und gibt den Festschreibungs-Hashwert, den Festschreiber, das Datum / die Uhrzeit, den Festschreibungskommentar sowie die Quelle und das Ziel zurück, wenn diese zusammengeführt werden"""
commitlines = commitstring.split("\n")
# 1 row
commithash = commitlines[0].replace("commit ","")
# 2 row
merge_source = merge_dest = None
author = None
if "Merge" in commitlines[1]:
# parse merge data
merge_source = commitlines[1].split(" ")[1]
merge_dest = commitlines[1].split(" ")[2]
else:
# parse author
author = commitlines[1].replace("Author: ","")
# 3 row
if "Author" in commitlines[2]:
# parse author
author = commitlines[2].replace("Author: ","")
else:
# parse date
date = dateparser.parse(commitlines[2].replace("Date: ",""))
# 4 row
if "Date" in commitlines[3]:
# parse date
date = dateparser.parse(commitlines[3].replace("Date: ",""))
else:
# parse comment
comment = " ".join([i.strip() for i in commitlines[3:]])
# 5 row
if "Merge" in commitlines[1]:
# comment -> under 4 row
comment = " ".join([i.strip() for i in commitlines[4:]])
return {"commithash": commithash,
"merge_data": (merge_source, merge_dest) if merge_source != None else None,
"author" : author,
"date" : date,
"comment" : comment}
commit c92b57f9418eddf75cd96e268bac616aaecd95c4
Merge: 46a71a7 137a6ca
Author: alice <[email protected]>
Date: Sat Nov 17 01:00:14 2012 +0900
Merge branch 'rewrite'
Conflicts:
commithash.py
Ein normales Festschreibungsprotokoll sieht wie oben aus. (Version mit Zusammenführung) Der obige Parser ist ein Skript, das dieses Festschreibungsprotokoll zeilenweise auswertet und den Hashwert und die Zusammenführungsdaten des Festschreibens, das Datum / die Uhrzeit im Committer und den Festschreibungskommentar abruft. Es ist sehr ärgerlich, Zeile für Zeile zu erklären, also lassen Sie es mich weglassen ... Nun, Sie können es verstehen, indem Sie den Code lesen. Ich habe noch nichts so fortgeschrittenes gemacht.
Wie Sie mit diesen Festschreibungsdaten umgehen, liegt bei Ihnen! !!
Recommended Posts