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