lib/eternity/patch.rb in eternity-0.0.3 vs lib/eternity/patch.rb in eternity-0.0.4

- old
+ new

@@ -24,120 +24,90 @@ def delta @delta ||= TransparentProxy.new { calculate_delta } end - end + def base_history + @base_history ||= [base_commit] + base_commit.history + end + def current_history + @current_history ||= [current_commit] + current_commit.history - base_history + end - class Merge - - extend Log - include Common - - def base_delta - @base_delta ||= merged? ? {} : Delta.merge([current_delta, delta]) + def target_history + @target_history ||= [target_commit] + target_commit.history - base_history end - def merged? - @merged ||= current_commit == target_commit || - target_commit.fast_forward?(current_commit) || - current_commit.fast_forward?(target_commit) + def remaining_history + @remaining_history ||= current_history - target_history end private - def current_delta - @current_delta ||= Delta.between target_commit, current_commit - end + def calculate_delta + base_commit.with_index do |base_index| + current_commit.with_index do |current_index| + + current_delta = Delta.merge current_history.reverse.map(&:delta), base_index + target_delta = Delta.merge target_history.reverse.map(&:delta), base_index + revert_delta = Delta.revert current_delta, base_index - def target_delta - @target_delta ||= Delta.between current_commit, target_commit - end + merged_delta = merge_deltas current_delta, target_delta, revert_delta, base_index - def calculate_delta - return {} if merged? + merged_delta.each_with_object({}) do |(collection, elements), hash| + hash[collection] = {} - base_commit.with_index do |base_index| - target_delta.each_with_object({}) do |(collection, elements), hash| - hash[collection] = {} - - elements.each do |id, change| - if change['action'] == INSERT && current_action_for(collection, id) == INSERT - data = ConflictResolver.resolve current_delta[collection][id]['data'], - change['data'] - change = {'action' => UPDATE, 'data' => data} - - elsif change['action'] == UPDATE - if current_action_for(collection, id) == UPDATE - data = ConflictResolver.resolve current_delta[collection][id]['data'], - change['data'], - base_index[collection][id].data - change = change.merge 'data' => data - elsif current_action_for(collection, id) == DELETE - change = {'action' => INSERT, 'data' => change['data']} + elements.each do |id, change| + if change['action'] == UPDATE && current_index[collection][id].sha1 == Blob.digest(Blob.serialize(change['data'])) + change = nil end - - elsif change['action'] == DELETE && current_action_for(collection, id) == DELETE - change = nil + hash[collection][id] = change if change end - hash[collection][id] = change if change + hash.delete collection if hash[collection].empty? end - - hash.delete collection if hash[collection].empty? end end end - def has_current_changes_for?(collection, id) - current_delta.key?(collection) && current_delta[collection].key?(id) - end - - def current_action_for(collection, id) - current_delta[collection][id]['action'] if has_current_changes_for? collection, id - end - - log :calculate_delta end - class Diff - + class Merge extend Log include Common + def merged? + @merged ||= current_commit == target_commit || + target_commit.fast_forward?(current_commit) || + current_commit.fast_forward?(target_commit) + end + private - def current_delta - @current_delta ||= Delta.between base_commit, current_commit + def calculate_delta + return {} if merged? + super end - def target_delta - @target_delta ||= Delta.between base_commit, target_commit + def merge_deltas(current_delta, target_delta, revert_delta, base_index) + remaining_delta = Delta.merge remaining_history.reverse.map(&:delta), base_index + Delta.merge [revert_delta, target_delta, remaining_delta], base_index end - def diff_delta - @diff_delta ||= Delta.merge [Delta.revert(current_delta, base_commit), target_delta] - end + log :calculate_delta + end - def calculate_delta - target_commit.with_index do |target_index| - diff_delta.each_with_object({}) do |(collection, elements), hash| - hash[collection] = {} - elements.each do |id, change| - if change['data'] - sha1 = Blob.digest(Blob.serialize(change['data'])) - change['data'] = target_index[collection][id].data if target_index[collection].include?(id) && sha1 != target_index[collection][id].sha1 - end + class Diff + extend Log + include Common - hash[collection][id] = change if change - end + private - hash.delete collection if hash[collection].empty? - end - end + def merge_deltas(current_delta, target_delta, revert_delta, base_index) + Delta.merge [revert_delta, target_delta], base_index end log :calculate_delta end