Class: Git

Inherits:
Object
  • Object
show all
Defined in:
lib/chef-deploy/git.rb

Overview

stolen wholesale from capistrano, thanks Jamis!

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Git

Performs a clone on the remote machine, then checkout on the branch you want to deploy.



7
8
9
# File 'lib/chef-deploy/git.rb', line 7

def initialize(opts={})
  @configuration = opts
end

Instance Method Details

#checkout(revision, destination) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/chef-deploy/git.rb', line 25

def checkout(revision, destination)
  remote = origin

  args = []
  args << "-o #{remote}" unless remote == 'origin'
  if depth = configuration[:git_shallow_clone]
    args << "--depth #{depth}"
  end

  execute = []

  execute << "rm -rf #{destination}"

  if args.empty?
    execute << "#{git} clone #{verbose} #{configuration[:repository]} #{destination}"
  else
    execute << "#{git} clone #{verbose} #{args.join(' ')} #{configuration[:repository]} #{destination}"
  end

  # checkout into a local branch rather than a detached HEAD
  execute << "cd #{destination} && #{git} checkout #{verbose} -b deploy #{revision}"
  
  if configuration[:git_enable_submodules]
    execute << "#{git} submodule #{verbose} init"
    execute << "#{git} submodule #{verbose} update"
  end

  execute.join(" && ")
end

#configurationObject



11
12
13
# File 'lib/chef-deploy/git.rb', line 11

def configuration
  @configuration
end

#diff(from, to = nil) ⇒ Object

Returns a string of diffs between two revisions



92
93
94
95
# File 'lib/chef-deploy/git.rb', line 92

def diff(from, to=nil)
  from << "..#{to}" if to
  scm :diff, from
end

#export(revision, destination) ⇒ Object

An expensive export. Performs a checkout as above, then removes the repo.



57
58
59
# File 'lib/chef-deploy/git.rb', line 57

def export(revision, destination)
  checkout(revision, destination) << " && rm -Rf #{destination}/.git"
end

#gitObject



15
16
17
18
19
# File 'lib/chef-deploy/git.rb', line 15

def git
  res = configuration[:git_ssh_wrapper] ? "GIT_SSH=#{configuration[:git_ssh_wrapper]} git" : 'git'
  res = "sudo -u #{configuration[:user]} #{res}" if configuration[:user]
  res
end

#headObject



127
128
129
# File 'lib/chef-deploy/git.rb', line 127

def head
  configuration[:branch] || 'HEAD'
end

#log(from, to = nil) ⇒ Object

Returns a log of changes between the two revisions (inclusive).



98
99
100
# File 'lib/chef-deploy/git.rb', line 98

def log(from, to=nil)
  scm :log, "#{from}..#{to}"
end

#originObject



131
132
133
# File 'lib/chef-deploy/git.rb', line 131

def origin
  configuration[:remote] || 'origin'
end

#query_revision(reference) ⇒ Object

Getting the actual commit id, in case we were passed a tag or partial sha or something - it will return the sha if you pass a sha, too

Raises:

  • (ArgumentError)


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/chef-deploy/git.rb', line 104

def query_revision(reference)
  raise ArgumentError, "Deploying remote branches is no longer supported.  Specify the remote branch as a local branch for the git repository you're deploying from (ie: '#{reference.gsub('origin/', '')}' rather than '#{reference}')." if reference =~ /^origin\//
  sha_hash = '[0-9a-f]{40}'
  return reference if reference =~ /^#{sha_hash}$/     # it's already a sha
  command = scm('ls-remote', configuration[:repository], reference)
  result = nil
  begin
    result = yield(command)
  rescue ChefDeployFailure => e
    raise obvious_error("Could not access the remote Git repository. If this is a private repository, please verify that the deploy key for your application has been added to your remote Git account.", e)
  end
  unless result =~ /^(#{sha_hash})\s+(\S+)/
    raise "Unable to resolve reference for '#{reference}' on repository '#{configuration[:repository]}'."
  end
  newrev = $1
  newref = $2
  return newrev
end

#respositoryObject



21
22
23
# File 'lib/chef-deploy/git.rb', line 21

def respository
  configuration[:repository]
end

#scm(*args) ⇒ Object



123
124
125
# File 'lib/chef-deploy/git.rb', line 123

def scm(*args)
  [git, *args].compact.join(" ")
end

#sync(revision, destination) ⇒ Object

Merges the changes to ‘head’ since the last fetch, for remote_cache deployment strategy



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/chef-deploy/git.rb', line 63

def sync(revision, destination)
  remote  = origin

  execute = []
  execute << "cd #{destination}"

  # Use git-config to setup a remote tracking branches. Could use
  # git-remote but it complains when a remote of the same name already
  # exists, git-config will just silenty overwrite the setting every
  # time. This could cause wierd-ness in the remote cache if the url
  # changes between calls, but as long as the repositories are all
  # based from each other it should still work fine.
  if remote != 'origin'
    execute << "#{git} config remote.#{remote}.url #{configuration[:repository]}"
    execute << "#{git} config remote.#{remote}.fetch +refs/heads/*:refs/remotes/#{remote}/*"
  end

  # since we're in a local branch already, just reset to specified revision rather than merge
  execute << "#{git} fetch #{verbose} #{remote} && #{git} reset #{verbose} --hard #{revision}"

  if configuration[:git_enable_submodules]
    execute << "#{git} submodule #{verbose} init"
    execute << "#{git} submodule #{verbose} update"
  end

  execute.join(" && ")
end