Hardik Topiwala
Hardik Topiwala

Reputation: 11

How to archive a remote git repository programmatically using Python?

I am trying to archive a remote git repo using Python code. I did it successfully using Git command line with following command.

> git archive --format=zip --remote=ssh://path/to/my/repo -o archived_file.zip     
HEAD:path/to/directory filename

This command fetches the required file from the repo and stores the zip in my current working directory. Note that there is no cloning of remote repo happening.

Now I have to do it using Python code. I am using GitPython 1.0.1. I guess if it is doable using command line then it should be doable using GitPython library. According to the docs,

repo.archive(open(join(rw_dir, 'archived_file.zip'), 'wb'))

Above line of code will archive the repo. Here repo is the instance of Repo class. It can be initialized using

repo = Repo('path to the directory which has .git folder')

If I give path to my remote repo(Ex. ssh://path/to/my/repo) in above line it goes to find it in directory where the .py file containing this code is residing(Like, Path\to\python\file\ssh:\path\to\my\repo), which is not what I want. So to sum up I can archive a local repo but not a remote one using GitPython. I may be able to archive remote repo if I am able to create a repo instance pointing to the remote repo. I am very new to Git and Python.

Is there any way to archive a remote repo using Python code without cloning it in local?

Upvotes: 1

Views: 2114

Answers (1)

Henrik
Henrik

Reputation: 2229

This is by the way a terrible idea, since you already have begun using gitpython, and I have never tried working with that, but I just really want to let you know, that you can do it without cloning it in local, without using gitpython.

Simply run the git command, in a shell, using subprocess.. running bash commands in python


edit: added some demonstration code, of reading stdout and writing stdin.

some of this is stolen from here: http://eyalarubas.com/python-subproc-nonblock.html

The rest is a small demo.. first two prerequisites

shell.py

import sys
while True:
    s = raw_input("Enter command: ")
    print "You entered: {}".format(s)
    sys.stdout.flush()

nbstreamreader.py:

from threading import Thread
from Queue import Queue, Empty

class NonBlockingStreamReader:

    def __init__(self, stream):
        '''
        stream: the stream to read from.
                Usually a process' stdout or stderr.
        '''

        self._s = stream
        self._q = Queue()

        def _populateQueue(stream, queue):
            '''
            Collect lines from 'stream' and put them in 'quque'.
            '''

            while True:
                line = stream.readline()
                if line:
                    queue.put(line)
                else:
                    raise UnexpectedEndOfStream

        self._t = Thread(target = _populateQueue,
                args = (self._s, self._q))
        self._t.daemon = True
        self._t.start() #start collecting lines from the stream

    def readline(self, timeout = None):
        try:
            return self._q.get(block = timeout is not None,
                    timeout = timeout)
        except Empty:
            return None

class UnexpectedEndOfStream(Exception): pass

then the actual code:

from subprocess import Popen, PIPE
from time import sleep
from nbstreamreader import NonBlockingStreamReader as NBSR

# run the shell as a subprocess:
p = Popen(['python', 'shell.py'],
        stdin = PIPE, stdout = PIPE, stderr = PIPE, shell = False)
# wrap p.stdout with a NonBlockingStreamReader object:
nbsr = NBSR(p.stdout)
# issue command:
p.stdin.write('command\n')
# get the output
i = 0
while True:
    output = nbsr.readline(0.1)
    # 0.1 secs to let the shell output the result
    if not output:
        print "time out the response took to long..."
        #do nothing, retry reading..
        continue
    if "Enter command:" in output:
        p.stdin.write('try it again' + str(i) + '\n')
        i += 1
    print output

Upvotes: 1

Related Questions