push
Push a feature branch to the remote. Automatically detects the remote type and uses the appropriate push strategy.
Usage
git loom push [branch] [--no-pr]
Arguments
| Argument | Description |
|---|---|
[branch] | Branch name or short ID (optional; interactive picker if omitted) |
Flags
| Flag | Description |
|---|---|
--no-pr | Push without creating a PR or Gerrit review (see below) |
Remote Type Detection
Detection priority (first match wins):
- Explicit config —
git config loom.remote-typeset togithub,azure, orgerrit - URL heuristics — remote URL contains
github.com→ GitHub - URL heuristics — remote URL contains
dev.azure.com→ Azure DevOps - Hook inspection —
.git/hooks/commit-msgcontains “gerrit” → Gerrit - Fallback — Plain Git
Push Remote Selection
Detection priority (first match wins):
- Explicit config —
git config loom.push-remote <remote> - GitHub fork convention — if the integration remote is named
upstreamandoriginexists, push toorigin - Fallback — integration branch’s remote
For non-standard fork setups (e.g., integration branch tracks origin but you push to personal), set:
git config loom.push-remote personal
Push Strategies
Plain Git (default)
git push --force-with-lease --force-if-includes -u <remote> <branch>
Uses --force-with-lease because woven branches are frequently rebased. --force-if-includes adds extra safety.
GitHub
Pushes the branch with --force-with-lease, then checks whether a PR already exists for the branch:
- PR exists — prints the PR URL (
PR updated: https://github.com/owner/repo/pull/42) without opening the browser - No PR — creates the PR via
gh pr createwith an auto-generated title and description (see PR Title and Description below)
If gh is not installed, the push succeeds with a message suggesting to install it.
In a fork workflow (tracking upstream/main), pushes go to origin (your fork) and the PR targets the upstream repository automatically.
If the branch being pushed is the upstream target branch itself, PR creation is skipped.
Azure DevOps
Pushes the branch with --force-with-lease, then checks whether a PR already exists for the branch:
- PR exists — prints the PR URL (
PR updated: https://dev.azure.com/...) without opening the browser - No PR — creates the PR via
az repos pr createwith an auto-generated title and description (see PR Title and Description below)
--detect auto-detects the organization and project from the remote URL. If az is not installed, the push succeeds with a message suggesting to install it.
Gerrit
git push -o topic=<branch> <remote> <branch>:refs/for/<target>
Uses the refs/for/ refspec and sets the topic to the branch name. After pushing, any review URLs returned by Gerrit are extracted from the remote output and displayed below the success message.
PR Title and Description
When creating a new PR (GitHub or Azure DevOps), git-loom auto-generates the title and description from the branch’s commits:
- Single commit — the commit subject becomes the PR title and the commit body becomes the description.
- Multiple commits — you are prompted for a PR title. The description is built by concatenating all commit messages (oldest to newest), separated by
---dividers. - Empty branch — the branch name is used as the title with an empty description.
Pushing Without a PR or Review
Use --no-pr when you want to push a branch to the remote without triggering PR or review creation — for example, to back up a branch, share work-in-progress, or push to a staging ref.
| Remote type | --no-pr behavior |
|---|---|
| Plain | Same as normal (force-with-lease push) |
| GitHub | Skips gh pr create |
| Azure DevOps | Skips az repos pr create |
| Gerrit | Plain push to branch ref instead of refs/for/ (see below) |
Gerrit: wip/ prefix warning
In Gerrit, pushing directly to a branch ref (not refs/for/) creates a remote branch that requires a project admin to delete. To protect against accidental non-deletable branches, --no-pr on Gerrit prompts when the branch name doesn’t start with wip/:
? Branch `feature-a` is not prefixed with `wip/` — a Gerrit admin will be needed to delete the remote branch later
> Push as `feature-a` (admin required to delete it later)
Push as `wip/feature-a` instead
Cancel
- Push as-is — pushes to
remote/feature-a; an admin is needed to delete it later - Push as
wip/<branch>— pushes with refspecfeature-a:wip/feature-a; your local branch name is unchanged - Cancel — aborts the push
If the branch already starts with wip/, no prompt is shown.
Examples
Push to a plain remote
git loom push feature-a
# Pushed 'feature-a' to origin
Push to GitHub (new PR)
git loom push feature-a
# Pushed 'feature-a' to origin
# (browser opens to PR creation page)
Push to GitHub (PR already exists)
git loom push feature-a
# Pushed 'feature-a' to origin
# PR updated: https://github.com/owner/repo/pull/42
Push to Azure DevOps (new PR)
git loom push feature-a
# Pushed 'feature-a' to origin
# (browser opens to PR creation page)
Push to Azure DevOps (PR already exists)
git loom push feature-a
# Pushed 'feature-a' to origin
# PR updated: https://dev.azure.com/org/project/_git/repo/pullrequest/42
Push to Gerrit
git loom push feature-a
# Pushed 'feature-a' to origin (Gerrit: refs/for/main)
# › https://gerrit.example.com/c/project/+/12345
Interactive selection
git loom push
# ? Select branch to push
# > feature-a
# feature-b
# Pushed 'feature-a' to origin
Push without opening a PR (GitHub)
git loom push feature-a --no-pr
# Pushed 'feature-a' to origin
Push without a review, renaming to wip/ (Gerrit)
git loom push feature-a --no-pr
# ? Branch `feature-a` is not prefixed with `wip/`...
# > Push as `wip/feature-a` instead
# Pushed 'feature-a' to origin as 'wip/feature-a'
Override remote type
git config loom.remote-type gerrit
git loom push feature-a
# Pushed 'feature-a' to origin (Gerrit: refs/for/main)
# › https://gerrit.example.com/c/project/+/12345
Prerequisites
- Must be on an integration branch with upstream tracking
- The target branch must be woven into the integration branch
- Network access to the remote
ghCLI (optional, for GitHub PR creation)azCLI (optional, for Azure DevOps PR creation)