diff --git a/helix-core/src/history.rs b/helix-core/src/history.rs
index 5f9fa71e..82509242 100644
--- a/helix-core/src/history.rs
+++ b/helix-core/src/history.rs
@@ -126,16 +126,27 @@ impl History {
 
         match revision.cmp(&self.current) {
             Equal => None,
-            Greater => self.revisions[self.current + 1..=revision]
-                .iter()
-                .map(|revision| &revision.inversion)
-                .cloned()
-                .reduce(|acc, inversion| acc.compose(inversion)),
-            Less => self.revisions[revision + 1..=self.current]
-                .iter()
-                .map(|revision| &revision.transaction)
-                .cloned()
-                .reduce(|acc, transaction| acc.compose(transaction)),
+            Less => {
+                let mut child = self.revisions[revision].last_child?.get();
+                let mut transaction = self.revisions[child].transaction.clone();
+                while child != self.current {
+                    child = self.revisions[child].last_child?.get();
+                    transaction = transaction.compose(self.revisions[child].transaction.clone());
+                }
+                Some(transaction)
+            }
+            Greater => {
+                let mut inversion = self.revisions[revision].inversion.clone();
+                let mut parent = self.revisions[revision].parent;
+                while parent != self.current {
+                    parent = self.revisions[parent].parent;
+                    if parent == 0 {
+                        return None;
+                    }
+                    inversion = inversion.compose(self.revisions[parent].inversion.clone());
+                }
+                Some(inversion)
+            }
         }
     }
 
diff --git a/helix-term/tests/test/commands.rs b/helix-term/tests/test/commands.rs
index 01295704..95bd95b7 100644
--- a/helix-term/tests/test/commands.rs
+++ b/helix-term/tests/test/commands.rs
@@ -306,5 +306,8 @@ async fn test_undo_redo() -> anyhow::Result<()> {
     // * <C-i>       Jump forward to line 1.
     test(("#[|]#", "[<space><C-s>kduU<C-o><C-i>", "#[|]#")).await?;
 
+    // In this case we 'redo' manually to ensure that the transactions are composing correctly.
+    test(("#[|]#", "[<space>u[<space>u", "#[|]#")).await?;
+
     Ok(())
 }