Exemplo n.º 1
0
def is_modified(name, git=git):
    status, out = git.diff('--', name,
                           name_only=True,
                           exit_code=True,
                           with_status=True,
                           **_common_diff_opts())
    return status != 0
Exemplo n.º 2
0
def diff_upstream(head):
    tracked = tracked_branch()
    if not tracked:
        return []
    diff_expr = merge_base_to(head, tracked)
    output = git.diff(diff_expr, name_only=True, z=True,
                      **_common_diff_opts())
    if output.startswith('fatal:'):
        return []
    return [core.decode(n) for n in output.split('\0') if n]
Exemplo n.º 3
0
def _branch_status(branch, git=git):
    """
    Returns a tuple of staged, unstaged, untracked, and unmerged files

    This shows only the changes that were introduced in branch

    """
    status, output = git.diff(name_only=True,
                              M=True, z=True,
                              with_status=True,
                              *branch.strip().split(),
                              **_common_diff_opts())
    if status != 0:
        return {}

    staged = map(core.decode, [n for n in output.split('\0') if n])
    return {'staged': staged,
            'upstream_changed': staged}
Exemplo n.º 4
0
def changed_files(start, end, git=git):
    zfiles_str = git.diff('%s..%s' % (start, end),
                          name_only=True, z=True,
                          **_common_diff_opts()).strip('\0')
    return [core.decode(enc) for enc in zfiles_str.split('\0') if enc]
Exemplo n.º 5
0
def renamed_files(start, end, git=git):
    difflines = git.diff('%s..%s' % (start, end), M=True,
                         **_common_diff_opts()).splitlines()
    return [eval_path(r[12:].rstrip())
                for r in difflines if r.startswith('rename from ')]
Exemplo n.º 6
0
def diff_filenames(arg, git=git):
    """Return a list of filenames that have been modified"""
    diff_zstr = git.diff(arg, name_only=True, z=True,
                         **_common_diff_opts()).rstrip('\0')
    return [core.decode(f) for f in diff_zstr.split('\0') if f]
Exemplo n.º 7
0
def diff_helper(commit=None,
                branch=None,
                ref=None,
                endref=None,
                filename=None,
                cached=True,
                with_diff_header=False,
                suppress_header=True,
                reverse=False,
                git=git):
    "Invokes git diff on a filepath."
    if commit:
        ref, endref = commit+'^', commit
    argv = []
    if ref and endref:
        argv.append('%s..%s' % (ref, endref))
    elif ref:
        for r in ref.strip().split():
            argv.append(r)
    elif branch:
        argv.append(branch)

    if filename:
        argv.append('--')
        if type(filename) is list:
            argv.extend(filename)
        else:
            argv.append(filename)

    start = False
    del_tag = 'deleted file mode '

    headers = []
    deleted = cached and not os.path.exists(core.encode(filename))

    diffoutput = git.diff(R=reverse, M=True, cached=cached,
                          *argv, **_common_diff_opts())
    # Handle 'git init'
    if diffoutput.startswith('fatal:'):
        if with_diff_header:
            return ('', '')
        else:
            return ''

    if diffoutput.startswith('Submodule'):
        if with_diff_header:
            return ('', diffoutput)
        else:
            return diffoutput

    output = StringIO()

    diff = diffoutput.split('\n')
    for line in map(core.decode, diff):
        if not start and '@@' == line[:2] and '@@' in line[2:]:
            start = True
        if start or (deleted and del_tag in line):
            output.write(core.encode(line) + '\n')
        else:
            if with_diff_header:
                headers.append(core.encode(line))
            elif not suppress_header:
                output.write(core.encode(line) + '\n')

    result = core.decode(output.getvalue())
    output.close()

    if with_diff_header:
        return('\n'.join(headers), result)
    else:
        return result
Exemplo n.º 8
0
def sha1_diff(sha1, git=git):
    return core.decode(git.diff(sha1 + '^!', **_common_diff_opts()))
Exemplo n.º 9
0
def worktree_state_dict(head='HEAD',
                        staged_only=False,
                        update_index=False,
                        git=git):
    """Return a dict of files in various states of being

    :rtype: dict, keys are staged, unstaged, untracked, unmerged,
            changed_upstream, and submodule.

    """
    if update_index:
        git.update_index(refresh=True)

    if staged_only:
        return _branch_status(head)

    staged_set = set()
    modified_set = set()

    staged = []
    modified = []
    unmerged = []
    untracked = []
    upstream_changed = []
    submodules = set()
    try:
        output = git.diff_index(head, cached=True, with_stderr=True)
        if output.startswith('fatal:'):
            raise errors.GitInitError('git init')
        for line in output.splitlines():
            rest, name = line.split('\t', 1)
            status = rest[-1]
            name = eval_path(name)
            if '160000' in rest[1:14]:
                submodules.add(name)
            if status  == 'M':
                staged.append(name)
                staged_set.add(name)
                # This file will also show up as 'M' without --cached
                # so by default don't consider it modified unless
                # it's truly modified
                modified_set.add(name)
                if not staged_only and is_modified(name):
                    modified.append(name)
            elif status == 'A':
                staged.append(name)
                staged_set.add(name)
            elif status == 'D':
                staged.append(name)
                staged_set.add(name)
                modified_set.add(name)
            elif status == 'U':
                unmerged.append(name)
                modified_set.add(name)

    except errors.GitInitError:
        # handle git init
        staged.extend(all_files())

    try:
        output = git.diff_index(head, with_stderr=True)
        if output.startswith('fatal:'):
            raise errors.GitInitError('git init')
        for line in output.splitlines():
            rest , name = line.split('\t', 1)
            status = rest[-1]
            name = eval_path(name)
            if '160000' in rest[1:13]:
                submodules.add(name)
            if status == 'M' or status == 'D':
                if name not in modified_set:
                    modified.append(name)
            elif status == 'A':
                # newly-added yet modified
                if (name not in modified_set and not staged_only and
                        is_modified(name)):
                    modified.append(name)

    except errors.GitInitError:
        # handle git init
        ls_files = git.ls_files(modified=True, z=True)[:-1].split('\0')
        modified.extend(map(core.decode, [f for f in ls_files if f]))

    untracked.extend(untracked_files())

    # Look for upstream modified files if this is a tracking branch
    tracked = tracked_branch()
    if tracked:
        try:
            diff_expr = merge_base_to(tracked)
            output = git.diff(diff_expr, name_only=True, z=True,
                              **_common_diff_opts())

            if output.startswith('fatal:'):
                raise errors.GitInitError('git init')

            for name in [n for n in output.split('\0') if n]:
                name = core.decode(name)
                upstream_changed.append(name)

        except errors.GitInitError:
            # handle git init
            pass

    # Keep stuff sorted
    staged.sort()
    modified.sort()
    unmerged.sort()
    untracked.sort()
    upstream_changed.sort()

    return {'staged': staged,
            'modified': modified,
            'unmerged': unmerged,
            'untracked': untracked,
            'upstream_changed': upstream_changed,
            'submodules': submodules}
Exemplo n.º 10
0
def sha1_diff(sha1, git=git):
    return git.diff(sha1 + '^!', **_common_diff_opts())