# rebase-migrations
A Python library for Django migration conflict resolution during git rebases. Automatically renumbers Django migration files to resolve conflicts when rebasing feature branches.
## The Problem
When rebasing Django feature branches, you often encounter migration number conflicts:
```
# Main branch has:
migrations/0010_main_change.py
migrations/0011_main_change.py
migrations/0012_latest_feature.py
# Your feature branch has:
migrations/0010_your_feature.py โ Conflict!
migrations/0011_another_change.py โ Conflict!
```
This library automatically detects and renumbers conflicting migrations during rebase.
## Installation
```bash
pip install rebase-migrations
```
## Usage
### Basic Usage
```python
import rebase_migrations
# Preview changes
rebase_migrations.dry_run('/path/to/django/project')
# Apply changes
rebase_migrations.execute('/path/to/django/project')
```
### JSON Output
Get machine-readable JSON output for programmatic processing:
```python
import rebase_migrations
import json
json_output = rebase_migrations.dry_run(
'/path/to/django/project',
json=True
)
if json_output:
data = json.loads(json_output)
print(json.dumps(data, indent=2))
```
Example JSON structure:
```json
{
"apps": {
"myapp": {
"app_name": "myapp",
"last_common_migration": "0001_initial",
"migration_changes": [
{
"migration_file_name": "0002_add_field",
"file_rename": {
"old_name": "0002_add_field",
"new_name": "0004_add_field"
}
}
],
"max_migration_update": {
"old": "0003_main_branch",
"new": "0004_add_field"
}
}
}
}
```
### Path Handling
The library supports various path formats:
```python
# Absolute paths
rebase_migrations.execute('/home/user/my-django-project')
# Relative paths
rebase_migrations.execute('.') # Current directory
rebase_migrations.execute('../my-project')
# Tilde expansion
rebase_migrations.execute('~/my-django-project')
```
### Parameters
#### `execute(path, all_dirs=False)`
Apply migration changes immediately.
- **`path`** (str): Path to the Django project directory
- **`all_dirs`** (bool, optional): If True, scan all directories for migrations. Default: False
- When False: Skips common directories like `node_modules`, `venv`, `.git`, etc. for better performance
- When True: Comprehensive scan of all directories (slower but finds migrations in unusual locations)
**Returns:** `None`
#### `dry_run(path, all_dirs=False, json=False)`
Preview changes without applying them.
- **`path`** (str): Path to the Django project directory
- **`all_dirs`** (bool, optional): If True, scan all directories for migrations. Default: False
- **`json`** (bool, optional): If True, return JSON output as a string. Default: False
- Returns `None` if `json=False`
- Returns JSON string if `json=True`
**Returns:** `Optional[str]` - JSON string if `json=True`, otherwise `None`
#### Single App Functions
For working with a single Django app:
- **`execute_for_app(app_path)`** - Apply changes to a single app
- **`dry_run_for_app(app_path, json=False)`** - Preview changes to a single app
Both accept the same parameters as their project-level counterparts, but take an `app_path` instead of a project `path`.
## How It Works
1. **Discovers migrations**: Finds Django migration files in your project
2. **Detects conflicts**: Identifies migration number conflicts from git rebase
3. **Renumbers safely**: Assigns new sequential numbers to resolve conflicts
4. **Updates dependencies**: Modifies migration dependencies to maintain integrity
5. **Updates tracking files**: Updates `max_migration.txt` files for django-linear-migrations
## Requirements
- Python 3.8+
- Django project with migration files following naming convention (`NNNN_name.py`)
- Git repository
- **[django-linear-migrations](https://github.com/adamchainz/django-linear-migrations)** package installed and configured
The library automatically updates `max_migration.txt` files that `django-linear-migrations` uses to track the latest migration in each app.
## Features
- ๐ **Automatic Detection**: Finds migration conflicts during rebase
- ๐ **Smart Renumbering**: Renumbers migrations to resolve conflicts
- ๐ **Dependency Updates**: Updates migration dependencies automatically
- ๐ **File Updates**: Updates `max_migration.txt` tracking files
- ๐งช **Dry Run Mode**: Preview changes before applying them
- ๐ **JSON Output**: Machine-readable output for automation and programmatic use
- ๐ **Fast Performance**: Skips irrelevant directories by default
- ๐ ๏ธ **Path Flexibility**: Supports relative paths, tilde expansion, and absolute paths
## CLI Alternative
If you prefer command-line usage, a standalone CLI binary is also available. See the [main repository](https://github.com/reinhash/rebase-migrations) for installation instructions.
## License
MIT License - see [LICENSE](https://github.com/reinhash/rebase-migrations/blob/main/LICENSE) for details.
## Contributing
Contributions welcome! Please see the [main repository](https://github.com/reinhash/rebase-migrations) for contributing guidelines.
Raw data
{
"_id": null,
"home_page": "https://github.com/reinhash/rebase-migrations",
"name": "rebase-migrations",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "django, migrations, git, rebase, conflict-resolution",
"author": null,
"author_email": "Reinhard Scheuerle <reinhard.scheuerle@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/70/b0/5bd67f2fbd86ec39e7c05f3f28a9267c11500bad6da9d41b85cdbd527593/rebase_migrations-0.4.0.tar.gz",
"platform": null,
"description": "# rebase-migrations\n\nA Python library for Django migration conflict resolution during git rebases. Automatically renumbers Django migration files to resolve conflicts when rebasing feature branches.\n\n## The Problem\n\nWhen rebasing Django feature branches, you often encounter migration number conflicts:\n\n```\n# Main branch has:\nmigrations/0010_main_change.py\nmigrations/0011_main_change.py\nmigrations/0012_latest_feature.py\n\n# Your feature branch has:\nmigrations/0010_your_feature.py \u2190 Conflict!\nmigrations/0011_another_change.py \u2190 Conflict!\n```\n\nThis library automatically detects and renumbers conflicting migrations during rebase.\n\n## Installation\n\n```bash\npip install rebase-migrations\n```\n\n## Usage\n\n### Basic Usage\n\n```python\nimport rebase_migrations\n\n# Preview changes\nrebase_migrations.dry_run('/path/to/django/project')\n\n# Apply changes\nrebase_migrations.execute('/path/to/django/project')\n```\n\n### JSON Output\n\nGet machine-readable JSON output for programmatic processing:\n\n```python\nimport rebase_migrations\nimport json\n\njson_output = rebase_migrations.dry_run(\n '/path/to/django/project',\n json=True\n)\n\nif json_output:\n data = json.loads(json_output)\n print(json.dumps(data, indent=2))\n```\n\nExample JSON structure:\n```json\n{\n \"apps\": {\n \"myapp\": {\n \"app_name\": \"myapp\",\n \"last_common_migration\": \"0001_initial\",\n \"migration_changes\": [\n {\n \"migration_file_name\": \"0002_add_field\",\n \"file_rename\": {\n \"old_name\": \"0002_add_field\",\n \"new_name\": \"0004_add_field\"\n }\n }\n ],\n \"max_migration_update\": {\n \"old\": \"0003_main_branch\",\n \"new\": \"0004_add_field\"\n }\n }\n }\n}\n```\n\n### Path Handling\n\nThe library supports various path formats:\n\n```python\n# Absolute paths\nrebase_migrations.execute('/home/user/my-django-project')\n\n# Relative paths\nrebase_migrations.execute('.') # Current directory\nrebase_migrations.execute('../my-project')\n\n# Tilde expansion\nrebase_migrations.execute('~/my-django-project')\n```\n\n### Parameters\n\n#### `execute(path, all_dirs=False)`\n\nApply migration changes immediately.\n\n- **`path`** (str): Path to the Django project directory\n- **`all_dirs`** (bool, optional): If True, scan all directories for migrations. Default: False\n - When False: Skips common directories like `node_modules`, `venv`, `.git`, etc. for better performance\n - When True: Comprehensive scan of all directories (slower but finds migrations in unusual locations)\n\n**Returns:** `None`\n\n#### `dry_run(path, all_dirs=False, json=False)`\n\nPreview changes without applying them.\n\n- **`path`** (str): Path to the Django project directory\n- **`all_dirs`** (bool, optional): If True, scan all directories for migrations. Default: False\n- **`json`** (bool, optional): If True, return JSON output as a string. Default: False\n - Returns `None` if `json=False`\n - Returns JSON string if `json=True`\n\n**Returns:** `Optional[str]` - JSON string if `json=True`, otherwise `None`\n\n#### Single App Functions\n\nFor working with a single Django app:\n\n- **`execute_for_app(app_path)`** - Apply changes to a single app\n- **`dry_run_for_app(app_path, json=False)`** - Preview changes to a single app\n\nBoth accept the same parameters as their project-level counterparts, but take an `app_path` instead of a project `path`.\n\n## How It Works\n\n1. **Discovers migrations**: Finds Django migration files in your project\n2. **Detects conflicts**: Identifies migration number conflicts from git rebase\n3. **Renumbers safely**: Assigns new sequential numbers to resolve conflicts\n4. **Updates dependencies**: Modifies migration dependencies to maintain integrity\n5. **Updates tracking files**: Updates `max_migration.txt` files for django-linear-migrations\n\n## Requirements\n\n- Python 3.8+\n- Django project with migration files following naming convention (`NNNN_name.py`)\n- Git repository\n- **[django-linear-migrations](https://github.com/adamchainz/django-linear-migrations)** package installed and configured\n\nThe library automatically updates `max_migration.txt` files that `django-linear-migrations` uses to track the latest migration in each app.\n\n## Features\n\n- \ud83d\udd0d **Automatic Detection**: Finds migration conflicts during rebase\n- \ud83d\udd04 **Smart Renumbering**: Renumbers migrations to resolve conflicts\n- \ud83d\udd17 **Dependency Updates**: Updates migration dependencies automatically\n- \ud83d\udcc4 **File Updates**: Updates `max_migration.txt` tracking files\n- \ud83e\uddea **Dry Run Mode**: Preview changes before applying them\n- \ud83d\udcca **JSON Output**: Machine-readable output for automation and programmatic use\n- \ud83d\ude80 **Fast Performance**: Skips irrelevant directories by default\n- \ud83d\udee0\ufe0f **Path Flexibility**: Supports relative paths, tilde expansion, and absolute paths\n\n## CLI Alternative\n\nIf you prefer command-line usage, a standalone CLI binary is also available. See the [main repository](https://github.com/reinhash/rebase-migrations) for installation instructions.\n\n## License\n\nMIT License - see [LICENSE](https://github.com/reinhash/rebase-migrations/blob/main/LICENSE) for details.\n\n## Contributing\n\nContributions welcome! Please see the [main repository](https://github.com/reinhash/rebase-migrations) for contributing guidelines.\n",
"bugtrack_url": null,
"license": null,
"summary": "Python library for Django migration conflict resolution during git rebases",
"version": "0.4.0",
"project_urls": {
"Homepage": "https://github.com/reinhash/rebase-migrations",
"Repository": "https://github.com/reinhash/rebase-migrations"
},
"split_keywords": [
"django",
" migrations",
" git",
" rebase",
" conflict-resolution"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "b6bcd262bd9af1d2200a5ac998a77cc61aebf8a3ba7128d33b910472ee740211",
"md5": "0646f6ae2e457aa931c914d17dd9dc7f",
"sha256": "389b55f91c15ffd2fd6b10aec3352ff29c1bafbcde3ea7219d854ae40668184b"
},
"downloads": -1,
"filename": "rebase_migrations-0.4.0-cp38-abi3-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "0646f6ae2e457aa931c914d17dd9dc7f",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 1311165,
"upload_time": "2025-10-06T21:17:20",
"upload_time_iso_8601": "2025-10-06T21:17:20.658368Z",
"url": "https://files.pythonhosted.org/packages/b6/bc/d262bd9af1d2200a5ac998a77cc61aebf8a3ba7128d33b910472ee740211/rebase_migrations-0.4.0-cp38-abi3-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "70b05bd67f2fbd86ec39e7c05f3f28a9267c11500bad6da9d41b85cdbd527593",
"md5": "7fa1c65735121fb583e10cce566ff2c4",
"sha256": "7d47286e47dab0a814264934442d14aa8dac57471a2032a90f6d68d2309a7581"
},
"downloads": -1,
"filename": "rebase_migrations-0.4.0.tar.gz",
"has_sig": false,
"md5_digest": "7fa1c65735121fb583e10cce566ff2c4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 49185,
"upload_time": "2025-10-06T21:17:22",
"upload_time_iso_8601": "2025-10-06T21:17:22.413557Z",
"url": "https://files.pythonhosted.org/packages/70/b0/5bd67f2fbd86ec39e7c05f3f28a9267c11500bad6da9d41b85cdbd527593/rebase_migrations-0.4.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-06 21:17:22",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "reinhash",
"github_project": "rebase-migrations",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "rebase-migrations"
}