Ich muss ein paar Dateien aus einem riesigen SVN-Repo holen. Es dauert fast eine Stunde, bis das gesamte Repo abgeholt ist. Dateien, die ich suche, sind Teil des Teerbündels.

Ist es möglich, nur diese beiden Dateien aus dem Tar-Bundle abzurufen, ohne das gesamte Bundle über Python Code zu extrahieren?

Wenn ja, kann mich jemand wissen lassen, wie ich vorgehen soll?

1
Rajan Pathak 7 Dez. 2013 im 02:44

3 Antworten

Beste Antwort

Hier ist eine Möglichkeit, eine TAR-Datei von svn abzurufen und eine Datei daraus zu extrahieren:

import tarfile
from subprocess import check_output
# Capture the tar file from subversion
tmp='/home/me/tempfile.tar'
open(tmp, 'wb').write(check_output(["svn", "cat", "svn://url/some.tar"]))
# Extract the file we want, saving to current directory
tarfile.open(tmp).extract('dir1/fname.ext', path='dir2')

Dabei ist 'dir1 / fname.ext' der vollständige Pfad zu der gewünschten Datei im tar-Archiv. Es wird in 'dir2 / dir1 / fname.ext' gespeichert. Wenn Sie das Pfadargument weglassen, wird es in 'dir1 / fname.ext' unter dem aktuellen Verzeichnis gespeichert.

Das Obige kann wie folgt verstanden werden. In einer normalen Shell-Befehlszeile weist svn cat url die Subversion an, die durch url definierte Datei an stdout zu senden (weitere Informationen finden Sie unter svn help cat). url kann eine beliebige Art von URL sein, die svn versteht, z. B. svn://..., svn+ssh://... oder file://.... Wir führen diesen Befehl unter Python-Steuerung mit dem Unterprozessmodul aus. Dazu wird der Befehl svn cat url in eine Liste unterteilt: ["svn", "cat", "url"]. Die Ausgabe dieses Befehls svn wird in einer lokalen Datei gespeichert, die durch die Variable tmp definiert ist. Wir verwenden dann das Tarfile-Modul, um die gewünschte Datei zu extrahieren.

Alternativ können Sie die Extractfile-Methode verwenden, um die Dateidaten in einer Python-Variablen zu erfassen:

handle = t.extractfile('dir1/fname.ext')
print handle.readlines() # show file contents

Gemäß der Dokumentation sollte Tarfile das Standardout eines Unterprozesses als Dateihandle akzeptieren. Dies würde den Code vereinfachen und die Notwendigkeit beseitigen, die TAR-Datei lokal zu speichern. Aufgrund eines Fehlers, Problem 10436, funktioniert dies jedoch nicht.

1
John1024 7 Dez. 2013 im 21:44

Vielleicht willst du so etwas?

#!/usr/local/cpython-3.3/bin/python

import tarfile as tarfile_mod

def main():
    tarfile = tarfile_mod.TarFile('tar-archive.tar', 'r')
    if False:
        file_ = tarfile.extractfile('etc/protocols')
        print(file_.read())
    else:
        tarfile.extract('etc/protocols')
    tarfile.close()

main()
1
dstromberg 6 Dez. 2013 im 22:56

Es hört sich so an, als hätten Sie zwei Teile Ihrer Frage:

  1. Abrufen eines einzelnen Teerbündels aus dem SVN-Repo ohne die restlichen Dateien des Repos.
  2. Verwenden von Python zum Extrahieren von zwei Dateien aus dem abgerufenen Bundle.

Im ersten Teil verweise ich einfach auf diesen Beitrag zu svn export und spärlichen Kassen.

Im zweiten Teil finden Sie eine Lösung zum Extrahieren der beiden Dateien aus dem abgerufenen Tarball:

import tarfile

files_i_want = ['path/to/file1','path/to/file2']

tar = tarfile.open("bundle.tar")
tar.extractall(members=[x for x in tar.getmembers() if x.name in files_i_want])
1
Community 23 Mai 2017 im 11:46