Last active
June 21, 2024 01:37
-
-
Save jbradberry/ab47ba6f8567473f06bd4015020c3ef5 to your computer and use it in GitHub Desktop.
Re-number Django migrations during a rebase, use like `$ git rebase -i devel --exec "python3 rebase_migrations.py"`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import defaultdict | |
from pathlib import Path | |
import re | |
import subprocess | |
changed_files = subprocess.check_output("git diff-tree --no-commit-id --name-status -r HEAD", shell=True) | |
changed_status = [line.split('\t') for line in changed_files.decode('utf-8').rstrip('\n').split('\n')] | |
changed_migrations = {fname for status, fname in changed_status | |
if '/migrations/' in fname and Path(fname).name[0].isdigit() and status != 'D'} | |
if changed_migrations: | |
print("Changed migrations: {}".format(changed_migrations)) | |
migrations = defaultdict(list) | |
for m in sorted(changed_migrations): | |
migrations[Path(m).parent].append(m) | |
for d, S in migrations.items(): | |
existing_migrations = sorted( | |
f for f in Path(d).iterdir() | |
if f.is_file() and f.name[0].isdigit() and f.name.endswith('.py') and str(f) not in S | |
) | |
existing_numbers = [int(f.name[:4], base=10) for f in existing_migrations] | |
for m in S: | |
migration = Path(m) | |
num = int(migration.name[:4], base=10) | |
if num in existing_numbers: | |
with open(m) as f: | |
contents = f.read() | |
print('git rm', m) | |
subprocess.check_output(['git', 'rm', m]) | |
updated = re.sub( | |
r'{:04d}_[a-zA-Z0-9_]*'.format(num - 1), | |
max(existing_migrations).name[:-3], | |
contents | |
) | |
migration = d / '{:04d}{}'.format(max(existing_numbers) + 1, migration.name[4:]) | |
with migration.open('w') as f: | |
f.write(updated) | |
print('git add', str(migration)) | |
subprocess.check_output(['git', 'add', str(migration)]) | |
existing_migrations.append(migration) | |
existing_numbers.append(num) | |
subprocess.check_output("git commit --amend --no-edit", shell=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment