eternity 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|