Example #1
0
def diff_worktree():
    modified = []
    submodules = set()

    output = git.diff_files(z=True, with_stderr=True)
    if output.startswith('fatal:'):
        # handle git init
        ls_files = git.ls_files(modified=True, z=True)[:-1].split('\0')
        modified = [core.decode(f) for f in ls_files if f]
        return modified, submodules

    while output:
        rest, output = output.split('\0', 1)
        name, output = output.split('\0', 1)
        status = rest[-1]
        name = core.decode(name)
        if '160000' in rest[1:14]:
            submodules.add(name)
        elif status in 'DAM':
            modified.append(name)

    return modified, submodules
Example #2
0
def untracked_files(git=git):
    """Returns a sorted list of untracked files."""
    ls_files = git.ls_files(z=True,
                            others=True,
                            exclude_standard=True)
    return [core.decode(f) for f in ls_files.split('\0') if f]
Example #3
0
def all_files(git=git):
    """Return the names of all files in the repository"""
    return [core.decode(f)
            for f in git.ls_files(z=True)
                        .strip('\0').split('\0') if f]
Example #4
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}