Commits

Andrew Godwin committed 8651d12

Rebase work I found.

Comments (0)

Files changed (4)

south/management/commands/migrate.py

 def format_migration_list_item(migration, applied=True):
     if applied:
         return '  (*) %s' % migration.name()
-    elif migration.is_rebase:
+    elif migration.is_rebase():
         return '  (R) %s' % migration.name()
     return '  ( ) %s' % migration.name()

south/migration/__init__.py

     return [m for m in forwards if m not in done]
 
 def to_unapply(backwards, done):
-    return [m for m in backwards if m in done]
+    return [m for m in backwards if (m in done) or m.is_rebase()]
 
 def problems(pending, done):
     last = None
 
 def get_dependencies(target, migrations):
     forwards = lambda allow_rebase=False: list()
-    backwards = list
+    backwards = lambda allow_rebase=False: list()
     if target is None:
         backwards = migrations[0].backwards_plan
     else:
     forwards, backwards = get_dependencies(target, migrations)
     # Is the whole forward branch applied?
     problems = None
-    forwards = forwards(allow_rebase=not applied)
-    workplan = to_apply(forwards, applied)
+    if target is not None:
+        forwards = forwards(allow_rebase = not [x for x in applied if x.migrations is target.migrations])
+        workplan = to_apply(forwards, applied)
+    else:
+        workplan = None
+    # See if there's some forward work to be done.
     if not workplan:
         # If they're all applied, we only know it's not backwards
         direction = None
         direction = Forwards(verbosity=verbosity, interactive=interactive)
     if not problems:
         # What about the whole backward trace then?
-        backwards = backwards()
+        backwards = backwards(allow_rebase=target is None)
         missing_backwards = to_apply(backwards, applied)
         if missing_backwards != backwards:
             # If what's missing is a strict left segment of backwards (i.e.
             # all the higher migrations) then we need to go backwards
             workplan = to_unapply(backwards, applied)
-            problems = backwards_problems(backwards, applied, verbosity)
+            problems = backwards_problems(
+                [x for x in backwards if not x.is_rebase()],
+                applied,
+                verbosity,
+            )
             direction = Backwards(verbosity=verbosity, interactive=interactive)
     return direction, problems, workplan
 

south/migration/base.py

                     new_plan.insert(0, item)
         return new_plan
 
-    def backwards_plan(self):
+    def backwards_plan(self, allow_rebase=False):
         """
         Returns a list of Migration objects to be unapplied, in order.
 
         This list includes `self`, which will be unapplied last.
         """
-        return depends(self, lambda x: x.dependents)
+        base_plan = depends(self, lambda x: x.dependents)
+        new_plan = []
+        for item in base_plan:
+            if allow_rebase:
+                new_plan.append(item)
+                if item.is_rebase():
+                    break
+            else:
+                if not item.is_rebase():
+                    new_plan.append(item)
+        return new_plan
+        
 
     def is_before(self, other):
         if self.migrations == other.migrations:

south/migration/migrators.py

             else:
                 # Django 1.1 always goes down here
                 record.delete()
+        # If this is a rebase migration, delete all remaining records for
+        # this app, too.
+        if migration.is_rebase():
+            MigrationHistory.objects.filter(app_label = record.app_label).delete()
 
     def migrate_many(self, target, migrations, database):
         for migration in migrations: