diff --git a/lib/cri/command.rb b/lib/cri/command.rb
index <HASH>..<HASH> 100644
--- a/lib/cri/command.rb
+++ b/lib/cri/command.rb
@@ -374,7 +374,8 @@ module Cri
         groups["options for #{self.supercommand.name}"] = self.supercommand.global_option_definitions
       end
       length = groups.values.inject(&:+).map { |o| o[:long].to_s.size }.max
-      groups.each_pair do |name, defs|
+      groups.keys.sort.each do |name|
+        defs = groups[name]
         unless defs.empty?
           text << "\n"
           text << "#{name}".formatted_as_title
diff --git a/test/test_command.rb b/test/test_command.rb
index <HASH>..<HASH> 100644
--- a/test/test_command.rb
+++ b/test/test_command.rb
@@ -276,6 +276,12 @@ class Cri::CommandTestCase < Cri::TestCase
     assert_match(/^\e\[33m    -s           \e\[0mshort$/, help)
   end
 
+  def test_help_with_multiple_groups
+    help = nested_cmd.subcommands.find { |cmd| cmd.name == 'sub' }.help
+
+    assert_match(/OPTIONS.*OPTIONS FOR SUPER/m,  help)
+  end
+
   def test_modify_with_block_argument
     cmd = Cri::Command.define do |c|
       c.name 'build'
Show option groups in consistent order (fixes #<I>)

This fix is intended for Ruby <I>.x, where hashes are not ordered.