Git

This module provides basic functionality to interact with git. It comes in handy when writing deployment scripts.

Interacting with a repository

All repository interactions are done through the Repo class and its methods. If an interaction fails, a GitError is raised.

class yuio.git.Repo(path: Path | str, /, env: dict[str, str] | None = None)

A class that allows interactions with a git repository.

Parameters:
  • path – path to the repo root dir.

  • env – environment variables for the git executable.

Raises:

constructor of this class may raise GitError if git isn’t available or if the given part is not inside of a git repository.

property path: Path

Path to the repo, as was passed to the constructor.

property root: Path

The root directory of the repo.

property git_dir: Path

Get path to the .git directory of the repo.

git(*args: str | Path, capture_io: bool = True)

Call git and return its stdout.

Parameters:
  • args – arguments for the git command.

  • capture_io – If set to False, command’s stderr and stdout are not captured.

Returns:

output of the git command.

Raises:

GitError, OSError.

status(
include_ignored: bool = False,
include_submodules: bool = True,
) Status

Query the current repository status.

Parameters:
  • include_ignored – include ignored status in the list of changes. Disable by default.

  • include_submodules – include status of submodules in the list of changes. Enabled by default.

Returns:

current repository status.

Raises:

GitError, OSError.

print_status()

Run git status and show its output to the user.

log(*refs: str, max_entries: int | None = None) list[Commit]

Query the log for given git objects.

Parameters:
  • refs – git references that will be passed to git log.

  • max_entries – maximum number of returned references.

Returns:

list of found commits.

Raises:

GitError, OSError.

trailers(
*refs: str,
max_entries: int | None = None,
) list[CommitTrailers]

Query trailer lines for given git objects.

Trailers are lines at the end of a commit message formatted as key: value pairs. See git-interpret-trailers for further description.

Parameters:
  • refs – git references that will be passed to git log.

  • max_entries

    maximum number of checked commits.

    Warning

    This option limits number of checked commits, not the number of trailers.

Returns:

list of found commits and their trailers.

Raises:

GitError, OSError.

show(ref: str, /) Commit | None

Query information for the given git object.

Return None if object is not found.

Parameters:

ref – git reference that will be passed to git log.

Returns:

found commit or None.

Raises:

OSError.

tags() list[str]

List all tags in this repository.

Returns:

list of strings representing tags, without refs/tags prefix, sorted lexicographically as strings.

Raises:

GitError, OSError.

branches() list[str]

List all branches in this repository.

Returns:

list of strings representing branch names, without refs/heads prefix, sorted lexicographically as strings.

Raises:

GitError, OSError.

remotes() list[str]

List all remote branches in this repository.

Returns:

list of strings representing remote branches, without refs/remotes prefix, sorted lexicographically as strings.

Raises:

GitError, OSError.

class yuio.git.GitError

Raised when interaction with git fails.

class yuio.git.GitExecError(returncode, cmd, output=None, stderr=None)

Raised when git returns a non-zero exit code.

class yuio.git.GitUnavailableError

Raised when git executable can’t be found.

class yuio.git.NotARepositoryError

Raised when given path is not in git repository.

Status objects

Repo.status() returns repository status parsed from git status command. It can show changed and unmerged files and submodules. See details about change representation in git status manual.

Yuio represents git status output as close to the original as possible, but makes some convenience renames. This results in somewhat unexpected class structure:

---
config:
    class:
        hideEmptyMembersBox: true
---
classDiagram

class PathStatus
click PathStatus href "#yuio.git.PathStatus" "yuio.git.PathStatus"

class FileStatus
click FileStatus href "#yuio.git.FileStatus" "yuio.git.FileStatus"
PathStatus <|-- FileStatus

class SubmoduleStatus
click SubmoduleStatus href "#yuio.git.SubmoduleStatus" "yuio.git.SubmoduleStatus"
FileStatus <|-- SubmoduleStatus

class UnmergedFileStatus
click UnmergedFileStatus href "#yuio.git.UnmergedFileStatus" "yuio.git.UnmergedFileStatus"
PathStatus <|-- UnmergedFileStatus

class UnmergedSubmoduleStatus
click UnmergedSubmoduleStatus href "#yuio.git.UnmergedSubmoduleStatus" "yuio.git.UnmergedSubmoduleStatus"
UnmergedFileStatus <|-- UnmergedSubmoduleStatus

class yuio.git.Status(
*,
commit: str | None,
branch: str | None = None,
upstream: str | None = None,
ahead: int | None = None,
behind: int | None = None,
changes: list[PathStatus] = <factory>,
cherry_pick_head: str | None = None,
merge_head: str | None = None,
rebase_head: str | None = None,
revert_head: str | None = None,
bisect_start: str | None = None,
)

Status of a working copy.

commit: str | None

Current commit hash. Can be absent if current branch is orphaned and doesn’t have any commits yet.

branch: str | None

Name of the current branch.

upstream: str | None

Name of the upstream branch.

ahead: int | None

Number of commits the branch is ahead of upstream.

behind: int | None

Number of commits the branch is behind of upstream.

changes: list[PathStatus]

List of changed files, both tracked and untracked.

See details about change representation in git status manual.

cherry_pick_head: str | None

Position of the CHERRY_PICK_HEAD.

If this field is not None, cherry pick is in progress.

merge_head: str | None

Position of the MERGE_HEAD.

If this field is not None, merge is in progress.

rebase_head: str | None

Position of the REBASE_HEAD.

If this field is not None, rebase is in progress.

revert_head: str | None

Position of the REVERT_HEAD.

If this field is not None, revert is in progress.

bisect_start: str | None

Position of the BISECT_START.

If this field is not None, bisect is in progress.

has_staged_changes() bool

Return True if there are unstaged changes in this repository.

get_staged_changes() Iterator[PathStatus]

Return iterator over all unstaged changes in this repository.

has_unstaged_changes() bool

Return True if there are unstaged changes in this repository.

get_unstaged_changes() Iterator[PathStatus]

Return iterator over all staged changes in this repository.

has_ongoing_operation() bool

Return True if there is an ongoing operation such as merge or rebase.

get_ongoing_operation() Literal['cherry_pick', 'merge', 'rebase', 'revert', 'bisect'] | None

Return name of an ongoing operation such as merge or rebase, if there is one.

class yuio.git.PathStatus(*, path: Path)

Status of a changed path.

path: Path

Path of the file.

class yuio.git.FileStatus(
*,
path: Path,
path_from: Path | None,
staged: Modification,
tree: Modification,
)

Status of a changed file.

path_from: Path | None

If file was moved, contains path where it was moved from.

staged: Modification

File modification in the index (staged).

tree: Modification

File modification in the tree (unstaged).

class yuio.git.SubmoduleStatus(
*,
path: Path,
path_from: Path | None,
staged: Modification,
tree: Modification,
commit_changed: bool,
has_tracked_changes: bool,
has_untracked_changes: bool,
)

Status of a submodule.

commit_changed: bool

The submodule has a different HEAD than recorded in the index.

has_tracked_changes: bool

Tracked files were changed in the submodule.

has_untracked_changes: bool

Untracked files were changed in the submodule.

class yuio.git.UnmergedFileStatus(
*,
path: Path,
us: Modification,
them: Modification,
)

Status of an unmerged file.

us: Modification

File modification that has happened at the head.

them: Modification

File modification that has happened at the merge head.

class yuio.git.UnmergedSubmoduleStatus(
*,
path: Path,
us: Modification,
them: Modification,
commit_changed: bool,
has_tracked_changes: bool,
has_untracked_changes: bool,
)

Status of an unmerged submodule.

commit_changed: bool

The submodule has a different HEAD than recorded in the index.

has_tracked_changes: bool

Tracked files were changed in the submodule.

has_untracked_changes: bool

Untracked files were changed in the submodule.

class yuio.git.Modification(*values)

For changed file or submodule, what modification was applied to it.

UNMODIFIED = '.'

File wasn’t changed.

MODIFIED = 'M'

File was changed.

SUBMODULE_MODIFIED = 'm'

Contents of submodule were modified.

TYPE_CHANGED = 'T'

File type changed.

ADDED = 'A'

File was created.

DELETED = 'D'

File was deleted.

RENAMED = 'R'

File was renamed (and possibly changed).

COPIED = 'C'

File was copied (and possibly changed).

UPDATED = 'U'

File was updated but unmerged.

UNTRACKED = '?'

File is untracked, i.e. not yet staged or committed.

IGNORED = '!'

File is in .gitignore.

Commit objects

class yuio.git.Commit(
*,
hash: str,
tags: list[str],
author: str,
author_email: str,
author_datetime: datetime,
committer: str,
committer_email: str,
committer_datetime: datetime,
title: str,
body: str,
orig_ref: str | None = None,
)

Commit description.

hash: str

Commit hash.

tags: list[str]

Tags attached to this commit.

author: str

Author name.

author_email: str

Author email.

author_datetime: datetime

Author time.

committer: str

Committer name.

committer_email: str

Committer email.

committer_datetime: datetime

Committer time.

title: str

Commit title, i.e. first line of the message.

body: str

Commit body, i.e. the rest of the message.

orig_ref: str | None

If commit was parsed from a user input, this field will contain original input. I.e. if a user enters HEAD and it gets resolved into a commit, orig_ref will contain string "HEAD".

See also CommitParser.

property short_hash

First seven characters of the commit hash.

class yuio.git.CommitTrailers(*, hash: str, trailers: list[tuple[str, str]])

Commit trailers.

hash: str

Commit hash.

trailers: list[tuple[str, str]]

Key-value pairs for commit trailers.

Parsing git refs

When you need to query a git ref from a user, RefParser will check that the given ref is formatted correctly. Use Ref in your type hints to help Yuio detect that you want to parse it as a git reference:

class yuio.git.Ref

A special kind of string that contains a git object reference.

Ref is not guaranteed to be valid; this type is used in type hints to make use of the RefParser.

alias of str

class yuio.git.Tag

A special kind of string that contains a tag name.

Ref is not guaranteed to be valid; this type is used in type hints to make use of the TagParser.

alias of str

class yuio.git.Branch

A special kind of string that contains a branch name.

Ref is not guaranteed to be valid; this type is used in type hints to make use of the BranchParser.

alias of str

class yuio.git.Remote

A special kind of string that contains a remote branch name.

Ref is not guaranteed to be valid; this type is used in type hints to make use of the RemoteParser.

alias of str

class yuio.git.RefParser

A parser that provides autocompletion for git refs, but doesn’t verify anything else.

class yuio.git.TagParser

A parser that provides autocompletion for git tag, but doesn’t verify anything else.

class yuio.git.BranchParser

A parser that provides autocompletion for git branches, but doesn’t verify anything else.

class yuio.git.RemoteParser

A parser that provides autocompletion for git remotes, but doesn’t verify anything else.

If you know path to your repository before hand, and want to make sure that the user supplies a valid ref that points to an existing git object, use CommitParser:

class yuio.git.CommitParser(*, repo: Repo)

A parser for git refs (commits, tags, branches, and so on).

This parser validates that the given ref exists in the given repository, parses it and returns a commit data associated with this ref.

If you need a simple string without additional validation, use RefParser.

Parameters:

repo – initialized repository is required to ensure that commit is valid.

Autocompleting git refs

class yuio.git.RefCompleter(
repo: Repo | None,
modes: set[RefCompleterMode] | None = None,
)

Completes git refs.

Parameters:
  • repo – source of completions. If not given, this completer will try to use current directory as a repo root, and fail silently if it’s not a repo.

  • modes – which objects to complete.

class yuio.git.RefCompleterMode(*values)

Specifies operation modes for RefCompleter.

BRANCH = 'b'

Completes branches.

REMOTE = 'r'

Completes remote branches.

TAG = 't'

Completes tags.

HEAD = 'h'

Completes HEAD and ORIG_HEAD.