Class: Eternity::Commit

Inherits:
Object
  • Object
show all
Defined in:
lib/eternity/commit.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id) ⇒ Commit

Returns a new instance of Commit.



6
7
8
# File 'lib/eternity/commit.rb', line 6

def initialize(id)
  @id = id
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



4
5
6
# File 'lib/eternity/commit.rb', line 4

def id
  @id
end

Class Method Details

.base_of(commit_1, commit_2) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/eternity/commit.rb', line 139

def self.base_of(commit_1, commit_2)
  history_1 = [commit_1.id]
  history_2 = [commit_2.id]

  base_1 = commit_1
  base_2 = commit_2

  while (history_1 & history_2).empty?
    base_1 = base_1.base if base_1
    base_2 = base_2.base if base_2
    
    history_1 << base_1.id if base_1
    history_2 << base_2.id if base_2
  end

  Commit.new (history_1 & history_2).first
end

.clear_history_cacheObject



168
169
170
171
172
# File 'lib/eternity/commit.rb', line 168

def self.clear_history_cache
  Eternity.connection.call('KEYS', history_cache_key['*']).each_slice(1000) do |keys|
    Eternity.connection.call 'DEL', *keys
  end
end

.create(options) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/eternity/commit.rb', line 110

def self.create(options)
  raise 'Author must be present' if options[:author].to_s.strip.empty?
  raise 'Message must be present' if options[:message].to_s.strip.empty?

  # TODO: Move to Repository and Patch
  history =
    if options[:parents].count == 2
      current_history_ids = [options[:parents][0]] + Commit.new(options[:parents][0]).history_ids
      target_history_ids = [options[:parents][1]] + Commit.new(options[:parents][1]).history_ids
      current_history_ids - target_history_ids + target_history_ids
    else
      parent_id = options[:parents][0]
      parent_id ? [parent_id] + Commit.new(parent_id).history_ids : []
    end

  data = {
    time:          Time.now,
    author:        options.fetch(:author),
    message:       options.fetch(:message),
    parents:       options.fetch(:parents),
    index:         options.fetch(:index),
    delta:         options.fetch(:delta),
    base:          options[:parents].count == 2 ? options.fetch(:base) : options[:parents].first,
    history:       Blob.write(:history, history)
  }

  new Blob.write(:commit, data)
end

.exists?(id) ⇒ Boolean

Returns:

  • (Boolean)


157
158
159
160
161
162
# File 'lib/eternity/commit.rb', line 157

def self.exists?(id)
  Blob.read :commit, id
  true
rescue
  false
end

.history_cache_keyObject



164
165
166
# File 'lib/eternity/commit.rb', line 164

def self.history_cache_key
  Eternity.keyspace[:cache][:history]
end

Instance Method Details

#==(commit) ⇒ Object Also known as: eql?



96
97
98
99
# File 'lib/eternity/commit.rb', line 96

def ==(commit)
  commit.class == self.class && 
  commit.id == id
end

#authorObject



18
19
20
# File 'lib/eternity/commit.rb', line 18

def author
  data['author']
end

#baseObject



45
46
47
# File 'lib/eternity/commit.rb', line 45

def base
  Commit.new data['base']
end

#deltaObject



41
42
43
# File 'lib/eternity/commit.rb', line 41

def delta
  data['delta'] ? Blob.read(:delta, data['delta']) : {}
end

#fast_forward?(commit) ⇒ Boolean

Returns:

  • (Boolean)


78
79
80
81
82
# File 'lib/eternity/commit.rb', line 78

def fast_forward?(commit)
  return false if nil?
  return true if commit.nil?
  history_ids.include? commit.id
end

#first?Boolean

Returns:

  • (Boolean)


84
85
86
# File 'lib/eternity/commit.rb', line 84

def first?
  parent_ids.compact.empty?
end

#hashObject



102
103
104
# File 'lib/eternity/commit.rb', line 102

def hash
  id.hash
end

#historyObject



74
75
76
# File 'lib/eternity/commit.rb', line 74

def history
  history_ids.map { |id| Commit.new id }
end

#history_idsObject



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/eternity/commit.rb', line 49

def history_ids
  return [] if nil?
  if data['history']
    Blob.read :history, data['history']
  else
    # Backward compatibility
    cache_key = self.class.history_cache_key[id]
    return Eternity.connection.call 'LRANGE', cache_key, 0, -1 if Eternity.connection.call('EXISTS', cache_key) == 1

    commit_ids =
      if parent_ids.count == 2
        current_history_ids = [parent_ids[0]] + Commit.new(parent_ids[0]).history_ids
        target_history_ids = [parent_ids[1]] + Commit.new(parent_ids[1]).history_ids
        current_history_ids - target_history_ids + target_history_ids
      else
        parent_id = parent_ids[0]
        parent_id ? [parent_id] + Commit.new(parent_id).history_ids : []
      end

    Eternity.connection.call 'RPUSH', cache_key, *commit_ids

    commit_ids
  end
end

#merge?Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/eternity/commit.rb', line 88

def merge?
  parent_ids.count == 2
end

#messageObject



22
23
24
# File 'lib/eternity/commit.rb', line 22

def message
  data['message']
end

#nil?Boolean

Returns:

  • (Boolean)


92
93
94
# File 'lib/eternity/commit.rb', line 92

def nil?
  id.nil?
end

#parent_idsObject



26
27
28
# File 'lib/eternity/commit.rb', line 26

def parent_ids
  data['parents'] || [nil]
end

#parentsObject



30
31
32
# File 'lib/eternity/commit.rb', line 30

def parents
  parent_ids.map { |id| Commit.new id }
end

#short_idObject



10
11
12
# File 'lib/eternity/commit.rb', line 10

def short_id
  id ? id[0,7] : nil
end

#timeObject



14
15
16
# File 'lib/eternity/commit.rb', line 14

def time
  Time.parse data['time'] if data['time']
end

#to_sObject



106
107
108
# File 'lib/eternity/commit.rb', line 106

def to_s
  "#{time} - #{short_id} - #{author}: #{message}"
end

#with_indexObject



34
35
36
37
38
39
# File 'lib/eternity/commit.rb', line 34

def with_index
  index = data['index'] ? Index.read_blob(data['index']) : Index.new
  yield index
ensure
  index.destroy if index
end