diff --git a/pcbnew/tools/multichannel_tool.cpp b/pcbnew/tools/multichannel_tool.cpp
index 654a5e73d0..e8561e41dc 100644
--- a/pcbnew/tools/multichannel_tool.cpp
+++ b/pcbnew/tools/multichannel_tool.cpp
@@ -501,12 +501,10 @@ int MULTICHANNEL_TOOL::RepeatLayout( const TOOL_EVENT& aEvent, ZONE* aRefZone )
         if( !targetArea.second.m_isOk )
             continue;
 
-        std::unordered_set<BOARD_ITEM*> affectedItems;
-        std::unordered_set<BOARD_ITEM*> groupableItems;
 
         if( !copyRuleAreaContents( targetArea.second.m_matchingComponents, &commit, m_areas.m_refRA,
-                                   targetArea.first, m_areas.m_options, affectedItems,
-                                   groupableItems ) )
+                                   targetArea.first, m_areas.m_options, targetArea.second.m_affectedItems,
+                                   targetArea.second.m_groupableItems ) )
         {
             auto errMsg = wxString::Format(
                     _( "Copy Rule Area contents failed between rule areas '%s' and '%s'." ),
@@ -522,26 +520,34 @@ int MULTICHANNEL_TOOL::RepeatLayout( const TOOL_EVENT& aEvent, ZONE* aRefZone )
 
             return -1;
         }
-
-        if( m_areas.m_options.m_groupItems )
-        {
-            pruneExistingGroups( commit, affectedItems );
-
-            PCB_GROUP* grp = new PCB_GROUP( board() );
-
-            commit.Add( grp );
-
-            for( BOARD_ITEM* item : groupableItems )
-            {
-                commit.Stage( item, CHT_GROUP );
-            }
-        }
-
         totalCopied++;
     }
 
+
     commit.Push( _( "Repeat layout" ) );
 
+    if( m_areas.m_options.m_groupItems )
+    {
+        BOARD_COMMIT grpCommit( GetManager(), true );
+
+        for( auto& targetArea : m_areas.m_compatMap )
+        {
+            pruneExistingGroups( grpCommit, targetArea.second.m_affectedItems );
+
+            PCB_GROUP* grp = new PCB_GROUP( board() );
+
+            grpCommit.Add( grp );
+
+            for( BOARD_ITEM* item : targetArea.second.m_groupableItems )
+            {
+                grpCommit.Stage( item, CHT_GROUP );
+            }
+        }
+
+        grpCommit.Push( _( "Group repeated items" ) );
+    }
+
+
     if( Pgm().IsGUI() )
     {
         frame()->ShowInfoBarMsg( wxString::Format( _( "Copied to %d Rule Areas." ), totalCopied ),
@@ -998,14 +1004,21 @@ bool MULTICHANNEL_TOOL::resolveConnectionTopology( RULE_AREA* aRefArea, RULE_ARE
 bool MULTICHANNEL_TOOL::pruneExistingGroups( COMMIT& aCommit,
                                              const std::unordered_set<BOARD_ITEM*>& aItemsToRemove )
 {
-    for( PCB_GROUP* grp : board()->Groups() )
+    std::deque<PCB_GROUP*> pending ( board()->Groups() );
+    while( !pending.empty() )
     {
+        auto grp = pending.front();
+        pending.pop_front();
+
         std::unordered_set<BOARD_ITEM*>& grpItems = grp->GetItems();
         size_t n_erased = 0;
 
         for( BOARD_ITEM* refItem : grpItems )
         {
-            //printf("check ref %p [%s]\n", refItem, refItem->GetTypeDesc().c_str().AsChar() );
+
+            if( refItem->Type() == PCB_GROUP_T )
+                pending.push_back( static_cast<PCB_GROUP*>(refItem) );
+                
             for( BOARD_ITEM* testItem : aItemsToRemove )
             {
                 if( refItem->m_Uuid == testItem->m_Uuid )
@@ -1021,7 +1034,6 @@ bool MULTICHANNEL_TOOL::pruneExistingGroups( COMMIT& aCommit,
             aCommit.Stage( grp, CHT_REMOVE );
         }
 
-        //printf("Grp %p items %d pruned %d air %d\n", grp,grpItems.size(), (int) n_erased, (int) aItemsToRemove.size() );
     }
 
     return false;
diff --git a/pcbnew/tools/multichannel_tool.h b/pcbnew/tools/multichannel_tool.h
index a0b4b77d7a..243ead0646 100644
--- a/pcbnew/tools/multichannel_tool.h
+++ b/pcbnew/tools/multichannel_tool.h
@@ -68,6 +68,8 @@ struct RULE_AREA_COMPAT_DATA
     bool                      m_doCopy = false;
     wxString                  m_errorMsg;
     TMATCH::COMPONENT_MATCHES m_matchingComponents;
+    std::unordered_set<BOARD_ITEM*> m_affectedItems;
+    std::unordered_set<BOARD_ITEM*> m_groupableItems;
 };
 
 struct RULE_AREA