Merge branch 'stable'
[stgit] / stgit / commands / sync.py
index 8a31c29..35c5c31 100644 (file)
@@ -36,9 +36,9 @@ in the series must apply cleanly.
 
 The sync operation can be reverted for individual patches with --undo."""
 
-directory = DirectoryHasRepository()
+directory = DirectoryGotoToplevel()
 options = [make_option('-a', '--all',
-                       help = 'synchronise all the patches',
+                       help = 'synchronise all the applied patches',
                        action = 'store_true'),
            make_option('-B', '--ref-branch',
                        help = 'syncronise patches with BRANCH'),
@@ -51,13 +51,13 @@ options = [make_option('-a', '--all',
 def __check_all():
     check_local_changes()
     check_conflicts()
-    check_head_top_equal()
+    check_head_top_equal(crt_series)
 
 def __branch_merge_patch(remote_series, pname):
     """Merge a patch from a remote branch into the current tree.
     """
     patch = remote_series.get_patch(pname)
-    git.merge(patch.get_bottom(), git.get_head(), patch.get_top())
+    git.merge_recursive(patch.get_bottom(), git.get_head(), patch.get_top())
 
 def __series_merge_patch(base, patchdir, pname):
     """Merge a patch file with the given StGIT patch.
@@ -108,11 +108,13 @@ def func(parser, options, args):
         raise CmdException, 'No remote branch or series specified'
 
     applied = crt_series.get_applied()
+    unapplied = crt_series.get_unapplied()
     
     if options.all:
         patches = applied
     elif len(args) != 0:
-        patches = parse_patches(args, applied, ordered = True)
+        patches = parse_patches(args, applied + unapplied, len(applied),
+                                ordered = True)
     elif applied:
         patches = [crt_series.get_current()]
     else:
@@ -129,16 +131,22 @@ def func(parser, options, args):
         raise CmdException, 'No common patches to be synchronised'
 
     # pop to the one before the first patch to be synchronised
-    popped = applied[applied.index(sync_patches[0]) + 1:]
-    if popped:
-        pop_patches(popped[::-1])
+    first_patch = sync_patches[0]
+    if first_patch in applied:
+        to_pop = applied[applied.index(first_patch) + 1:]
+        if to_pop:
+            pop_patches(crt_series, to_pop[::-1])
+    else:
+        to_pop = []
+    popped = to_pop + [p for p in patches if p in unapplied]
 
-    for p in sync_patches:
+    for p in [first_patch] + popped:
         if p in popped:
-            # push to this patch
-            idx = popped.index(p) + 1
-            push_patches(popped[:idx])
-            del popped[:idx]
+            # push this patch
+            push_patches(crt_series, [p])
+        if p not in sync_patches:
+            # nothing to synchronise
+            continue
 
         # the actual sync
         out.start('Synchronising "%s"' % p)
@@ -149,7 +157,6 @@ def func(parser, options, args):
 
         # reset the patch backup information. That's needed in case we
         # undo the sync but there were no changes made
-        patch.set_bottom(bottom, backup = True)
         patch.set_top(top, backup = True)
 
         # the actual merging (either from a branch or an external file)
@@ -163,7 +170,3 @@ def func(parser, options, args):
             out.done('updated')
         else:
             out.done()
-
-    # push the remaining patches
-    if popped:
-        push_patches(popped)