Push branches to remote repository with safety checks and force-with-lease support
Pushes Git branches to remote repositories with safety checks, including protected branch validation and force-with-lease support. Triggered by `/repo:push` commands, repo-manager agent, or FABER workflow managers during Release phase.
/plugin marketplace add fractary/claude-plugins/plugin install fractary-repo@fractaryThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Your responsibility is to push Git branches to remote repositories safely. You handle upstream tracking setup, force push operations with safety (--force-with-lease), and validate protected branch rules before pushing.
You are invoked by:
You delegate to the active source control handler to perform platform-specific Git push operations. </CONTEXT>
<CRITICAL_RULES> NEVER VIOLATE THESE RULES:
Protected Branch Safety
--force-with-lease instead of --forceForce Push Safety
--force (always use --force-with-lease)Upstream Tracking
Handler Invocation
Network & Auth
</CRITICAL_RULES>
<INPUTS> You receive structured operation requests:{
"operation": "push-branch",
"parameters": {
"branch_name": "feat/123-add-export",
"remote": "origin",
"set_upstream": true,
"force": false
}
}
Optional Parameters:
branch_name (string) - Name of branch to push (default: current branch)remote (string) - Remote name (default: "origin")set_upstream (boolean) - Set upstream tracking (default: false)force (boolean) - Force push with lease (default: false)force_unsafe (boolean) - Force push without lease (DANGEROUS, default: false)1. OUTPUT START MESSAGE:
šÆ STARTING: Branch Pusher
Branch: {branch_name}
Remote: {remote}
Set Upstream: {set_upstream}
Force: {force}
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
2. LOAD CONFIGURATION:
Load repo configuration to determine:
Use repo-common skill to load configuration.
Note: If config doesn't exist, defaults will be used (including push_sync_strategy: "auto-merge")
3. VALIDATE INPUTS:
Branch Validation:
Remote Validation:
4. CHECK PROTECTED BRANCHES:
PROTECTED_BRANCHES = config.defaults.protected_branches
if branch_name in PROTECTED_BRANCHES and force:
ERROR: "CRITICAL: Cannot force push to protected branch: {branch_name}"
EXIT CODE 10
if branch_name in PROTECTED_BRANCHES:
WARN: "Warning: Pushing to protected branch: {branch_name}"
# Require explicit confirmation unless autonomous mode
5. VALIDATE FORCE PUSH:
If force=true:
if force and not force_unsafe:
# Use --force-with-lease (safe force push)
push_flags = "--force-with-lease"
elif force_unsafe:
# DANGEROUS: Only allow with explicit override
ERROR: "CRITICAL: Unsafe force push requires explicit confirmation"
EXIT CODE 10
6. CHECK AUTHENTICATION:
Verify credentials before attempting push:
7. INVOKE HANDLER:
Invoke the active source control handler skill.
IMPORTANT: You MUST use the Skill tool to invoke the handler. The handler skill name is constructed as follows:
config.handlers.source_control.active (e.g., "github")fractary-repo:handler-source-control-<platform>fractary-repo:handler-source-control-githubDO NOT use any other handler name pattern. The correct pattern is always fractary-repo:handler-source-control-<platform>.
Use the Skill tool with:
fractary-repo:handler-source-control-<platform> (where <platform> is from config)The handler will:
8. VALIDATE RESPONSE:
9. CHECK CONFIG AND OUTPUT COMPLETION MESSAGE:
Check if configuration file exists using repo-common:check-config-exists utility.
If config_exists is false, include the recommendation in completion message:
ā
COMPLETED: Branch Pusher
Branch Pushed: {branch_name} ā {remote}/{branch_name}
Upstream Set: {upstream_set}
Commits Pushed: {commit_count}
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Next: Run /fractary-repo:pr-create to open pull request when ready
š” Tip: Run /fractary-repo:init to create a configuration file for this repository.
This allows you to customize branch naming, merge strategies, and other plugin settings.
If config exists, omit the recommendation:
ā
COMPLETED: Branch Pusher
Branch Pushed: {branch_name} ā {remote}/{branch_name}
Upstream Set: {upstream_set}
Commits Pushed: {commit_count}
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Next: Run /fractary-repo:pr-create to open pull request when ready
</WORKFLOW>
<COMPLETION_CRITERIA> ā Configuration loaded successfully ā All inputs validated ā Protected branch rules checked ā Authentication verified ā Handler invoked and returned success ā Branch pushed to remote successfully ā Upstream tracking set if requested ā Remote ref verified </COMPLETION_CRITERIA>
<OUTPUTS> Return structured JSON response:Success Response:
{
"status": "success",
"operation": "push-branch",
"branch_name": "feat/123-add-export",
"remote": "origin",
"upstream_set": true,
"commits_pushed": 5,
"remote_ref": "refs/heads/feat/123-add-export",
"platform": "github"
}
Error Response:
{
"status": "failure",
"operation": "push-branch",
"error": "Authentication failed: Invalid credentials",
"error_code": 11
}
Error Response with Context (Exit Code 13):
{
"status": "failure",
"operation": "push-branch",
"error": "Branch is out of sync with remote (non-fast-forward)",
"error_code": 13,
"context": {
"branch_name": "main",
"remote": "origin",
"push_sync_strategy": "auto-merge",
"auto_sync_attempted": true,
"auto_sync_failed": true,
"reason": "Conflicts detected during auto-merge"
}
}
This context helps the repo-manager agent determine whether to:
The active handler is determined by configuration: config.handlers.source_control.active
</HANDLERS>
<ERROR_HANDLING>
Invalid Inputs (Exit Code 2):
Protected Branch Violation (Exit Code 10):
Authentication Error (Exit Code 11):
Network Error (Exit Code 12):
Push Rejected Error (Exit Code 13):
IMPORTANT: When exit code 13 occurs, ALWAYS include context in error response:
{
"error_code": 13,
"context": {
"branch_name": "...",
"remote": "...",
"push_sync_strategy": "auto-merge|pull-rebase|pull-merge|manual|fail",
"auto_sync_attempted": true|false,
"auto_sync_failed": true|false,
"reason": "Detailed explanation"
}
}
This allows the repo-manager agent to make intelligent decisions about retry strategies.
Configuration Error (Exit Code 3):
Handler Error (Exit Code 1):
</ERROR_HANDLING>
<USAGE_EXAMPLES>
Example 1: Push Current Branch (No Branch Name Specified)
INPUT:
{
"operation": "push-branch",
"parameters": {
"remote": "origin",
"set_upstream": true
}
}
# Assuming current branch is feat/123-user-export
OUTPUT:
{
"status": "success",
"operation": "push-branch",
"branch_name": "feat/123-user-export",
"remote": "origin",
"upstream_set": true,
"commits_pushed": 3
}
Example 2: First Push with Upstream Tracking
INPUT:
{
"operation": "push-branch",
"parameters": {
"branch_name": "feat/123-user-export",
"remote": "origin",
"set_upstream": true
}
}
OUTPUT:
{
"status": "success",
"operation": "push-branch",
"branch_name": "feat/123-user-export",
"remote": "origin",
"upstream_set": true,
"commits_pushed": 3
}
Example 2: Regular Push to Existing Remote Branch
INPUT:
{
"operation": "push-branch",
"parameters": {
"branch_name": "feat/456-dashboard",
"remote": "origin"
}
}
OUTPUT:
{
"status": "success",
"operation": "push-branch",
"branch_name": "feat/456-dashboard",
"remote": "origin",
"upstream_set": false,
"commits_pushed": 2
}
Example 3: Force Push with Lease (Safe)
INPUT:
{
"operation": "push-branch",
"parameters": {
"branch_name": "fix/789-auth-bug",
"remote": "origin",
"force": true
}
}
OUTPUT:
{
"status": "success",
"operation": "push-branch",
"branch_name": "fix/789-auth-bug",
"remote": "origin",
"force_used": true,
"force_method": "force-with-lease",
"commits_pushed": 1
}
Example 4: Protected Branch Force Push Error
INPUT:
{
"operation": "push-branch",
"parameters": {
"branch_name": "main",
"remote": "origin",
"force": true
}
}
OUTPUT:
{
"status": "failure",
"operation": "push-branch",
"error": "CRITICAL: Cannot force push to protected branch: main",
"error_code": 10
}
Example 5: Authentication Error
INPUT:
{
"operation": "push-branch",
"parameters": {
"branch_name": "feat/999-new-feature",
"remote": "origin"
}
}
OUTPUT:
{
"status": "failure",
"operation": "push-branch",
"error": "Authentication failed: Invalid credentials",
"error_code": 11
}
</USAGE_EXAMPLES>
<FORCE_PUSH_SAFETY>
Force-With-Lease Explained:
Traditional --force overwrites remote branch unconditionally. This is DANGEROUS as it can lose others' work.
--force-with-lease is safe because it:
When to Use Force Push:
When NOT to Use Force Push:
Best Practice: Always pull/fetch before force pushing to ensure you have latest remote state.
</FORCE_PUSH_SAFETY>
<INTEGRATION>Called By:
repo-manager agent - For programmatic push operations/repo:push command - For user-initiated pushesrelease-manager - Before creating PRsCalls:
repo-common skill - For configuration loadinghandler-source-control-{platform} skill - For platform-specific push operationsDoes NOT Call:
This skill is focused on push operations:
By separating push operations: