Concepts¶
Workspace Root¶
A GWZ workspace is a local directory that owns a tracked gwz.conf/ metadata
directory. The root repository is a normal Git repository and records the
workspace manifest, lock, and snapshots.
Member Repository¶
A member is a Git repository managed as part of the workspace. Commands can act on all members, a selected set of members, or the workspace root when the operation includes root state.
Members have:
- an id, used with
--member; - a workspace-relative path, used with
--member-path; - an absolute path when materialized locally;
- source and remote metadata in workspace files;
- current Git state observed by status, materialize, pull, and push.
Manifest And Lock¶
The manifest is gwz.conf/gwz.yml. It records the workspace and configured
members.
The lock is gwz.conf/gwz.lock.yml. It records exact member revisions so the
workspace can be reproduced by gwz materialize --lock or by gwz clone.
Use gwz capture to record the live worktree state into the lock without
otherwise mutating member repositories.
Member Listing¶
gwz ls lists materialized members by default. gwz ls --local prints
workspace-relative paths, which is useful in scripts. gwz ls --unmaterialized
also includes configured members that are not currently checked out on disk.
Snapshot¶
A snapshot is a named workspace artifact that captures the current selected member revisions. Use snapshots before risky multi-repository changes or when you need a reproducible workspace point that is not necessarily a release tag.
Commands:
gwz snapshot before-refactor
gwz snapshot --list
gwz materialize --snapshot before-refactor
gwz pull --snapshot before-refactor
Git Tag¶
gwz tag manages real Git tags across selected members. Local create, list, and
delete operations include selected members and the committed workspace root.
Remote push, fetch, list, and delete operations span member repositories.
Tags are checked out through materialization:
Workspace History¶
gwz log reads the workspace root and selected member repositories as one
newest-first history. The default selection is the root plus every active
member. The same global selectors used by other commands can narrow it.
Coordinated commits carrying the same valid GWZ commit marker normally
coalesce into one workspace entry. A conservative message/author/time
heuristic can coalesce compatible unmarked commits; --no-coalesce exposes
the underlying per-repository commits. Machine output identifies the result as
none, heuristic, marker:<uuid-v7>, or marker-invalid provenance.
Revision and snapshot operands use the shared range grammar. For example,
+release..HEAD starts each repository at its release snapshot entry, while
+lock..HEAD starts at the revision recorded in the workspace lock. Pathspecs
belong after -- and are interpreted relative to the invocation directory.
See the log command page for limits, filters, output modes,
and failure policy.
Selection¶
Selection flags are global:
--member <member-id>selects by member id and may be repeated.--member-path <member-path>selects by workspace-relative path and may be repeated.--allselects all members and cannot be combined with--memberor--member-path.
Commands also have command-specific selection in some cases. gwz forall, for
example, accepts positional project names that match member ids or paths.
Planning And Failure Policy¶
--dry-run plans an operation without mutating workspace metadata or member
repositories. It is not supported for gwz clone.
--partial allows operations to complete for members that can proceed even when
another selected member fails. Without it, operations that can plan ahead reject
partial mutation when a selected member cannot proceed cleanly.
--force allows destructive behavior when an operation requires explicit
confirmation.
Remotes And Sync¶
--remote <name> selects the Git remote used by operations that contact
remotes.
--sync <mode> selects sync behavior. Implemented values are:
The default policy is fast-forward only.
Network operations are bounded by --jobs <n> across the whole operation and
--max-per-host <n> per remote host. --ssh-timeout <secs> bounds stalled
SSH/network reads; 0 disables the timeout.
On clone and materialize, --url-scheme <manifest|ssh|https> chooses the
URL form used for repositories this operation clones on the known hosts
github.com, gitlab.com, and bitbucket.org; GWZ_URL_SCHEME sets the same
choice. The manifest is never rewritten, and a member that is already checked
out keeps its remotes.
The flag wins over GWZ_URL_SCHEME, which wins over the preference an earlier
ssh or https run recorded in <workspace>/.gwz/url-scheme.yml; manifest
applies when none of them is set. An explicit --url-scheme manifest clears
that record. The file is local runtime state: it is not part of gwz.conf/,
not in the manifest, and not committed.
On gwz merge, --remote <name> does not name a Git remote at all: it names
a member of the local clone family, described below.
Publication¶
gwz push sends each selected repository to its own configured remote. A push
that contacts the root proves, before the root transfer, that every member
commit the committed lock names is available, from this operation's own reads of
the member remotes or its accepted pushes of branches that contain the commit,
never from remote-tracking refs. It reads every dependency; like its transfers,
its reads run in parallel within --jobs and --max-per-host.
The proof reads each dependency at the push URL, else the fetch URL, of the
member's remote (the one the manifest names, usually origin) when that URL is
the committed URL or the same URL in the other scheme on github.com, gitlab.com
or bitbucket.org; at the committed URL in the scheme .gwz/url-scheme.yml
records when the member is not checked out; and at the committed URL otherwise.
A workspace cloned with gwz clone --url-scheme https therefore publishes over
HTTPS end to end, with credentials from your Git credential helper.
To switch a workspace cloned over SSH, clone it again with --url-scheme https,
or point the root (.) and each member at HTTPS yourself:
Push takes no --url-scheme and does not read GWZ_URL_SCHEME. A workspace
switched by hand has no .gwz/url-scheme.yml, so members that are not checked
out are still read at their committed URLs until a --url-scheme https clone or
materialize records one. The manifest keeps its URLs: gwz repo sync keeps the
manifest URL for a remote that differs from it only by scheme, unless run with
--force.
By default a push contacts only repositories that changed since the last fetch
or push. It compares each branch with its remote-tracking ref, such as
origin/main, not with the branch's upstream, and neither checks for changes
nor pushes a repository whose branch equals that ref or is behind it. A
repository without a usable remote-tracking ref (a branch never fetched or
pushed, a single-branch or shallow clone, or a push URL that names another
repository) is always contacted. Each repository left alone reports Noop with
a reason that names the remote and branch:
already on origin: this push read the remote, and its branch already points at the local commit;up to date with origin/main as of the last fetch or push: the branch equals its remote-tracking ref, so the remote was not contacted;behind origin/main as of the last fetch or push: the remote-tracking ref is ahead of the branch, so there is nothing to publish and the remote was not contacted.
When repositories were not contacted, human output ends with a line such as the
following, and --verbose adds each row's reason:
7 repositories unchanged since the last fetch or push were not checked for changes; --check-remotes to verify
gwz push --check-remotes skips that comparison: it reads every selected remote
and every root dependency, pushes repositories whose remote lacks their branch's
commit, and proves a selected root even when it has nothing to push. Use it when
someone else may have rewound a remote, before a release, or to check that an
unchanged root is still sound. Remote-tracking refs can go stale; see
Troubleshooting.
Local Clone Family¶
A local clone is a second working copy of the whole workspace on the same
machine, made with gwz local clone <name> [dest] and registered by name in
the workspace's local clone family. A create copies the tree as it sits,
uncommitted work and build output included. The family index lives on the
workspace root; each clone carries a pointer back to it, so family commands
work from any ready member. Names resolve at operation time, are never
written into gwz.conf/, and never become Git remotes.
Work comes back by name: gwz merge --remote <name> [<ref>] imports the
clone's commits into each receiving repository under a retained
refs/gwz/local-imports/<transfer-id> ref and runs the ordinary coordinated
merge from there. On merge the name is family-only. On pull and push a
family name is not served by this build and falls through to Git remote
resolution.
A clone is deleted with gwz local dispose <name> only when its history is
verifiably preserved in another surviving member; a clean working tree is not
proof. --keep forgets the clone without deleting anything, --force
<hazard,...> names the losses you accept, and gwz local disband retires the
family while keeping every tree. See Local Clones.
Progress Events¶
Human mode renders live progress to stderr when stderr is a terminal.
--jsonl streams operation records to stdout for machine consumers. Progress
event frequency is controlled by --progress-interval <ms>, with the default
100 milliseconds per member and 0 meaning every update.
Forall Execution¶
gwz forall is a CLI-local executor. It resolves selected materialized members,
then runs a command in each member directory.
In argv mode, use -- before the command:
In shell mode, use -c:
Each child receives:
GWZ_MEMBER_IDGWZ_MEMBER_PATHGWZ_MEMBER_ABSPATHGWZ_ROOT
In argv mode, {@} inside an argument is replaced with the member path.