'Yield the object type, and then an iterator over the data referred
to by the id ref.  If size is true, yield (obj_type, obj_size)
instead of just the type.'

def get(self, id, size=False):

    if ((not self.p) or (self.p.poll() != None)):
        self.restart()
    assert self.p
    poll_result = self.p.poll()
    assert (poll_result == None)
    if self.inprogress:
        log(('get:    opening    %r    while    %r    is    open\n' % (id, self.inprogress)))
    assert (not self.inprogress)
    assert (id.find('\n') < 0)
    assert (id.find('\r') < 0)
    assert (not id.startswith('-'))
    self.inprogress = id
    self.p.stdin.write(('%s\n' % id))
    self.p.stdin.flush()
    hdr = self.p.stdout.readline()
    if hdr.endswith('    missing\n'):
        self.inprogress = None
        raise MissingObject(id.decode('hex'))
    spl = hdr.split('    ')
    if ((len(spl) != 3) or (len(spl[0]) != 40)):
        raise GitError(('expected    blob,    got    %r' % spl))
    (hex, typ, sz) = spl
    sz = int(sz)
    it = _AbortableIter(chunkyreader(self.p.stdout, sz), onabort=self._abort)
    try:
        if size:
            (yield (typ, sz))
        else:
            (yield typ)
        for blob in it:
            (yield blob)
        readline_result = self.p.stdout.readline()
        assert (readline_result == '\n')
        self.inprogress = None
    except Exception as e:
        it.abort()
        raise
