@@ -122,32 +122,16 @@ impl History {
122122 /// Returns the changes since the given revision composed into a transaction.
123123 /// Returns None if there are no changes between the current and given revisions.
124124 pub fn changes_since(&self, revision: usize) -> Option<Transaction> {
125− use std::cmp::Ordering::*;
125+ let lca = self.lowest_common_ancestor(revision, self.current);
126+ let up = self.path_up(revision, lca);
127+ let down = self.path_up(self.current, lca);
128+ let up_txns = up
129+ .iter()
130+ .rev()
131+ .map(|&n| self.revisions[n].inversion.clone());
132+ let down_txns = down.iter().map(|&n| self.revisions[n].transaction.clone());
126133
127− match revision.cmp(&self.current) {
128− Equal => None,
129− Less => {
130− let mut child = self.revisions[revision].last_child?.get();
131− let mut transaction = self.revisions[child].transaction.clone();
132− while child != self.current {
133− child = self.revisions[child].last_child?.get();
134− transaction = transaction.compose(self.revisions[child].transaction.clone());
135− }
136− Some(transaction)
137− }
138− Greater => {
139− let mut inversion = self.revisions[revision].inversion.clone();
140− let mut parent = self.revisions[revision].parent;
141− while parent != self.current {
142− parent = self.revisions[parent].parent;
143− if parent == 0 {
144− return None;
145− }
146− inversion = inversion.compose(self.revisions[parent].inversion.clone());
147− }
148− Some(inversion)
149− }
150− }
134+ up_txns.chain(down_txns).reduce(|acc, tx| tx.compose(acc))
151135 }
152136
153137 /// Undo the last edit.