submodule¶

For git-submodule(1).

Overview¶

Manage git submodules using GitSubmoduleManager (collection-level) and GitSubmoduleEntryCmd (per-submodule operations).

Note

GitSubmoduleCmd is the legacy interface. Use git.submodules (GitSubmoduleManager) for the new Manager/Cmd pattern.

Example¶

from libvcs.cmd.git import Git

git = Git(path='/path/to/repo')

# Add a submodule
git.submodules.add(url='https://github.com/org/lib.git', path='vendor/lib')

# List all submodules
submodules = git.submodules.ls()

# Get a specific submodule and operate on it
submodule = git.submodules.get(path='vendor/lib')
submodule.init()
submodule.update()
submodule.deinit()

# Sync submodule URLs
git.submodules.sync()

API Reference¶

class libvcs.cmd.git.GitSubmoduleManager[source]¶

Bases: object

Traverse and manage git submodules with ORM-like filtering via QueryList.

Wrap some of git-submodule(1), manager.

Parameters:

path (str | PathLike[str]) – Operates as PATH in the corresponding git subcommand.

Examples

>>> GitSubmoduleManager(path=tmp_path)
<GitSubmoduleManager path=...>
>>> GitSubmoduleManager(path=tmp_path).run('status')
'fatal: not a git repository (or any of the parent directories): .git'
>>> GitSubmoduleManager(path=example_git_repo.path).run('status')
''
__init__(*, path, cmd=None)[source]¶

Wrap some of git-submodule(1), manager.

Parameters:
  • path (str | PathLike[str]) – Operates as PATH in the corresponding git subcommand.

  • cmd (Git | None)

Return type:

None

Examples

>>> GitSubmoduleManager(path=tmp_path)
<GitSubmoduleManager path=...>
>>> GitSubmoduleManager(path=tmp_path).run('status')
'fatal: not a git repository (or any of the parent directories): .git'
>>> GitSubmoduleManager(path=example_git_repo.path).run('status')
''
path: Path¶

Directory to check out

run(command=None, local_flags=None, *, quiet=False, log_in_real_time=False, check_returncode=None, **kwargs)[source]¶

Run a command against a git repository’s submodules.

Wraps git submodule.

Parameters:
  • command (Literal['add', 'status', 'init', 'deinit', 'update', 'set-branch', 'set-url', 'summary', 'foreach', 'sync', 'absorbgitdirs'] | None) – Submodule command to run.

  • local_flags (list[str] | None) – Additional flags to pass.

  • quiet (bool) – Suppress output.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

  • kwargs (Any)

Return type:

str

Examples

>>> GitSubmoduleManager(path=example_git_repo.path).run('status')
''
add(repository, path=None, *, branch=None, force=False, name=None, depth=None, log_in_real_time=False, check_returncode=None)[source]¶

Add a new submodule.

Parameters:
  • repository (str) – URL of the repository to add as submodule.

  • path (str | None) – Path where submodule will be cloned.

  • branch (str | None) – Branch to track.

  • force (bool) – Force add.

  • name (str | None) – Logical name for the submodule.

  • depth (int | None) – Shallow clone depth.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> git_remote_repo = create_git_remote_repo()
>>> result = GitSubmoduleManager(path=example_git_repo.path).add(
...     f'file://{git_remote_repo}',
...     'vendor/example'
... )
>>> 'error' in result.lower() or 'fatal' in result.lower() or result == ''
True
init(*, path=None, log_in_real_time=False, check_returncode=None)[source]¶

Initialize submodules.

Parameters:
  • path (list[str] | str | None) – Specific submodule path(s) to initialize.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> GitSubmoduleManager(path=example_git_repo.path).init()
''
update(*, path=None, init=False, force=False, checkout=False, rebase=False, merge=False, recursive=False, remote=False, log_in_real_time=False, check_returncode=None)[source]¶

Update submodules.

Parameters:
  • path (list[str] | str | None) – Specific submodule path(s) to update.

  • init (bool) – Initialize if not already.

  • force (bool) – Discard local changes.

  • checkout (bool) – Check out superproject’s recorded commit.

  • rebase (bool) – Rebase current branch onto commit.

  • merge (bool) – Merge commit into current branch.

  • recursive (bool) – Recurse into nested submodules.

  • remote (bool) – Use remote tracking branch.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> GitSubmoduleManager(path=example_git_repo.path).update()
''
>>> GitSubmoduleManager(path=example_git_repo.path).update(init=True)
''
foreach(command, *, recursive=False, log_in_real_time=False, check_returncode=None)[source]¶

Run command in each submodule.

Parameters:
  • command (str) – Shell command to run.

  • recursive (bool) – Recurse into nested submodules.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> result = GitSubmoduleManager(path=example_git_repo.path).foreach(
...     'git status'
... )
>>> isinstance(result, str)
True
sync(*, path=None, recursive=False, log_in_real_time=False, check_returncode=None)[source]¶

Sync submodule URLs.

Parameters:
  • path (list[str] | str | None) – Specific submodule path(s) to sync.

  • recursive (bool) – Recurse into nested submodules.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> GitSubmoduleManager(path=example_git_repo.path).sync()
''
summary(*, cached=False, files=False, summary_limit=None, commit=None, path=None, log_in_real_time=False, check_returncode=None)[source]¶

Show commit summary for submodules.

Parameters:
  • cached (bool) – Use cached info.

  • files (bool) – Compare to working tree.

  • summary_limit (int | None) – Limit number of commits shown.

  • commit (str | None) – Commit to compare against.

  • path (list[str] | str | None) – Specific submodule path(s).

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> result = GitSubmoduleManager(path=example_git_repo.path).summary()
>>> isinstance(result, str)
True
absorbgitdirs(*, path=None, log_in_real_time=False, check_returncode=None)[source]¶

Absorb git directories into superproject.

Parameters:
  • path (list[str] | str | None) – Specific submodule path(s).

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> result = GitSubmoduleManager(path=example_git_repo.path).absorbgitdirs()
>>> isinstance(result, str)
True
_ls(*, recursive=False, cached=False, log_in_real_time=False, check_returncode=None)[source]¶

Parse submodule status output into structured data.

Parameters:
  • recursive (bool) – Include nested submodules.

  • cached (bool) – Use cached info.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Returns:

List of parsed submodule data.

Return type:

list[dict[str, Any]]

Examples

>>> submodules = GitSubmoduleManager(path=example_git_repo.path)._ls()
>>> isinstance(submodules, list)
True
ls(*, recursive=False, cached=False)[source]¶

List submodules as GitSubmodule objects.

Parameters:
  • recursive (bool) – Include nested submodules.

  • cached (bool) – Use cached info.

Returns:

List of submodules with ORM-like filtering.

Return type:

QueryList[GitSubmodule]

Examples

>>> submodules = GitSubmoduleManager(path=example_git_repo.path).ls()
>>> isinstance(submodules, QueryList)
True
get(path=None, name=None, **kwargs)[source]¶

Get a specific submodule.

Parameters:
  • path (str | None) – Submodule path to find.

  • name (str | None) – Submodule name to find.

  • **kwargs (Any) – Additional filter criteria.

Returns:

The matching submodule.

Return type:

GitSubmodule

Raises:

Examples

>>> submodules = GitSubmoduleManager(path=example_git_repo.path)
>>> # submodule = submodules.get(path='vendor/lib')
filter(*args, **kwargs)[source]¶

Filter submodules.

Parameters:
  • *args (Any) – Positional arguments for QueryList.filter().

  • **kwargs (Any) – Keyword arguments for filtering (supports Django-style lookups).

Returns:

Filtered list of submodules.

Return type:

QueryList[GitSubmodule]

Examples

>>> submodules = GitSubmoduleManager(path=example_git_repo.path).filter()
>>> isinstance(submodules, QueryList)
True
class libvcs.cmd.git.GitSubmodule[source]¶

Bases: object

Represent a git submodule.

name: str¶

Submodule name (from .gitmodules).

path: str¶

Path to submodule relative to repository root.

url: str | None = None¶

Remote URL for the submodule.

sha: str | None = None¶

Current commit SHA of the submodule.

branch: str | None = None¶

Configured branch for the submodule.

status_prefix: str = ''¶

‘-’ not initialized, ‘+’ differs, ‘U’ conflicts.

Type:

Status prefix

_cmd: GitSubmoduleEntryCmd | None = None¶

GitSubmoduleEntryCmd for operations on this submodule

Type:

Internal

property cmd: GitSubmoduleEntryCmd¶

Return command object for this submodule.

property initialized: bool¶

Check if submodule is initialized.

__init__(name, path, url=None, sha=None, branch=None, status_prefix='', _cmd=None)[source]¶
Parameters:
Return type:

None

class libvcs.cmd.git.GitSubmoduleEntryCmd[source]¶

Bases: object

Run git commands targeting a specific submodule.

Wrap some of git-submodule(1) for specific submodule operations.

Parameters:
  • path (str | PathLike[str]) – Operates as PATH in the corresponding git subcommand.

  • submodule_path (str) – Path to the submodule relative to repository root.

Examples

>>> GitSubmoduleEntryCmd(
...     path=example_git_repo.path,
...     submodule_path='vendor/lib',
... )
<GitSubmoduleEntryCmd vendor/lib>
__init__(*, path, submodule_path, cmd=None)[source]¶

Wrap some of git-submodule(1) for specific submodule operations.

Parameters:
  • path (str | PathLike[str]) – Operates as PATH in the corresponding git subcommand.

  • submodule_path (str) – Path to the submodule relative to repository root.

  • cmd (Git | None)

Return type:

None

Examples

>>> GitSubmoduleEntryCmd(
...     path=example_git_repo.path,
...     submodule_path='vendor/lib',
... )
<GitSubmoduleEntryCmd vendor/lib>
path: Path¶

Directory to check out

run(command=None, local_flags=None, *, log_in_real_time=False, check_returncode=None, **kwargs)[source]¶

Run a command against a specific submodule.

Wraps git submodule.

Parameters:
  • command (Literal['add', 'status', 'init', 'deinit', 'update', 'set-branch', 'set-url', 'summary', 'foreach', 'sync', 'absorbgitdirs'] | None) – Submodule command to run.

  • local_flags (list[str] | None) – Additional flags to pass.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

  • kwargs (Any)

Return type:

str

Examples

>>> GitSubmoduleEntryCmd(
...     path=example_git_repo.path,
...     submodule_path='vendor/lib',
... ).run('status')
''
init(*, log_in_real_time=False, check_returncode=None)[source]¶

Initialize this submodule.

Return type:

str

Parameters:
  • log_in_real_time (bool)

  • check_returncode (bool | None)

Examples

>>> result = GitSubmoduleEntryCmd(
...     path=example_git_repo.path,
...     submodule_path='vendor/lib',
... ).init()
>>> 'error' in result.lower() or result == ''
True
update(*, init=False, force=False, checkout=False, rebase=False, merge=False, recursive=False, remote=False, log_in_real_time=False, check_returncode=None)[source]¶

Update this submodule.

Parameters:
  • init (bool) – Initialize if not already.

  • force (bool) – Discard local changes.

  • checkout (bool) – Check out superproject’s recorded commit.

  • rebase (bool) – Rebase current branch onto commit.

  • merge (bool) – Merge commit into current branch.

  • recursive (bool) – Recurse into nested submodules.

  • remote (bool) – Use remote tracking branch.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> result = GitSubmoduleEntryCmd(
...     path=example_git_repo.path,
...     submodule_path='vendor/lib',
... ).update()
>>> 'error' in result.lower() or result == ''
True
deinit(*, force=False, log_in_real_time=False, check_returncode=None)[source]¶

Unregister this submodule.

Parameters:
  • force (bool) – Force removal even if has local modifications.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> result = GitSubmoduleEntryCmd(
...     path=example_git_repo.path,
...     submodule_path='vendor/lib',
... ).deinit()
>>> 'error' in result.lower() or result == ''
True
set_branch(branch=None, *, default=False, log_in_real_time=False, check_returncode=None)[source]¶

Set branch for this submodule.

Parameters:
  • branch (str | None) – Branch to track.

  • default (bool) – Reset to default (remove branch setting).

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> result = GitSubmoduleEntryCmd(
...     path=example_git_repo.path,
...     submodule_path='vendor/lib',
... ).set_branch('main')
>>> 'fatal' in result.lower() or 'error' in result.lower() or result == ''
True
set_url(url, *, log_in_real_time=False, check_returncode=None)[source]¶

Set URL for this submodule.

