---
title: "Rollback Procedures"
description: "Safely revert artifacts to previous versions when needed"
---

# Rollback Procedures

Rollback allows you to revert artifacts to previous versions when changes need to be undone. TraceRTM provides safe rollback mechanisms with full traceability.

## Basic Rollback

### Rollback to Previous Version

```python
from tracertm import TraceRTMClient

client = TraceRTMClient()

# Rollback to previous version
client.rollback(
    item_id="FEAT-001",
    to_version=3,
    reason="Reverting incorrect changes from sprint review"
)
```

### CLI Rollback

```bash
# Rollback to specific version
tracertm rollback FEAT-001 --to-version 3 --reason "Reverting incorrect changes"

# Output:
# Rolling back FEAT-001
# ════════════════════════════════════════
# Current version: v5
# Target version: v3
#
# Changes to revert:
#   v5: status (done → review)
#   v4: description, metadata.story_points
#
# Confirm rollback? [y/N]: y
#
# ✓ Rolled back FEAT-001 to v3
# New version: v6 (rollback of v5-v4 to v3)
```

## Rollback Options

### Rollback to Previous Version

```python
# Rollback by 1 version
client.rollback(
    item_id="FEAT-001",
    steps=1,  # Go back 1 version
    reason="Undo last change"
)

# Rollback by multiple versions
client.rollback(
    item_id="FEAT-001",
    steps=3,  # Go back 3 versions
    reason="Reverting sprint changes"
)
```

```bash
# Rollback by steps
tracertm rollback FEAT-001 --steps 1
tracertm rollback FEAT-001 --steps 3
```

### Rollback to Timestamp

```python
# Rollback to point in time
client.rollback(
    item_id="FEAT-001",
    to_timestamp="2024-12-05T10:00:00Z",
    reason="Reverting to pre-review state"
)
```

```bash
tracertm rollback FEAT-001 --to-time "2024-12-05 10:00"
tracertm rollback FEAT-001 --to-time "2 days ago"
```

### Rollback to Baseline

```python
# Rollback to a baseline
client.rollback(
    item_id="FEAT-001",
    to_baseline="v1.0-release",
    reason="Reverting to release baseline"
)
```

```bash
tracertm rollback FEAT-001 --to-baseline "v1.0-release"
```

## Selective Rollback

### Rollback Specific Fields

```python
# Rollback only certain fields
client.rollback_fields(
    item_id="FEAT-001",
    to_version=3,
    fields=["description", "metadata.story_points"],
    reason="Reverting specification changes only"
)
```

```bash
# Rollback specific fields
tracertm rollback FEAT-001 --to-version 3 --fields "description,metadata.story_points"
```

### Exclude Fields from Rollback

```python
# Rollback but keep current status
client.rollback(
    item_id="FEAT-001",
    to_version=3,
    exclude_fields=["status", "assignee"],
    reason="Revert content, keep workflow state"
)
```

```bash
tracertm rollback FEAT-001 --to-version 3 --exclude "status,assignee"
```

## Bulk Rollback

### Rollback Multiple Items

```python
# Rollback multiple items
results = client.bulk_rollback(
    items={
        "FEAT-001": {"to_version": 3},
        "FEAT-002": {"to_version": 5},
        "CODE-010": {"to_baseline": "v1.0-release"}
    },
    reason="Reverting sprint 5 changes"
)

for item_id, result in results.items():
    print(f"{item_id}: {'✓' if result.success else '✗'}")
```

```bash
# Bulk rollback
tracertm rollback FEAT-001 FEAT-002 CODE-010 --to-baseline "v1.0-release"
```

### Rollback by Query

```python
# Rollback all items matching criteria
client.rollback_query(
    query={
        "item_type": "feature",
        "metadata.sprint": "2024-Q4-S5",
        "status": "in_progress"
    },
    to_baseline="sprint-4-end",
    reason="Reverting incomplete sprint work"
)
```

```bash
tracertm rollback --filter "metadata.sprint = 2024-Q4-S5" --to-baseline sprint-4-end
```

## Link Rollback

### Rollback Links

```python
# Rollback link changes
client.rollback_links(
    item_id="FEAT-001",
    to_version=3,
    reason="Reverting incorrect link changes"
)
```

### Include/Exclude Links

```python
# Rollback content without links
client.rollback(
    item_id="FEAT-001",
    to_version=3,
    include_links=False,
    reason="Revert content only"
)

# Rollback only links
client.rollback_links_only(
    item_id="FEAT-001",
    to_version=3,
    reason="Revert link changes only"
)
```

## Preview Rollback

### Dry Run

```python
# Preview rollback without applying
preview = client.preview_rollback(
    item_id="FEAT-001",
    to_version=3
)

print("Changes that would be reverted:")
for version in preview.versions_to_revert:
    print(f"  v{version.number}: {version.changes}")

print("\nResult after rollback:")
for field, value in preview.result_state.items():
    print(f"  {field}: {value}")
```

```bash
# CLI dry run
tracertm rollback FEAT-001 --to-version 3 --dry-run

# Output:
# Rollback Preview: FEAT-001
# ════════════════════════════════════════
#
# Current state (v5):
#   title: User Authentication
#   status: done
#   description: OAuth2 authentication with SSO
#   metadata.story_points: 13
#
# Target state (v3):
#   title: User Authentication
#   status: in_progress
#   description: Basic authentication
#   metadata.story_points: 5
#
# Changes to revert:
#   v5 → v4: status (done → review)
#   v4 → v3: description, story_points
#
# This is a dry-run. No changes were made.
```

