Usage Guide¶
This guide provides detailed instructions on using changes-roller.
Installation¶
# Install the tool
pip install -e .
# Verify installation
roller --version
Basic Workflow¶
1. Generate a Configuration Template (Optional but Recommended)¶
Use the init command to generate a template configuration file:
# Create with default name (series.ini)
roller init
# Or specify a custom name
roller init --output my-series.ini
# Overwrite existing file
roller init --force
This creates a fully documented template with all available options.
2. Create a Patch Script¶
Create an executable shell script that performs your desired changes:
#!/bin/bash
# Example: patch.sh
# Your patch logic here
# The script runs in the context of each cloned repository
# Exit with non-zero code on failure
# Example: Update a configuration file
sed -i 's/old_value/new_value/g' config.yml
Make it executable:
chmod +x patch.sh
3. Edit the Configuration File¶
If you used roller init, edit the generated file. Otherwise, create an INI configuration file (series.ini):
[SERIE]
# Comma-separated list of repository URLs
projects = https://github.com/org/repo1,
https://github.com/org/repo2
# Path to your patch script
commands = ./patch.sh
# Commit message template
# Use {{ project_name }} for the repository name
commit_msg = Update configuration in {{ project_name }}
This updates the configuration from old_value to new_value
for improved performance.
# Optional: Gerrit topic for grouping patches
topic = config-update-2025
# Create commits (default: true)
commit = true
# Submit to Gerrit for review (default: false)
review = false
[TESTS]
# Run tests before committing (default: false)
run = false
# Fail if tests fail (default: false)
blocking = false
# Test command to execute (default: tox)
command = tox
4. Execute the Patch Series¶
# Basic execution
roller create --config-file series.ini
# Exit on first error
roller create --config-file series.ini --exit-on-error
# Verbose output
roller create --config-file series.ini --verbose
Configuration Reference¶
[SERIE] Section¶
Option |
Required |
Default |
Description |
|---|---|---|---|
|
Yes |
- |
Comma-separated Git repository URLs |
|
Yes |
- |
Path to patch script |
|
Yes |
- |
Commit message template |
|
No |
“” |
Gerrit topic name |
|
No |
true |
Auto-commit changes |
|
No |
false |
Submit to Gerrit |
|
No |
None |
Target branch to switch to |
|
No |
false |
Create branch if it doesn’t exist |
|
No |
false |
Don’t return to original branch |
|
No |
[] |
Commands to run before changes (one per line) |
|
No |
[] |
Commands to run after changes (one per line) |
|
No |
false |
Continue if commands fail |
|
No |
false |
Preview without executing |
[TESTS] Section¶
Option |
Required |
Default |
Description |
|---|---|---|---|
|
No |
false |
Enable test execution |
|
No |
false |
Fail on test failure |
|
No |
tox |
Test command to run |
Template Variables¶
The following variables can be used in commit_msg:
{{ project_name }}- Name of the repository (extracted from URL){{project_name}}- Alternative syntax without spaces
Example:
commit_msg = Update {{ project_name }} dependencies
Bumps library-x to version 2.0 in {{ project_name }}.
Automatic Sign-off: All commits are automatically signed off using the -s flag. The tool will append a “Signed-off-by: Your Name your.email@example.com” line to your commit message using your Git configuration (user.name and user.email).
Patch Script Guidelines¶
Best Practices¶
Exit codes: Exit with 0 on success, non-zero on failure
Idempotency: Script should be safe to run multiple times
Change detection: Only make changes when necessary
Error handling: Use
set -eto fail on errorsLogging: Print helpful messages for debugging
Example Script¶
#!/bin/bash
set -e # Exit on error
# Check if target file exists
if [ ! -f "requirements.txt" ]; then
echo "No requirements.txt found"
exit 0 # Not an error, just skip
fi
# Make the change
sed -i 's/library==1.0/library==2.0/' requirements.txt
# Verify the change
if grep -q "library==2.0" requirements.txt; then
echo "Successfully updated library version"
else
echo "Failed to update library version"
exit 1
fi
Testing Integration¶
Running Tests¶
Enable testing in your configuration:
[TESTS]
run = true
blocking = true
command = pytest tests/
Test Commands¶
Common test commands:
tox- Run tox environmentspytest- Run pytestnpm test- Node.js testsmake test- Makefile-based tests./run_tests.sh- Custom test script
Blocking vs Non-Blocking¶
Blocking (blocking = true):
Tests must pass for commit to be created
Repository is marked as failed if tests fail
Use for critical changes
Non-Blocking (blocking = false):
Tests run but failures are warnings
Commit is created even if tests fail
Use for experimental changes
Gerrit Integration¶
Setup¶
Install git-review:
pip install git-review
Configure your repositories with
.gitreviewfileEnable review submission:
[SERIE]
review = true
topic = my-patch-series
Workflow¶
Tool clones each repository
Automatically runs
git review -sto setup Gerrit remoteApplies patches and creates commits locally (with automatic sign-off)
Submits to Gerrit with specified topic
All patches grouped under same topic
Review and merge through Gerrit UI
Notes:
The tool automatically sets up git-review for each repository by running
git review -safter cloning. This ensures the Gerrit remote is properly configured before submitting patches.All commits are automatically signed off using
git commit -s, which adds a “Signed-off-by” line with your Git user name and email to the commit message.
Error Handling¶
Exit on Error¶
Use --exit-on-error to stop on first failure:
roller create --config-file series.ini --exit-on-error
Continue on Error¶
Default behavior continues processing all repositories even if some fail.
Debugging¶
Check the workspace directory (shown in output)
Inspect failed repositories manually
Use
--verbosefor detailed outputReview patch script logic
Branch Switching¶
Using the –branch Option¶
Apply changes to a specific branch:
roller create --config-file series.ini --branch stable/1.x
Create a new branch if it doesn’t exist:
roller create --config-file series.ini --branch feature/new --create-branch
Stay on the target branch after completion:
roller create --config-file series.ini --branch dev --stay-on-branch
Multi-Branch Backport¶
Apply the same fix to multiple branches:
for branch in main stable/2.x stable/1.x; do
roller create --config-file security-fix.ini --branch $branch
done
Command Execution¶
Pre-Commands¶
Run commands before applying changes:
roller create --config-file series.ini \
--pre-command "git pull origin main" \
--pre-command "pytest tests/"
Post-Commands¶
Run commands after applying changes:
roller create --config-file series.ini \
--post-command "git add -A" \
--post-command "git commit -m 'Auto-commit'" \
--post-command "git push"
Continue on Error¶
Continue processing even if commands fail:
roller create --config-file series.ini \
--pre-command "npm test" \
--continue-on-error
Dry Run¶
Preview what would be executed without making changes:
roller create --config-file series.ini --dry-run
Commands in Configuration File¶
You can also specify commands in the config file:
[SERIE]
projects = https://github.com/org/repo.git
commands = ./patch.sh
commit_msg = Test
# Commands to run before applying changes
pre_commands = git checkout main
git pull
pytest tests/
# Commands to run after applying changes
post_commands = git add -A
git commit -m "Auto-update"
git push
Security Warning: Commands from configuration files pose a security risk. Only use configuration files from trusted sources, as they can execute arbitrary commands on your system.
Examples¶
Security Update¶
[SERIE]
projects = https://github.com/org/service1,
https://github.com/org/service2,
https://github.com/org/service3
commands = ./update_dependency.sh
commit_msg = Security update for {{ project_name }}
Update vulnerable-lib to address CVE-2025-1234.
topic = security-cve-2025-1234
commit = true
review = true
[TESTS]
run = true
blocking = true
command = tox -e py39
License Header Addition¶
#!/bin/bash
# add_license.sh
for file in $(find . -name "*.py" -type f); do
if ! grep -q "SPDX-License-Identifier" "$file"; then
# Add header
cat license_header.txt "$file" > "$file.tmp"
mv "$file.tmp" "$file"
fi
done
[SERIE]
projects = https://github.com/org/lib1,
https://github.com/org/lib2
commands = ./add_license.sh
commit_msg = Add SPDX license headers to {{ project_name }}
topic = license-compliance
commit = true
review = false
Troubleshooting¶
Common Issues¶
Script not executable
chmod +x your_script.sh
Git authentication fails
Use SSH URLs with configured keys
Or use HTTPS with credential helper
No changes detected
Verify your script makes actual file changes
Check script runs without errors
Tests timeout
Increase timeout in repository.py
Or disable blocking tests
Advanced Usage¶
Parallel Processing¶
The tool automatically processes repositories in parallel (up to 4 concurrent workers).
Workspace Management¶
Workspaces are created in /tmp/changes-roller-XXXXXX by default. The workspace path is displayed at the start of execution.
To inspect a workspace after execution:
cd /tmp/changes-roller-abc123/repo-name
git log
git diff
Custom Git Operations¶
Your patch script can use Git commands:
#!/bin/bash
# Create a new file
echo "content" > newfile.txt
git add newfile.txt
# Modify existing file
git mv oldname.txt newname.txt
Tips and Best Practices¶
Test locally first: Run your patch script manually on one repo before running on all repos
Use dry runs: Set
commit = falseandreview = falseto test without committingIncremental rollout: Start with a small subset of repos
Version control configs: Keep configuration files in Git
Descriptive topics: Use descriptive Gerrit topics for easier tracking
Monitor progress: Watch the output for any warnings or errors
Review workspaces: Check the workspace if something seems wrong
Getting Help¶
roller --help
roller create --help
For issues and feature requests, visit the project repository.