eternity 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/eternity/blob.rb +9 -2
- data/lib/eternity/commit.rb +36 -13
- data/lib/eternity/delta.rb +29 -21
- data/lib/eternity/patch.rb +47 -77
- data/lib/eternity/repository.rb +9 -9
- data/lib/eternity/version.rb +1 -1
- data/spec/delta_spec.rb +107 -10
- data/spec/history_spec.rb +102 -0
- data/spec/log_spec.rb +3 -4
- data/spec/merge_spec.rb +134 -0
- data/spec/minitest_helper.rb +0 -34
- data/spec/patch_spec.rb +3 -16
- data/spec/pull_spec.rb +10 -8
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 319437ad396ef5f306feb9578edf4a890dc2ecfc
|
4
|
+
data.tar.gz: e2ae5f04b986d60ab7a5fdcd26fe3c7614f0c1a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c95bcefe396e0751d1165ae01b69d7500b277c2ab48228c82fda06f5bae0de1c7b651c02852c9b3b9035d8c68521c05f2ba071e47576507861d0ed8c4976656f
|
7
|
+
data.tar.gz: b1082bb669fedc219e0a82326ecbb8298e70cc0365393935cf49384c1f92533342c1af44891cdb100687d1b6ffc29da32107fe5784474b2080ca59fdfb6b158a
|
data/lib/eternity/blob.rb
CHANGED
@@ -41,8 +41,15 @@ module Eternity
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def normalize(data)
|
44
|
-
|
45
|
-
|
44
|
+
case data
|
45
|
+
when Hash
|
46
|
+
sorted_data = Hash[data.sort_by { |k,v| k.to_s }]
|
47
|
+
sorted_data.each { |k,v| sorted_data[k] = v.utc.strftime TIME_FORMAT if v.respond_to? :utc }
|
48
|
+
when Array
|
49
|
+
data.map { |d| normalize d }
|
50
|
+
else
|
51
|
+
data
|
52
|
+
end
|
46
53
|
end
|
47
54
|
|
48
55
|
def clear_cache
|
data/lib/eternity/commit.rb
CHANGED
@@ -46,19 +46,37 @@ module Eternity
|
|
46
46
|
Commit.new data['base']
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
50
|
-
|
49
|
+
def history_ids
|
50
|
+
if data['history']
|
51
|
+
Blob.read :history, data['history']
|
52
|
+
else
|
53
|
+
# Backward compatibility
|
54
|
+
cache_key = Eternity.keyspace[:cache][:history][id]
|
55
|
+
return Eternity.redis.call 'LRANGE', cache_key, 0, -1 if Eternity.redis.call('EXISTS', cache_key) == 1
|
56
|
+
|
57
|
+
commit_ids =
|
58
|
+
if parent_ids.count == 2
|
59
|
+
current_history_ids = [parent_ids[0]] + Commit.new(parent_ids[0]).history_ids
|
60
|
+
target_history_ids = [parent_ids[1]] + Commit.new(parent_ids[1]).history_ids
|
61
|
+
current_history_ids - target_history_ids + target_history_ids
|
62
|
+
else
|
63
|
+
parent_id = parent_ids[0]
|
64
|
+
parent_id ? [parent_id] + Commit.new(parent_id).history_ids : []
|
65
|
+
end
|
66
|
+
|
67
|
+
Eternity.redis.call 'RPUSH', cache_key, *commit_ids
|
68
|
+
|
69
|
+
commit_ids
|
70
|
+
end
|
51
71
|
end
|
52
72
|
|
53
73
|
def history
|
54
|
-
|
55
|
-
.map { |id, time| Commit.new id }
|
56
|
-
.reverse
|
74
|
+
history_ids.map { |id| Commit.new id }
|
57
75
|
end
|
58
76
|
|
59
77
|
def fast_forward?(commit)
|
60
78
|
return true if commit.nil?
|
61
|
-
|
79
|
+
history_ids.include? commit.id
|
62
80
|
end
|
63
81
|
|
64
82
|
def first?
|
@@ -91,21 +109,26 @@ module Eternity
|
|
91
109
|
raise 'Author must be present' if options[:author].to_s.strip.empty?
|
92
110
|
raise 'Message must be present' if options[:message].to_s.strip.empty?
|
93
111
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
112
|
+
# TODO: Move to Repository and Patch
|
113
|
+
history =
|
114
|
+
if options[:parents].count == 2
|
115
|
+
current_history_ids = [options[:parents][0]] + Commit.new(options[:parents][0]).history_ids
|
116
|
+
target_history_ids = [options[:parents][1]] + Commit.new(options[:parents][1]).history_ids
|
117
|
+
current_history_ids - target_history_ids + target_history_ids
|
118
|
+
else
|
119
|
+
parent_id = options[:parents][0]
|
120
|
+
parent_id ? [parent_id] + Commit.new(parent_id).history_ids : []
|
121
|
+
end
|
99
122
|
|
100
123
|
data = {
|
101
|
-
time:
|
124
|
+
time: Time.now,
|
102
125
|
author: options.fetch(:author),
|
103
126
|
message: options.fetch(:message),
|
104
127
|
parents: options.fetch(:parents),
|
105
128
|
index: options.fetch(:index),
|
106
129
|
delta: options.fetch(:delta),
|
107
130
|
base: options[:parents].count == 2 ? options.fetch(:base) : options[:parents].first,
|
108
|
-
|
131
|
+
history: Blob.write(:history, history)
|
109
132
|
}
|
110
133
|
|
111
134
|
new Blob.write(:commit, data)
|
data/lib/eternity/delta.rb
CHANGED
@@ -14,33 +14,41 @@ module Eternity
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def merge(deltas)
|
17
|
+
def merge(deltas, base_index)
|
18
18
|
union(deltas).each_with_object({}) do |(collection, elements), hash|
|
19
19
|
hash[collection] = {}
|
20
20
|
elements.each do |id, changes|
|
21
|
-
|
22
|
-
|
21
|
+
base_data = base_index[collection].include?(id) ? base_index[collection][id].data : {}
|
22
|
+
changes.each do |change|
|
23
|
+
current_change = change
|
24
|
+
if hash[collection][id]
|
25
|
+
current_change = TrackFlatter.flatten [hash[collection][id], change]
|
26
|
+
if current_change && [INSERT, UPDATE].include?(current_change['action'])
|
27
|
+
current_change['data'] = ConflictResolver.resolve hash[collection][id]['data'] || base_data,
|
28
|
+
change['data'],
|
29
|
+
base_data
|
30
|
+
end
|
31
|
+
elsif hash[collection].key?(id) && change['action'] == DELETE
|
32
|
+
current_change = nil
|
33
|
+
end
|
34
|
+
hash[collection][id] = current_change
|
35
|
+
end
|
36
|
+
hash[collection].delete id unless hash[collection][id]
|
23
37
|
end
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def between(commit_1, commit_2)
|
28
|
-
commits = ([commit_2] + commit_2.history) - ([commit_1] + commit_1.history)
|
29
|
-
merge commits.reverse.map(&:delta)
|
38
|
+
hash.delete collection if hash[collection].empty?
|
39
|
+
end
|
30
40
|
end
|
31
41
|
|
32
|
-
def revert(delta,
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
42
|
+
def revert(delta, index)
|
43
|
+
delta.each_with_object({}) do |(collection, changes), hash|
|
44
|
+
hash[collection] = {}
|
45
|
+
changes.each do |id, change|
|
46
|
+
hash[collection][id] =
|
47
|
+
case change['action']
|
48
|
+
when INSERT then {'action' => DELETE}
|
49
|
+
when UPDATE then {'action' => UPDATE, 'data' => index[collection][id].data}
|
50
|
+
when DELETE then {'action' => INSERT, 'data' => index[collection][id].data}
|
51
|
+
end
|
44
52
|
end
|
45
53
|
end
|
46
54
|
end
|
data/lib/eternity/patch.rb
CHANGED
@@ -26,117 +26,87 @@ module Eternity
|
|
26
26
|
@delta ||= TransparentProxy.new { calculate_delta }
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
29
|
+
def base_history
|
30
|
+
@base_history ||= [base_commit] + base_commit.history
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
include Common
|
33
|
+
def current_history
|
34
|
+
@current_history ||= [current_commit] + current_commit.history - base_history
|
35
|
+
end
|
36
36
|
|
37
|
-
def
|
38
|
-
@
|
37
|
+
def target_history
|
38
|
+
@target_history ||= [target_commit] + target_commit.history - base_history
|
39
39
|
end
|
40
40
|
|
41
|
-
def
|
42
|
-
@
|
43
|
-
target_commit.fast_forward?(current_commit) ||
|
44
|
-
current_commit.fast_forward?(target_commit)
|
41
|
+
def remaining_history
|
42
|
+
@remaining_history ||= current_history - target_history
|
45
43
|
end
|
46
44
|
|
47
45
|
private
|
48
46
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
47
|
+
def calculate_delta
|
48
|
+
base_commit.with_index do |base_index|
|
49
|
+
current_commit.with_index do |current_index|
|
50
|
+
|
51
|
+
current_delta = Delta.merge current_history.reverse.map(&:delta), base_index
|
52
|
+
target_delta = Delta.merge target_history.reverse.map(&:delta), base_index
|
53
|
+
revert_delta = Delta.revert current_delta, base_index
|
52
54
|
|
53
|
-
|
54
|
-
@target_delta ||= Delta.between current_commit, target_commit
|
55
|
-
end
|
55
|
+
merged_delta = merge_deltas current_delta, target_delta, revert_delta, base_index
|
56
56
|
|
57
|
-
|
58
|
-
|
57
|
+
merged_delta.each_with_object({}) do |(collection, elements), hash|
|
58
|
+
hash[collection] = {}
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
elements.each do |id, change|
|
65
|
-
if change['action'] == INSERT && current_action_for(collection, id) == INSERT
|
66
|
-
data = ConflictResolver.resolve current_delta[collection][id]['data'],
|
67
|
-
change['data']
|
68
|
-
change = {'action' => UPDATE, 'data' => data}
|
69
|
-
|
70
|
-
elsif change['action'] == UPDATE
|
71
|
-
if current_action_for(collection, id) == UPDATE
|
72
|
-
data = ConflictResolver.resolve current_delta[collection][id]['data'],
|
73
|
-
change['data'],
|
74
|
-
base_index[collection][id].data
|
75
|
-
change = change.merge 'data' => data
|
76
|
-
elsif current_action_for(collection, id) == DELETE
|
77
|
-
change = {'action' => INSERT, 'data' => change['data']}
|
60
|
+
elements.each do |id, change|
|
61
|
+
if change['action'] == UPDATE && current_index[collection][id].sha1 == Blob.digest(Blob.serialize(change['data']))
|
62
|
+
change = nil
|
78
63
|
end
|
79
|
-
|
80
|
-
elsif change['action'] == DELETE && current_action_for(collection, id) == DELETE
|
81
|
-
change = nil
|
64
|
+
hash[collection][id] = change if change
|
82
65
|
end
|
83
66
|
|
84
|
-
hash
|
67
|
+
hash.delete collection if hash[collection].empty?
|
85
68
|
end
|
86
|
-
|
87
|
-
hash.delete collection if hash[collection].empty?
|
88
69
|
end
|
89
70
|
end
|
90
71
|
end
|
91
72
|
|
92
|
-
def has_current_changes_for?(collection, id)
|
93
|
-
current_delta.key?(collection) && current_delta[collection].key?(id)
|
94
|
-
end
|
95
|
-
|
96
|
-
def current_action_for(collection, id)
|
97
|
-
current_delta[collection][id]['action'] if has_current_changes_for? collection, id
|
98
|
-
end
|
99
|
-
|
100
|
-
log :calculate_delta
|
101
73
|
end
|
102
74
|
|
103
75
|
|
104
|
-
class
|
105
|
-
|
76
|
+
class Merge
|
106
77
|
extend Log
|
107
78
|
include Common
|
108
79
|
|
80
|
+
def merged?
|
81
|
+
@merged ||= current_commit == target_commit ||
|
82
|
+
target_commit.fast_forward?(current_commit) ||
|
83
|
+
current_commit.fast_forward?(target_commit)
|
84
|
+
end
|
85
|
+
|
109
86
|
private
|
110
87
|
|
111
|
-
def
|
112
|
-
|
88
|
+
def calculate_delta
|
89
|
+
return {} if merged?
|
90
|
+
super
|
113
91
|
end
|
114
92
|
|
115
|
-
def target_delta
|
116
|
-
|
93
|
+
def merge_deltas(current_delta, target_delta, revert_delta, base_index)
|
94
|
+
remaining_delta = Delta.merge remaining_history.reverse.map(&:delta), base_index
|
95
|
+
Delta.merge [revert_delta, target_delta, remaining_delta], base_index
|
117
96
|
end
|
118
97
|
|
119
|
-
|
120
|
-
|
121
|
-
end
|
98
|
+
log :calculate_delta
|
99
|
+
end
|
122
100
|
|
123
|
-
def calculate_delta
|
124
|
-
target_commit.with_index do |target_index|
|
125
|
-
diff_delta.each_with_object({}) do |(collection, elements), hash|
|
126
|
-
hash[collection] = {}
|
127
|
-
|
128
|
-
elements.each do |id, change|
|
129
|
-
if change['data']
|
130
|
-
sha1 = Blob.digest(Blob.serialize(change['data']))
|
131
|
-
change['data'] = target_index[collection][id].data if target_index[collection].include?(id) && sha1 != target_index[collection][id].sha1
|
132
|
-
end
|
133
101
|
|
134
|
-
|
135
|
-
|
102
|
+
class Diff
|
103
|
+
extend Log
|
104
|
+
include Common
|
136
105
|
|
137
|
-
|
138
|
-
|
139
|
-
|
106
|
+
private
|
107
|
+
|
108
|
+
def merge_deltas(current_delta, target_delta, revert_delta, base_index)
|
109
|
+
Delta.merge [revert_delta, target_delta], base_index
|
140
110
|
end
|
141
111
|
|
142
112
|
log :calculate_delta
|
data/lib/eternity/repository.rb
CHANGED
@@ -62,8 +62,7 @@ module Eternity
|
|
62
62
|
|
63
63
|
locker.lock! :commit do
|
64
64
|
commit! message: options.fetch(:message),
|
65
|
-
author: options.fetch(:author)
|
66
|
-
time: options.fetch(:time) { Time.now }
|
65
|
+
author: options.fetch(:author)
|
67
66
|
end
|
68
67
|
end
|
69
68
|
|
@@ -134,7 +133,9 @@ module Eternity
|
|
134
133
|
|
135
134
|
def revert
|
136
135
|
locker.lock! :revert do
|
137
|
-
|
136
|
+
current_commit.with_index do |index|
|
137
|
+
Delta.revert(delta, index).tap { tracker.revert }
|
138
|
+
end
|
138
139
|
end
|
139
140
|
end
|
140
141
|
|
@@ -189,12 +190,11 @@ module Eternity
|
|
189
190
|
|
190
191
|
raise 'Already merged' if patch.merged?
|
191
192
|
|
192
|
-
commit! message:
|
193
|
-
author:
|
194
|
-
parents:
|
195
|
-
index:
|
196
|
-
base:
|
197
|
-
base_delta: Blob.write(:delta, patch.base_delta)
|
193
|
+
commit! message: "Merge #{target_commit.short_id} into #{current_commit.short_id} (#{name})",
|
194
|
+
author: 'System',
|
195
|
+
parents: [current_commit.id, target_commit.id],
|
196
|
+
index: write_index(patch.delta),
|
197
|
+
base: patch.base_commit.id
|
198
198
|
|
199
199
|
patch.delta
|
200
200
|
end
|
data/lib/eternity/version.rb
CHANGED
data/spec/delta_spec.rb
CHANGED
@@ -6,7 +6,15 @@ describe 'Delta' do
|
|
6
6
|
let(:repo_2) { Repository.new :test_2 }
|
7
7
|
let(:repo_3) { Repository.new :test_3 }
|
8
8
|
|
9
|
-
it 'Merge
|
9
|
+
it 'Merge -> Checkout (2 times)' do
|
10
|
+
# P P P
|
11
|
+
# REPO 1: (*)--(1)---(4)---(5) (6)--(8) (10)
|
12
|
+
# \ \ / \ / \
|
13
|
+
# REPO 2: -(2)--(3)---(6)--(7)--(9)--(10) \
|
14
|
+
# \ MP M P \
|
15
|
+
# REPO 3: ------(11) (10)
|
16
|
+
#
|
17
|
+
|
10
18
|
repo_1[:countries].insert 'AR', name: 'Argentina'
|
11
19
|
commit_1 = repo_1.commit author: 'User 1', message: 'Commit 1'
|
12
20
|
repo_1.push
|
@@ -17,10 +25,10 @@ describe 'Delta' do
|
|
17
25
|
repo_2[:countries].insert 'BR', name: 'Brasil'
|
18
26
|
commit_2 = repo_2.commit author: 'User 2', message: 'Commit 2'
|
19
27
|
|
20
|
-
repo_2[:countries].update 'AR', name: 'Argentina',
|
28
|
+
repo_2[:countries].update 'AR', name: 'Argentina', number: 54, capital: 'CABA'
|
21
29
|
commit_3 = repo_2.commit author: 'User 2', message: 'Commit 3'
|
22
30
|
|
23
|
-
repo_1[:countries].update 'AR', name: 'Argentina', capital: '
|
31
|
+
repo_1[:countries].update 'AR', name: 'Argentina', capital: '...', code: 'ARG'
|
24
32
|
commit_4 = repo_1.commit author: 'User 1', message: 'Commit 4'
|
25
33
|
|
26
34
|
repo_1[:countries].insert 'CL', name: 'Chile'
|
@@ -32,12 +40,12 @@ describe 'Delta' do
|
|
32
40
|
commit_6 = repo_2.current_commit # Merge
|
33
41
|
|
34
42
|
delta.must_equal 'countries' => {
|
35
|
-
'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina', '
|
43
|
+
'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina', 'number' => 54, 'code' => 'ARG', 'capital' => 'CABA'}},
|
36
44
|
'CL' => {'action' => 'insert', 'data' => {'name' => 'Chile'}}
|
37
45
|
}
|
38
46
|
|
39
47
|
commit_6.must_equal_index 'countries' => {
|
40
|
-
'AR' => digest(name: 'Argentina',
|
48
|
+
'AR' => digest(name: 'Argentina', number: 54, code: 'ARG', capital: 'CABA'),
|
41
49
|
'BR' => digest(name: 'Brasil'),
|
42
50
|
'CL' => digest(name: 'Chile')
|
43
51
|
}
|
@@ -49,9 +57,8 @@ describe 'Delta' do
|
|
49
57
|
repo_1.current_commit.must_equal commit_6
|
50
58
|
|
51
59
|
delta.must_equal 'countries' => {
|
52
|
-
'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina', '
|
53
|
-
'BR' => {'action' => 'insert', 'data' => {'name' => 'Brasil'}}
|
54
|
-
'CL' => {'action' => 'update', 'data' => {'name' => 'Chile'}}
|
60
|
+
'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina', 'number' => 54, 'code' => 'ARG', 'capital' => 'CABA'}},
|
61
|
+
'BR' => {'action' => 'insert', 'data' => {'name' => 'Brasil'}}
|
55
62
|
}
|
56
63
|
|
57
64
|
repo_2[:countries].delete 'CL'
|
@@ -71,7 +78,7 @@ describe 'Delta' do
|
|
71
78
|
}
|
72
79
|
|
73
80
|
commit_9.must_equal_index 'countries' => {
|
74
|
-
'AR' => digest(name: 'Argentina',
|
81
|
+
'AR' => digest(name: 'Argentina', number: 54, code: 'ARG', capital: 'CABA'),
|
75
82
|
'BR' => digest(name: 'Brasil'),
|
76
83
|
'PY' => digest(name: 'Paraguay'),
|
77
84
|
'CO' => digest(name: 'Colombia')
|
@@ -101,13 +108,19 @@ describe 'Delta' do
|
|
101
108
|
|
102
109
|
delta.must_equal 'countries' => {
|
103
110
|
'UY' => {'action' => 'delete'},
|
104
|
-
'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina', '
|
111
|
+
'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina', 'number' => 54, 'code' => 'ARG', 'capital' => 'CABA'}},
|
105
112
|
'BR' => {'action' => 'insert', 'data' => {'name' => 'Brasil'}},
|
106
113
|
'PY' => {'action' => 'insert', 'data' => {'name' => 'Paraguay'}}
|
107
114
|
}
|
108
115
|
end
|
109
116
|
|
110
117
|
it 'Commit -> Pull -> Push (multiple times)' do
|
118
|
+
# P MP MP M
|
119
|
+
# REPO 1: (*)--(1)--(3)--(4)--(7)--(8)--(11)--(12)
|
120
|
+
# \ / \ / \ /
|
121
|
+
# REPO 2: ---(2)--(5)--(6)--(9)--(10)
|
122
|
+
# P MP MP
|
123
|
+
|
111
124
|
repo_1[:countries].insert 'AR', name: 'Argentina'
|
112
125
|
repo_1.commit author: 'User 1', message: 'Added Argentina'
|
113
126
|
repo_1.push
|
@@ -216,4 +229,88 @@ describe 'Delta' do
|
|
216
229
|
}
|
217
230
|
end
|
218
231
|
|
232
|
+
it 'Merge -> Merge -> Checkout' do
|
233
|
+
# P MP P
|
234
|
+
# REPO 1: (*)--(1)--(2)------(6)--(7)
|
235
|
+
# \ MP / \
|
236
|
+
# REPO 2: --(3)--(5) (7)
|
237
|
+
# \ /
|
238
|
+
# REPO 3: -(4)-
|
239
|
+
# P
|
240
|
+
|
241
|
+
repo_1[:countries].insert 'AR', name: 'Argentina'
|
242
|
+
repo_1.commit author: 'User 1', message: 'Commit 1'
|
243
|
+
repo_1.push
|
244
|
+
|
245
|
+
delta = repo_2.pull
|
246
|
+
delta.must_equal 'countries' => {
|
247
|
+
'AR' => {'action' => 'insert', 'data' => {'name' => 'Argentina'}}
|
248
|
+
}
|
249
|
+
|
250
|
+
repo_2.current_commit.must_equal_index 'countries' => {
|
251
|
+
'AR' => digest(name: 'Argentina'),
|
252
|
+
}
|
253
|
+
|
254
|
+
delta = repo_3.pull
|
255
|
+
delta.must_equal 'countries' => {
|
256
|
+
'AR' => {'action' => 'insert', 'data' => {'name' => 'Argentina'}}
|
257
|
+
}
|
258
|
+
|
259
|
+
repo_3.current_commit.must_equal_index 'countries' => {
|
260
|
+
'AR' => digest(name: 'Argentina'),
|
261
|
+
}
|
262
|
+
|
263
|
+
repo_1[:countries].insert 'BR', name: 'Brasil'
|
264
|
+
repo_1.commit author: 'User 1', message: 'Commit 2'
|
265
|
+
|
266
|
+
repo_2[:countries].update 'AR', name: 'Argentina', number: 54
|
267
|
+
repo_2.commit author: 'User 2', message: 'Commit 3'
|
268
|
+
|
269
|
+
repo_3[:countries].insert 'UY', name: 'Uruguay'
|
270
|
+
repo_3.commit author: 'User 3', message: 'Commit 4'
|
271
|
+
repo_3.push
|
272
|
+
|
273
|
+
delta = repo_2.pull
|
274
|
+
delta.must_equal 'countries' => {
|
275
|
+
'UY' => {'action' => 'insert', 'data' => {'name' => 'Uruguay'}}
|
276
|
+
}
|
277
|
+
|
278
|
+
repo_2.current_commit.must_equal_index 'countries' => {
|
279
|
+
'AR' => digest(name: 'Argentina', number: 54),
|
280
|
+
'UY' => digest(name: 'Uruguay')
|
281
|
+
}
|
282
|
+
|
283
|
+
repo_2.push
|
284
|
+
|
285
|
+
delta = repo_1.pull
|
286
|
+
delta.must_equal 'countries' => {
|
287
|
+
'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina', 'number' => 54}},
|
288
|
+
'UY' => {'action' => 'insert', 'data' => {'name' => 'Uruguay'}}
|
289
|
+
}
|
290
|
+
|
291
|
+
repo_1.current_commit.must_equal_index 'countries' => {
|
292
|
+
'AR' => digest(name: 'Argentina', number: 54),
|
293
|
+
'BR' => digest(name: 'Brasil'),
|
294
|
+
'UY' => digest(name: 'Uruguay')
|
295
|
+
}
|
296
|
+
|
297
|
+
repo_1.push
|
298
|
+
|
299
|
+
repo_1[:countries].delete 'UY'
|
300
|
+
repo_1.commit author: 'User 1', message: 'Commit 7'
|
301
|
+
repo_1.push
|
302
|
+
|
303
|
+
delta = repo_2.pull
|
304
|
+
delta.must_equal 'countries' => {
|
305
|
+
'BR' => {'action' => 'insert', 'data' => {'name' => 'Brasil'}},
|
306
|
+
'UY' => {'action' => 'delete'}
|
307
|
+
}
|
308
|
+
|
309
|
+
repo_2.current_commit.must_equal_index 'countries' => {
|
310
|
+
'AR' => digest(name: 'Argentina', number: 54),
|
311
|
+
'BR' => digest(name: 'Brasil')
|
312
|
+
}
|
313
|
+
|
314
|
+
end
|
315
|
+
|
219
316
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
|
3
|
+
describe Commit, 'history' do
|
4
|
+
|
5
|
+
let(:repo_1) { Repository.new :test_1 }
|
6
|
+
let(:repo_2) { Repository.new :test_2 }
|
7
|
+
let(:repo_3) { Repository.new :test_3 }
|
8
|
+
|
9
|
+
let(:commits) { Hash.new }
|
10
|
+
|
11
|
+
def commit(repo, id)
|
12
|
+
data = {id: SecureRandom.uuid}
|
13
|
+
repo[:countries].insert data[:id], data
|
14
|
+
commits[id] = repo.commit author: repo.name, message: "Commit #{id}"
|
15
|
+
end
|
16
|
+
|
17
|
+
def push(repo)
|
18
|
+
repo.push
|
19
|
+
end
|
20
|
+
|
21
|
+
def pull(repo, merge_id=nil)
|
22
|
+
repo.pull
|
23
|
+
commits[merge_id] = repo.current_commit if merge_id
|
24
|
+
end
|
25
|
+
|
26
|
+
def assert_history(expected)
|
27
|
+
commits.each do |i,c|
|
28
|
+
c.history.must_equal expected[i].map { |e| commits[e] }, "Fail history of ##{i}: #{c}\nExpected: #{expected[i].map{ |c| commits[c].message }} \nActual: #{c.history.map(&:message)}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'Test 1' do
|
33
|
+
# P M P
|
34
|
+
# REPO 1: (*)--(1)--(2)--(4)---(6)---(7)
|
35
|
+
# \ / \
|
36
|
+
# REPO 2: -----(3)---(5)---(8)
|
37
|
+
# P M
|
38
|
+
|
39
|
+
commit repo_1, 1
|
40
|
+
commit repo_1, 2
|
41
|
+
push repo_1
|
42
|
+
pull repo_2
|
43
|
+
commit repo_2, 3
|
44
|
+
push repo_2
|
45
|
+
commit repo_1, 4
|
46
|
+
commit repo_2, 5
|
47
|
+
pull repo_1, 6
|
48
|
+
commit repo_1, 7
|
49
|
+
push repo_1
|
50
|
+
pull repo_2, 8
|
51
|
+
|
52
|
+
assert_history 1 => [],
|
53
|
+
2 => [1],
|
54
|
+
3 => [2,1],
|
55
|
+
4 => [2,1],
|
56
|
+
5 => [3,2,1],
|
57
|
+
6 => [4,3,2,1],
|
58
|
+
7 => [6,4,3,2,1],
|
59
|
+
8 => [5,7,6,4,3,2,1]
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'Test 2' do
|
63
|
+
# P M
|
64
|
+
# REPO 1: (*)--(1)--(2)------------------(11)
|
65
|
+
# \ M P /
|
66
|
+
# REPO 2: --(3)--(4)--(7)--(8) /
|
67
|
+
# \ / \ /
|
68
|
+
# REPO 3: -(5)----(6)--(9)--(10)
|
69
|
+
# P MP
|
70
|
+
|
71
|
+
commit repo_1, 1
|
72
|
+
push repo_1
|
73
|
+
commit repo_1, 2
|
74
|
+
pull repo_2
|
75
|
+
commit repo_2, 3
|
76
|
+
commit repo_2, 4
|
77
|
+
pull repo_3
|
78
|
+
commit repo_3, 5
|
79
|
+
commit repo_3, 6
|
80
|
+
push repo_3
|
81
|
+
pull repo_2, 7
|
82
|
+
commit repo_2, 8
|
83
|
+
push repo_2
|
84
|
+
commit repo_3, 9
|
85
|
+
pull repo_3, 10
|
86
|
+
push repo_3
|
87
|
+
pull repo_1, 11
|
88
|
+
|
89
|
+
assert_history 1 => [],
|
90
|
+
2 => [1],
|
91
|
+
3 => [1],
|
92
|
+
4 => [3,1],
|
93
|
+
5 => [1],
|
94
|
+
6 => [5,1],
|
95
|
+
7 => [4,3,6,5,1],
|
96
|
+
8 => [7,4,3,6,5,1],
|
97
|
+
9 => [6,5,1],
|
98
|
+
10 => [9,8,7,4,3,6,5,1],
|
99
|
+
11 => [2,10,9,8,7,4,3,6,5,1]
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
data/spec/log_spec.rb
CHANGED
@@ -29,21 +29,20 @@ describe Repository, 'Log' do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'Merge' do
|
32
|
-
time = Time.now
|
33
32
|
repository[:countries].insert 'AR', name: 'Argentina'
|
34
|
-
commit_1 = repository.commit author: 'User', message: 'Commit 1'
|
33
|
+
commit_1 = repository.commit author: 'User', message: 'Commit 1'
|
35
34
|
repository.push
|
36
35
|
|
37
36
|
other_repository = Repository.new :other
|
38
37
|
other_repository.pull
|
39
38
|
|
40
39
|
other_repository[:countries].insert 'UY', name: 'Uruguay'
|
41
|
-
commit_2 = other_repository.commit author: 'User', message: 'Commit 2'
|
40
|
+
commit_2 = other_repository.commit author: 'User', message: 'Commit 2'
|
42
41
|
|
43
42
|
other_repository.push
|
44
43
|
|
45
44
|
repository[:countries].insert 'BR', name: 'Brasil'
|
46
|
-
commit_3 = repository.commit author: 'User', message: 'Commit 3'
|
45
|
+
commit_3 = repository.commit author: 'User', message: 'Commit 3'
|
47
46
|
|
48
47
|
repository.pull
|
49
48
|
|
data/spec/merge_spec.rb
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'minitest_helper'
|
2
|
+
|
3
|
+
describe Repository, 'Merge' do
|
4
|
+
|
5
|
+
let(:repo_1) { Repository.new :test_1 }
|
6
|
+
let(:repo_2) { Repository.new :test_2 }
|
7
|
+
let(:repo_3) { Repository.new :test_3 }
|
8
|
+
|
9
|
+
let(:commits) { Hash.new }
|
10
|
+
|
11
|
+
def commit(id, repo, &block)
|
12
|
+
repo[:countries].instance_eval &block
|
13
|
+
commits[id] = repo.commit author: repo.name, message: "Commit #{id}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def merge(id, repo, target_id)
|
17
|
+
delta = repo.merge commit: commits[target_id].id
|
18
|
+
commits[id] = repo.current_commit
|
19
|
+
yield delta['countries'] if block_given?
|
20
|
+
delta
|
21
|
+
end
|
22
|
+
|
23
|
+
def assert_history(id, history_ids)
|
24
|
+
commits[id].history.must_equal history_ids.map { |c| commits[c] }
|
25
|
+
end
|
26
|
+
|
27
|
+
def assert_index(id, expected)
|
28
|
+
commits[id].must_equal_index 'countries' => expected
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'Delta, index and history' do
|
32
|
+
# REPO 1: (*)---(1)--(2)--(5)---(6)---(9)--(11)
|
33
|
+
# \ / \ /
|
34
|
+
# REPO 2: -(3)---(4)--(7)--(8)--(10)
|
35
|
+
|
36
|
+
commit 1, repo_1 do
|
37
|
+
insert 'AR', name: 'Argentina'
|
38
|
+
insert 'BR', name: 'Brasil'
|
39
|
+
end
|
40
|
+
|
41
|
+
assert_history 1, []
|
42
|
+
assert_index 1, 'AR' => digest(name: 'Argentina'),
|
43
|
+
'BR' => digest(name: 'Brasil')
|
44
|
+
|
45
|
+
commit 2, repo_1 do
|
46
|
+
delete 'BR'
|
47
|
+
end
|
48
|
+
|
49
|
+
assert_history 2, [1]
|
50
|
+
assert_index 2, 'AR' => digest(name: 'Argentina')
|
51
|
+
|
52
|
+
repo_2.checkout commit: commits[1].id
|
53
|
+
|
54
|
+
commit 3, repo_2 do
|
55
|
+
insert 'UY', name: 'Uruguay'
|
56
|
+
end
|
57
|
+
|
58
|
+
assert_history 3, [1]
|
59
|
+
assert_index 3, 'AR' => digest(name: 'Argentina'),
|
60
|
+
'BR' => digest(name: 'Brasil'),
|
61
|
+
'UY' => digest(name: 'Uruguay')
|
62
|
+
|
63
|
+
commit 4, repo_2 do
|
64
|
+
update 'BR', name: 'Brasil', number: 55
|
65
|
+
end
|
66
|
+
|
67
|
+
assert_history 4, [3,1]
|
68
|
+
assert_index 4, 'AR' => digest(name: 'Argentina'),
|
69
|
+
'BR' => digest(name: 'Brasil', number: 55),
|
70
|
+
'UY' => digest(name: 'Uruguay')
|
71
|
+
|
72
|
+
commit 5, repo_1 do
|
73
|
+
update 'AR', name: 'Argentina', number: 54
|
74
|
+
end
|
75
|
+
|
76
|
+
assert_history 5, [2, 1]
|
77
|
+
assert_index 5, 'AR' => digest(name: 'Argentina', number: 54)
|
78
|
+
|
79
|
+
merge 6, repo_1, 4 do |delta|
|
80
|
+
delta.must_equal 'UY' => {'action' => 'insert', 'data' => {'name' => 'Uruguay'}}
|
81
|
+
end
|
82
|
+
|
83
|
+
assert_history 6, [5,2,4,3,1]
|
84
|
+
assert_index 6, 'AR' => digest(name: 'Argentina', number: 54),
|
85
|
+
'UY' => digest(name: 'Uruguay')
|
86
|
+
|
87
|
+
commit 7, repo_2 do
|
88
|
+
update 'AR', name: 'Argentina', code: 'ARG'
|
89
|
+
end
|
90
|
+
|
91
|
+
assert_history 7, [4,3,1]
|
92
|
+
assert_index 7, 'AR' => digest(name: 'Argentina', code: 'ARG'),
|
93
|
+
'BR' => digest(name: 'Brasil', number: 55),
|
94
|
+
'UY' => digest(name: 'Uruguay')
|
95
|
+
|
96
|
+
merge 8, repo_2, 6 do |delta|
|
97
|
+
delta.must_equal 'BR' => {'action' => 'delete'},
|
98
|
+
'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina', 'code' => 'ARG', 'number' => 54}}
|
99
|
+
end
|
100
|
+
|
101
|
+
assert_history 8, [7,6,5,2,4,3,1]
|
102
|
+
assert_index 8, 'AR' => digest(name: 'Argentina', code: 'ARG', number: 54),
|
103
|
+
'UY' => digest(name: 'Uruguay')
|
104
|
+
|
105
|
+
commit 9, repo_1 do
|
106
|
+
insert 'CL', name: 'Chile', code: 'CHI'
|
107
|
+
end
|
108
|
+
|
109
|
+
assert_history 9, [6,5,2,4,3,1]
|
110
|
+
assert_index 9, 'AR' => digest(name: 'Argentina', number: 54),
|
111
|
+
'UY' => digest(name: 'Uruguay'),
|
112
|
+
'CL' => digest(name: 'Chile', code: 'CHI')
|
113
|
+
|
114
|
+
commit 10, repo_2 do
|
115
|
+
insert 'CL', name: 'Republica de Chile', number: 56
|
116
|
+
end
|
117
|
+
|
118
|
+
assert_history 10, [8,7,6,5,2,4,3,1]
|
119
|
+
assert_index 10, 'AR' => digest(name: 'Argentina', code: 'ARG', number: 54),
|
120
|
+
'UY' => digest(name: 'Uruguay'),
|
121
|
+
'CL' => digest(name: 'Republica de Chile', number: 56)
|
122
|
+
|
123
|
+
merge 11, repo_1, 10 do |delta|
|
124
|
+
delta.must_equal 'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina', 'number' => 54, 'code' => 'ARG'}},
|
125
|
+
'CL' => {'action' => 'update', 'data' => {'name' => 'Chile', 'number' => 56, 'code' => 'CHI'}}
|
126
|
+
end
|
127
|
+
|
128
|
+
assert_history 11, [9,10,8,7,6,5,2,4,3,1]
|
129
|
+
assert_index 11, 'AR' => digest(name: 'Argentina', code: 'ARG', number: 54),
|
130
|
+
'UY' => digest(name: 'Uruguay'),
|
131
|
+
'CL' => digest(name: 'Chile', number: 56, code: 'CHI')
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
data/spec/minitest_helper.rb
CHANGED
@@ -20,14 +20,6 @@ Eternity.configure do |config|
|
|
20
20
|
config.logger.level = Logger::ERROR
|
21
21
|
end
|
22
22
|
|
23
|
-
class Time
|
24
|
-
@last = Time.now
|
25
|
-
|
26
|
-
def self.now
|
27
|
-
@last += 1
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
23
|
class Minitest::Spec
|
32
24
|
def redis
|
33
25
|
Eternity.redis
|
@@ -37,32 +29,6 @@ class Minitest::Spec
|
|
37
29
|
Blob.digest(Blob.serialize(data))
|
38
30
|
end
|
39
31
|
|
40
|
-
def print_keys
|
41
|
-
puts Eternity.redis_keys.sort
|
42
|
-
end
|
43
|
-
|
44
|
-
def print_commit(commit)
|
45
|
-
puts "COMMIT: #{commit.author} - #{commit.message}"
|
46
|
-
puts "MERGE: #{commit.merge?}"
|
47
|
-
puts 'DELTA:'
|
48
|
-
puts JSON.pretty_generate(commit.delta)
|
49
|
-
if commit.merge?
|
50
|
-
puts "BASE: #{commit.base.author} - #{commit.base.message}"
|
51
|
-
puts 'BASE DELTA:'
|
52
|
-
puts JSON.pretty_generate(commit.base_delta)
|
53
|
-
end
|
54
|
-
puts 'INDEX:'
|
55
|
-
commit.with_index do |index|
|
56
|
-
index.each do |collection, collection_index|
|
57
|
-
puts collection
|
58
|
-
collection_index.ids.each do |id|
|
59
|
-
puts "#{id} -> #{collection_index[id].data}"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
puts '------------------------------------'
|
64
|
-
end
|
65
|
-
|
66
32
|
after do
|
67
33
|
Eternity.clear_redis
|
68
34
|
Eternity.clear_file_system
|
data/spec/patch_spec.rb
CHANGED
@@ -8,9 +8,9 @@ describe Patch do
|
|
8
8
|
let(:commits) { Hash.new }
|
9
9
|
|
10
10
|
before do
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
11
|
+
# REPO 1: (*)---(1)---(2)---(3)---(4)---(5)---(8)---(9)---(12)---(13)---(14)
|
12
|
+
# REPO 2: \ \--(6)---(7)--/ /
|
13
|
+
# REPO 3: \----------(10)-----------------(11)------/
|
14
14
|
|
15
15
|
repo_1[:countries].insert 'AR', name: 'Argentina'
|
16
16
|
commit repo_1, 1
|
@@ -74,7 +74,6 @@ describe Patch do
|
|
74
74
|
|
75
75
|
patch.delta.must_be_empty
|
76
76
|
patch.base_commit.must_equal commits[4]
|
77
|
-
patch.base_delta.must_be_empty
|
78
77
|
end
|
79
78
|
|
80
79
|
it 'Diff' do
|
@@ -95,10 +94,6 @@ describe Patch do
|
|
95
94
|
'CO' => {'action' => 'insert', 'data' => {'name' => 'Colombia', 'number' => 57}}
|
96
95
|
}
|
97
96
|
patch.base_commit.must_be_nil
|
98
|
-
patch.base_delta.must_equal 'countries' => {
|
99
|
-
'AR' => {'action' => 'insert', 'data' => {'name' => 'Argentina'}},
|
100
|
-
'CO' => {'action' => 'insert', 'data' => {'name' => 'Colombia', 'number' => 57}}
|
101
|
-
}
|
102
97
|
end
|
103
98
|
|
104
99
|
it 'Diff' do
|
@@ -120,7 +115,6 @@ describe Patch do
|
|
120
115
|
|
121
116
|
patch.delta.must_be_empty
|
122
117
|
patch.base_commit.must_equal commits[1]
|
123
|
-
patch.base_delta.must_be_empty
|
124
118
|
end
|
125
119
|
|
126
120
|
it 'Diff' do
|
@@ -142,7 +136,6 @@ describe Patch do
|
|
142
136
|
|
143
137
|
patch.delta.must_be_empty
|
144
138
|
patch.base_commit.must_equal commits[2]
|
145
|
-
patch.base_delta.must_be_empty
|
146
139
|
end
|
147
140
|
|
148
141
|
it 'Diff' do
|
@@ -167,11 +160,6 @@ describe Patch do
|
|
167
160
|
'CL' => {'action' => 'insert', 'data' => {'name' => 'Chile'}}
|
168
161
|
}
|
169
162
|
patch.base_commit.must_equal commits[3]
|
170
|
-
patch.base_delta.must_equal 'countries' => {
|
171
|
-
'UY' => {'action' => 'update', 'data' => {'name' => 'Republica Oriental del Uruguay'}},
|
172
|
-
'AR' => {'action' => 'update', 'data' => {'name' => 'Republica Argentina', 'number' => 54}},
|
173
|
-
'CL' => {'action' => 'insert', 'data' => {'name' => 'Chile'}},
|
174
|
-
}
|
175
163
|
end
|
176
164
|
|
177
165
|
it 'Diff' do
|
@@ -194,7 +182,6 @@ describe Patch do
|
|
194
182
|
|
195
183
|
patch.delta.must_be_empty
|
196
184
|
patch.base_commit.must_equal commits[3]
|
197
|
-
patch.base_delta.must_be_empty
|
198
185
|
end
|
199
186
|
|
200
187
|
it 'Diff' do
|
data/spec/pull_spec.rb
CHANGED
@@ -132,7 +132,7 @@ describe Repository, 'Pull' do
|
|
132
132
|
|
133
133
|
delta.must_equal 'countries' => {'AR' => {'action' => 'insert', 'data' => {'name' => 'Argentina 1'}}}
|
134
134
|
|
135
|
-
other_repository[:countries].update 'AR', name: 'Argentina 2'
|
135
|
+
other_repository[:countries].update 'AR', name: 'Argentina 2', number: 54
|
136
136
|
commit_2 = other_repository.commit author: 'User', message: 'Commit 2'
|
137
137
|
other_repository.push
|
138
138
|
|
@@ -140,7 +140,7 @@ describe Repository, 'Pull' do
|
|
140
140
|
commit_3 = repository.commit author: 'User', message: 'Commit 3'
|
141
141
|
delta = repository.pull
|
142
142
|
|
143
|
-
delta.must_equal 'countries' => {'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina
|
143
|
+
delta.must_equal 'countries' => {'AR' => {'action' => 'update', 'data' => {'name' => 'Argentina 3', 'number' => 54}}}
|
144
144
|
|
145
145
|
repository.branches[repository.current_branch].must_equal repository.current_commit.id
|
146
146
|
|
@@ -149,7 +149,7 @@ describe Repository, 'Pull' do
|
|
149
149
|
commit.parents.must_equal [commit_3, commit_2]
|
150
150
|
commit.base.id.must_equal commit_1.id
|
151
151
|
commit.delta.must_be_empty
|
152
|
-
commit.must_equal_index 'countries' => {'AR' => digest(name: 'Argentina
|
152
|
+
commit.must_equal_index 'countries' => {'AR' => digest(name: 'Argentina 3', number: 54)}
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
@@ -202,7 +202,7 @@ describe Repository, 'Pull' do
|
|
202
202
|
commit_3 = repository.commit author: 'User', message: 'Commit 3'
|
203
203
|
delta = repository.pull
|
204
204
|
|
205
|
-
delta.must_equal 'countries' => {'X' => {'action' => 'update', 'data' => {'name' => '
|
205
|
+
delta.must_equal 'countries' => {'X' => {'action' => 'update', 'data' => {'name' => 'X2', 'number' => 2, 'code' => 1}}}
|
206
206
|
|
207
207
|
repository.branches[repository.current_branch].must_equal repository.current_commit.id
|
208
208
|
|
@@ -213,7 +213,7 @@ describe Repository, 'Pull' do
|
|
213
213
|
commit.delta.must_be_empty
|
214
214
|
commit.must_equal_index 'countries' => {
|
215
215
|
'AR' => digest(name: 'Argentina'),
|
216
|
-
'X' => digest(name: '
|
216
|
+
'X' => digest(name: 'X2', 'number' => 2, 'code' => 1)
|
217
217
|
}
|
218
218
|
end
|
219
219
|
end
|
@@ -234,6 +234,7 @@ describe Repository, 'Pull' do
|
|
234
234
|
|
235
235
|
repository[:countries].delete 'AR'
|
236
236
|
commit_3 = repository.commit author: 'User', message: 'Commit 3'
|
237
|
+
|
237
238
|
delta = repository.pull
|
238
239
|
|
239
240
|
delta.must_be_empty
|
@@ -259,15 +260,16 @@ describe Repository, 'Pull' do
|
|
259
260
|
|
260
261
|
delta.must_equal 'countries' => {'AR' => {'action' => 'insert', 'data' => {'name' => 'Argentina'}}}
|
261
262
|
|
262
|
-
other_repository[:countries].
|
263
|
+
other_repository[:countries].delete 'AR'
|
263
264
|
commit_2 = other_repository.commit author: 'User', message: 'Commit 2'
|
264
265
|
other_repository.push
|
265
266
|
|
266
|
-
repository[:countries].
|
267
|
+
repository[:countries].update 'AR', name: 'Argentina', code: 'ARG'
|
267
268
|
commit_3 = repository.commit author: 'User', message: 'Commit 3'
|
269
|
+
|
268
270
|
delta = repository.pull
|
269
271
|
|
270
|
-
delta.
|
272
|
+
delta.must_be_empty
|
271
273
|
|
272
274
|
repository.branches[repository.current_branch].must_equal repository.current_commit.id
|
273
275
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eternity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Naiman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redic
|
@@ -217,9 +217,11 @@ files:
|
|
217
217
|
- spec/commit_spec.rb
|
218
218
|
- spec/coverage_helper.rb
|
219
219
|
- spec/delta_spec.rb
|
220
|
+
- spec/history_spec.rb
|
220
221
|
- spec/index_spec.rb
|
221
222
|
- spec/locking_spec.rb
|
222
223
|
- spec/log_spec.rb
|
224
|
+
- spec/merge_spec.rb
|
223
225
|
- spec/minitest_helper.rb
|
224
226
|
- spec/patch_spec.rb
|
225
227
|
- spec/pull_spec.rb
|
@@ -258,9 +260,11 @@ test_files:
|
|
258
260
|
- spec/commit_spec.rb
|
259
261
|
- spec/coverage_helper.rb
|
260
262
|
- spec/delta_spec.rb
|
263
|
+
- spec/history_spec.rb
|
261
264
|
- spec/index_spec.rb
|
262
265
|
- spec/locking_spec.rb
|
263
266
|
- spec/log_spec.rb
|
267
|
+
- spec/merge_spec.rb
|
264
268
|
- spec/minitest_helper.rb
|
265
269
|
- spec/patch_spec.rb
|
266
270
|
- spec/pull_spec.rb
|