How to archive a remote git repository programmatically using Python?
Question: 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](http://gitpython.readthedocs.org/en/latest/tutorial.html#meet-the-repo-
type),

    
    
    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?


Answer: 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](http://stackoverflow.com/questions/4256107/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
    

