python - mit - linux terminal übungen




Wie kann ich "git pull" aus Python heraus aufrufen? (4)

Die akzeptierte Antwort mit https://github.com/gitpython-developers/GitPython ist wenig besser als die direkte Verwendung eines subprocess .

Das Problem bei diesem Ansatz besteht darin, dass Sie, wenn Sie die Ausgabe analysieren möchten, am Ende das Ergebnis eines Befehls "Porzellan" betrachten, was eine schlechte Idee ist

Wenn Sie GitPython auf diese Weise verwenden, ist es so, als würden Sie eine glänzende neue Toolbox erhalten und sie dann für den Haufen Schrauben verwenden, der sie zusammenhält, anstatt die Werkzeuge im Inneren. So wurde die API für die Verwendung entworfen:

import git
repo = git.Repo('Path/to/repo')
repo.remotes.origin.pull()

Wenn Sie prüfen möchten, ob sich etwas geändert hat, können Sie verwenden

current = repo.head.commit
repo.remotes.origin.pull()
if current != repo.head.commit:
    print("It changed")

Mit den Webhooks von Github möchte ich Änderungen auf einen Remote-Entwicklungsserver übertragen. Im Moment, wenn sich das entsprechende Verzeichnis im richtigen Verzeichnis befindet, erhält git pull alle erforderlichen Änderungen. Ich kann jedoch nicht herausfinden, wie ich diese Funktion in Python aufrufen kann. Ich habe folgendes versucht:

import subprocess
process = subprocess.Popen("git pull", stdout=subprocess.PIPE)
output = process.communicate()[0]

Dies führt jedoch zu dem folgenden Fehler

Traceback (letzter Aufruf zuletzt): Datei "", Zeile 1, in Datei "/usr/lib/python2.7/subprocess.py", Zeile 679, in init errread, errwrite) Datei "/ usr / lib / python2. 7 / subprocess.py ", Zeile 1249, in _execute_child Rise child_exception OSError: [Errno 2] Keine solche Datei oder Verzeichnis

Gibt es eine Möglichkeit, diesen bash-Befehl in Python aufzurufen?


Dies ist ein Beispielrezept, das ich in einem meiner Projekte verwendet habe. Vereinbart, dass es mehrere Möglichkeiten gibt, dies zu tun. :)

>>> import subprocess, shlex
>>> git_cmd = 'git status'
>>> kwargs = {}
>>> kwargs['stdout'] = subprocess.PIPE
>>> kwargs['stderr'] = subprocess.PIPE
>>> proc = subprocess.Popen(shlex.split(git_cmd), **kwargs)
>>> (stdout_str, stderr_str) = proc.communicate()
>>> return_code = proc.wait()

>>> print return_code
0

>>> print stdout_str
# On branch dev
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   file1
#   file2
nothing added to commit but untracked files present (use "git add" to track)

>>> print stderr_str

Das Problem mit Ihrem Code war, dass Sie kein Array für subprocess.Popen() und daher versucht haben, eine einzelne Binärdatei namens git pull auszuführen. Stattdessen muss das binäre git wobei das erste Argument pull usw. ist.


Versuchen:

subprocess.Popen("git pull", stdout=subprocess.PIPE, shell=True)

subprocess.Popen erwartet eine Liste des Programmnamens und der Argumente. Sie übergeben eine einzelne Zeichenkette, die (mit der Standardshell shell=False ) gleichwertig ist zu:

['git pull']

Das bedeutet, dass der Unterprozess versucht, ein Programm mit dem Namen wörtlich git pull , was nicht der FileNotFoundError: [Errno 2] No such file or directory: 'git pull' In Python 3.3 löst der Code die Ausnahme aus FileNotFoundError: [Errno 2] No such file or directory: 'git pull' . Übergeben Sie stattdessen eine Liste wie diese:

import subprocess
process = subprocess.Popen(["git", "pull"], stdout=subprocess.PIPE)
output = process.communicate()[0]

In Python 2.7 und höher können Sie diesen Code check_output mit der check_output check_output vereinfachen:

import subprocess
output = subprocess.check_output(["git", "pull"])

Um die Git-Funktionalität zu nutzen, ist es keinesfalls notwendig (wenn auch einfach und portabel), die Git-Binärdatei aufzurufen. Erwägen Sie die Verwendung von https://github.com/gitpython-developers/GitPython oder Dulwich .





github