def unstage_paths(args, head='HEAD'): status, output = git.reset(head, '--', with_stderr=True, with_status=True, *set(args)) if status != 128: return (status, output) # handle git init: we have to use 'git rm --cached' # detect this condition by checking if the file is still staged status, output = git.update_index('--', force_remove=True, with_status=True, with_stderr=True, *set(args)) return (status, output)
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, unmerged, submodules = diff_index(head) modified, more_submods = diff_worktree() submodules = submodules.union(more_submods) untracked = untracked_files() # Look for upstream modified files if this is a tracking branch upstream_changed = diff_upstream(head) # 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}
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}