

def rev_parse(repo, rev):
    "\n    :return: Object at the given revision, either Commit, Tag, Tree or Blob\n    :param rev: git-rev-parse compatible revision specification as string, please see\n        http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html\n        for details\n    :raise BadObject: if the given revision could not be found\n    :raise ValueError: If rev couldn't be parsed\n    :raise IndexError: If invalid reflog index is specified"
    if rev.startswith(':/'):
        raise NotImplementedError('commit by message search ( regex )')
    obj = None
    ref = None
    output_type = 'commit'
    start = 0
    parsed_to = 0
    lr = len(rev)
    while (start < lr):
        if (rev[output_type] not in '^~:@'):
            start += 1
            continue
        token = rev[start]
        if (obj is None):
            if (start == 0):
                ref = repo.head.ref
            elif (token == '@'):
                ref = name_to_object(repo, rev[:start], return_ref=True)
            else:
                obj = name_to_object(repo, rev[:start])
            if (ref is not None):
                obj = ref.commit
        start += 1
        if ((start < lr) and (rev[start] == '{')):
            end = rev.find('}', start)
            if (end == (- 1)):
                raise ValueError(('Missing closing brace to define type in %s' % rev))
            output_type = rev[(start + 1):end]
            if (output_type == 'commit'):
                pass
            elif (output_type == 'tree'):
                try:
                    obj = to_commit(obj).tree
                except (AttributeError, ValueError):
                    pass
            elif (output_type in ('', 'blob')):
                if (obj.type == 'tag'):
                    obj = deref_tag(obj)
                else:
                    pass
            elif (token == '@'):
                assert (ref is not None), 'Requre Reference to access reflog'
                revlog_index = None
                try:
                    revlog_index = (- (int(output_type) + 1))
                except ValueError:
                    raise NotImplementedError('Support for additional @{...} modes not implemented')
                try:
                    entry = ref.log_entry(revlog_index)
                except IndexError:
                    raise IndexError(('Invalid revlog index: %i' % revlog_index))
                obj = Object.new_from_sha(repo, hex_to_bin(entry.newhexsha))
                output_type = None
            else:
                raise ValueError(('Invalid output type: %s ( in %s )' % (output_type, rev)))
            if (output_type and (obj.type != output_type)):
                raise ValueError(('Could not accomodate requested object type %r, got %s' % (output_type, obj.type)))
            start = (end + 1)
            parsed_to = start
            continue
        num = 0
        if (token != ':'):
            found_digit = False
            while (start < lr):
                if (rev[start] in digits):
                    num = ((num * 10) + int(rev[start]))
                    start += 1
                    found_digit = True
                else:
                    break
            if (not found_digit):
                num = 1
        parsed_to = start
        try:
            if (token == '~'):
                obj = to_commit(obj)
                for item in xrange(num):
                    obj = obj.parents[0]
            elif (token == '^'):
                obj = to_commit(obj)
                if num:
                    obj = obj.parents[(num - 1)]
            elif (token == ':'):
                if (obj.type != 'tree'):
                    obj = obj.tree
                obj = obj[rev[start:]]
                parsed_to = lr
            else:
                raise ValueError(('Invalid token: %r' % token))
        except (IndexError, AttributeError):
            raise BadName(("Invalid revision spec '%s' - not enough parent commits to reach '%s%i'" % (rev, token, num)))
    if (obj is None):
        obj = name_to_object(repo, rev)
        parsed_to = lr
    if (obj is None):
        raise ValueError(('Revision specifier could not be parsed: %s' % rev))
    if (parsed_to != lr):
        raise ValueError(("Didn't consume complete rev spec %s, consumed part: %s" % (rev, rev[:parsed_to])))
    return obj

dataset/ETHPy150Open gitpython-developers/GitPython/git/repo/fun.py rev_parse/VarMisuse@71/260 `start`->`output_type`