Class: GitModel::Transaction

Inherits:
Object
  • Object
show all
Defined in:
lib/gitmodel/transaction.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Transaction

Returns a new instance of Transaction.



8
9
10
11
# File 'lib/gitmodel/transaction.rb', line 8

def initialize(options = {})
  self.branch = options[:branch] || GitModel.default_branch
  self.commit_message = options[:commit_message]
end

Instance Attribute Details

#branchObject

Returns the value of attribute branch.



5
6
7
# File 'lib/gitmodel/transaction.rb', line 5

def branch
  @branch
end

#commit_messageObject

Returns the value of attribute commit_message.



6
7
8
# File 'lib/gitmodel/transaction.rb', line 6

def commit_message
  @commit_message
end

#indexObject

Returns the value of attribute index.



4
5
6
# File 'lib/gitmodel/transaction.rb', line 4

def index
  @index
end

Instance Method Details

#execute(&block) ⇒ Object



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/gitmodel/transaction.rb', line 13

def execute(&block)
  if index 
    # We're already in a transaction
    yield self
  else
    # For now there's a big ugly lock here, this will be fixed!
    # TODO move this lock around the commit only (need to make sure two
    # processes aren't updating refs/heads/<branch> at the same time) and
    # make concurrent transactions can work. This will require some merging
    # magic!
    lock do
      # We're not in a transaction, start a new one
      GitModel.logger.debug "Beginning transaction on #{branch}..."

      # Save the current head so that concurrent transactions can work. We need
      # to make sure the parent of this commit is the same SHA that this
      # index's tree is based on.
      parent = GitModel.last_commit(branch)

      self.index = Grit::Index.new(GitModel.repo)
      index.read_tree(parent.to_s)
      
      yield self

      committer = Grit::Actor.new(GitModel.git_user_name, GitModel.git_user_email)
      sha = index.commit(commit_message, parent ? [parent] : nil, committer, nil, branch)
      # TODO return false and log if anything went wrong with the commit

      GitModel.logger.debug "Finished transaction on #{branch}."

      return sha
    end
  end
end

#lock(&block) ⇒ Object

Wait until we can get an exclusive lock on the branch, then execute the block. We lock the branch by creating refs/heads/<branch>.lock, which the git commands also seem to respect



51
52
53
54
55
56
57
58
59
# File 'lib/gitmodel/transaction.rb', line 51

def lock(&block)
  lockfile = Lockfile.new File.join(GitModel.repo.path, 'refs/heads', branch + '.lock')
  begin
    lockfile.lock
    yield
  ensure
    lockfile.unlock
  end
end