## Rollback Safety

### Validation Checks

```python
# Rollback with validation
try:
    client.rollback(
        item_id="FEAT-001",
        to_version=3,
        validate=True  # Check if rollback is safe
    )
except RollbackValidationError as e:
    print(f"Rollback blocked: {e.message}")
    print(f"Issues: {e.issues}")
```

### Blocked Rollback Scenarios

```python
# These scenarios may block rollback:

# 1. Breaking links
# If items linked to FEAT-001 depend on current state
preview = client.preview_rollback("FEAT-001", to_version=3)
if preview.would_break_links:
    print(f"Warning: Would break {len(preview.affected_links)} links")

# 2. Workflow violations
# If rollback would violate workflow rules
if preview.workflow_violations:
    print(f"Warning: Would violate workflow: {preview.workflow_violations}")

# 3. Locked items
# If item is version-locked
if preview.is_locked:
    print(f"Cannot rollback: Item is locked")
```

### Force Rollback

```python
# Force rollback despite warnings
client.rollback(
    item_id="FEAT-001",
    to_version=3,
    force=True,  # Override safety checks
    reason="Emergency rollback - approved by lead"
)
```

```bash
# Force rollback
tracertm rollback FEAT-001 --to-version 3 --force --reason "Emergency rollback"
```

## Rollback Policies

### Configure Rollback Rules

```yaml
# .tracertm/config.yaml
rollback:
  # Who can rollback
  permissions:
    own_changes: true      # Users can rollback their own changes
    others_changes: admin  # Only admins can rollback others' changes

  # Rollback restrictions
  restrictions:
    # Statuses that can't be rolled back from
    protected_statuses:
      - released
      - archived

    # Time limit for easy rollback
    easy_rollback_window: "24h"  # Within 24h, no approval needed

    # Require approval after window
    require_approval_after: "24h"
    approvers: [lead, admin]

  # What to preserve during rollback
  preserve:
    - audit_trail
    - comments
    - attachments
```

### Approval Workflow

```python
# Request rollback approval
request = client.request_rollback(
    item_id="FEAT-001",
    to_version=3,
    reason="Need to revert specification changes",
    approvers=["lead@example.com"]
)

print(f"Request ID: {request.id}")
print(f"Status: {request.status}")  # pending_approval

# Approver approves
client.approve_rollback(request.id, approved_by="lead@example.com")

# Rollback executes after approval
```

## Rollback History

### Track Rollbacks

```python
# View rollback history
rollbacks = client.get_rollback_history("FEAT-001")

for rb in rollbacks:
    print(f"{rb.timestamp}: v{rb.from_version} → v{rb.to_version}")
    print(f"  By: {rb.user}")
    print(f"  Reason: {rb.reason}")
```

```bash
# CLI rollback history
tracertm rollback history FEAT-001

# Output:
# Rollback History for FEAT-001
# ════════════════════════════════════════
# 2024-12-10 15:30  v5 → v3
#   By: admin@example.com
#   Reason: Reverting sprint changes
#   Result version: v6
#
# 2024-12-05 10:00  v4 → v2
#   By: developer@example.com
#   Reason: Undo accidental changes
#   Result version: v5
```

### Rollback Audit

```python
# Generate rollback audit report
report = client.generate_rollback_report(
    since="2024-01-01",
    format="pdf"
)

report.save("rollback_audit_2024.pdf")
```

## Undo Rollback

### Restore After Rollback

```python
# The rollback itself creates a new version
# You can "undo" a rollback by rolling back to pre-rollback version

# Before rollback: v5
# After rollback to v3: v6 (contains v3 state)
# To undo rollback: rollback to v5

client.rollback(
    item_id="FEAT-001",
    to_version=5,  # Pre-rollback version
    reason="Undoing previous rollback"
)
```

### Rollback Chain

```python
# View the version chain including rollbacks
chain = client.get_version_chain("FEAT-001")

for entry in chain:
    if entry.is_rollback:
        print(f"v{entry.version}: Rollback to v{entry.rollback_target}")
    else:
        print(f"v{entry.version}: {entry.summary}")
```

## Best Practices

### 1. Always Preview First

```bash
# Good: Preview before rollback
tracertm rollback FEAT-001 --to-version 3 --dry-run
tracertm rollback FEAT-001 --to-version 3

# Avoid: Blind rollback
```

### 2. Provide Clear Reasons

```python
# Good: Descriptive reason
client.rollback(
    item_id="FEAT-001",
    to_version=3,
    reason="Reverting spec changes from ticket JIRA-456 per PM request"
)

# Avoid: No reason
client.rollback(item_id="FEAT-001", to_version=3)
```

### 3. Use Selective Rollback When Possible

```python
# Good: Only revert what's needed
client.rollback_fields(
    item_id="FEAT-001",
    to_version=3,
    fields=["description"],  # Only the problematic field
    reason="Correcting specification text"
)

# Avoid: Full rollback when only one field is wrong
```

### 4. Consider Link Impact

```python
# Check impact before rollback
preview = client.preview_rollback("FEAT-001", to_version=3)

if preview.affected_links:
    print("Warning: This rollback affects links:")
    for link in preview.affected_links:
        print(f"  {link.source_id} → {link.target_id}")
```

## Related Topics

- [History](/docs/wiki/concepts/versioning/history) - Change tracking
- [Branching](/docs/wiki/concepts/versioning/branching) - Branch workflows
- [Merging](/docs/wiki/concepts/versioning/merging) - Combining changes
- [Strategies](/docs/wiki/concepts/versioning/strategies) - Versioning approaches