Parameters:
  • url (str) – New URL for the submodule.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> result = GitSubmoduleEntryCmd(
...     path=example_git_repo.path,
...     submodule_path='vendor/lib',
... ).set_url('https://example.com/repo.git')
>>> 'fatal' in result.lower() or 'error' in result.lower() or result == ''
True
status(*, recursive=False, log_in_real_time=False, check_returncode=None)[source]¶

Get status of this submodule.

Parameters:
  • recursive (bool) – Recurse into nested submodules.

  • log_in_real_time (bool)

  • check_returncode (bool | None)

Return type:

str

Examples

>>> result = GitSubmoduleEntryCmd(
...     path=example_git_repo.path,
...     submodule_path='vendor/lib',
... ).status()
>>> isinstance(result, str)
True
absorbgitdirs(*, log_in_real_time=False, check_returncode=None)[source]¶

Absorb git directory for this submodule.

Return type:

str

Parameters:
  • log_in_real_time (bool)

  • check_returncode (bool | None)

Examples

>>> result = GitSubmoduleEntryCmd(
...     path=example_git_repo.path,
...     submodule_path='vendor/lib',
... ).absorbgitdirs()
>>> 'error' in result.lower() or result == ''
True
class libvcs.cmd.git.GitSubmoduleCmd[source]¶

Bases: object

Run git submodule commands (low-level, use GitSubmoduleManager for traversal).

Lite, typed, pythonic wrapper for git-submodule(1).

Parameters:

path (str | PathLike[str]) – Operates as PATH in the corresponding git subcommand.

Examples

>>> GitSubmoduleCmd(path=tmp_path)
<GitSubmoduleCmd path=...>
>>> GitSubmoduleCmd(path=tmp_path).run(quiet=True)
'fatal: not a git repository (or any of the parent directories): .git'
>>> GitSubmoduleCmd(path=example_git_repo.path).run(quiet=True)
''
__init__(*, path, cmd=None)[source]¶

Lite, typed, pythonic wrapper for git-submodule(1).

Parameters:
  • path (str | PathLike[str]) – Operates as PATH in the corresponding git subcommand.

  • cmd (Git | None)

Return type:

None

Examples

>>> GitSubmoduleCmd(path=tmp_path)
<GitSubmoduleCmd path=...>
>>> GitSubmoduleCmd(path=tmp_path).run(quiet=True)
'fatal: not a git repository (or any of the parent directories): .git'
>>> GitSubmoduleCmd(path=example_git_repo.path).run(quiet=True)
''
path: Path¶

Directory to check out

run(command=None, local_flags=None, *, quiet=None, cached=None, log_in_real_time=False, check_returncode=None, **kwargs)[source]¶

Run a command against a git submodule.

Wraps git submodule.

Return type:

str

Parameters:
  • command (Literal['add', 'status', 'init', 'deinit', 'update', 'set-branch', 'set-url', 'summary', 'foreach', 'sync', 'absorbgitdirs'] | None)

  • local_flags (list[str] | None)

  • quiet (bool | None)

  • cached (bool | None)

  • log_in_real_time (bool)

  • check_returncode (bool | None)

  • kwargs (Any)

Examples

>>> GitSubmoduleCmd(path=example_git_repo.path).run()
''
init(*, path=None, log_in_real_time=False, check_returncode=None)[source]¶

Git submodule init.

Return type:

str

Parameters:

Examples

>>> GitSubmoduleCmd(path=example_git_repo.path).init()
''
update(*, path=None, init=None, force=None, checkout=None, rebase=None, merge=None, recursive=None, log_in_real_time=False, check_returncode=None, **kwargs)[source]¶

Git submodule update.

Return type:

str

Parameters:

Examples

>>> GitSubmoduleCmd(path=example_git_repo.path).update()
''
>>> GitSubmoduleCmd(path=example_git_repo.path).update(init=True)
''
>>> GitSubmoduleCmd(
...     path=example_git_repo.path
... ).update(init=True, recursive=True)
''
>>> GitSubmoduleCmd(path=example_git_repo.path).update(force=True)
''
>>> GitSubmoduleCmd(path=example_git_repo.path).update(checkout=True)
''
>>> GitSubmoduleCmd(path=example_git_repo.path).update(rebase=True)
''
>>> GitSubmoduleCmd(path=example_git_repo.path).update(merge=True)
''