1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

Distributed git support for better operability with remote_cache strategy (closes #11137)

git-svn-id: http://svn.rubyonrails.org/rails/tools/capistrano@8923 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
Jamis Buck 2008-02-22 03:38:08 +00:00
parent 1ace9cb2d5
commit a06a802168
3 changed files with 108 additions and 34 deletions

View file

@ -1,5 +1,7 @@
*SVN*
* Distributed git support for better operability with remote_cache strategy [voidlock]
* Use a default line length in help text if line length is otherwise too small [Jamis Buck]
* Fix incorrect reference to the 'setup' task in task documentation [rajeshduggal]

View file

@ -49,11 +49,28 @@ module Capistrano
# You may set <tt>:branch</tt>, which is the reference to the branch, tag,
# or any SHA1 you are deploying, for example:
#
# set :branch, "origin/master"
# set :branch, "master"
#
# Otherwise, HEAD is assumed. I strongly suggest you set this. HEAD is
# not always the best assumption.
#
# You may also set <tt>:remote</tt>, which will be used as a name for remote
# tracking of repositories. This option is intended for use with the
# <tt>:remote_cache</tt> strategy in a distributed git environment.
#
# For example in the projects <tt>config/deploy.rb</tt>:
#
# set :repository, "#{scm_user}@somehost:~/projects/project.git"
# set :remote, "#{scm_user}"
#
# Then each person with deploy priveledges can add the following to their
# local <tt>~/.caprc</tt> file:
#
# set :scm_user, 'someuser'
#
# Now any time a person deploys the project, their repository will be
# setup as a remote git repository within the cached repository.
#
# The <tt>:scm_command</tt> configuration variable, if specified, will
# be used as the full path to the git executable on the *remote* machine:
#
@ -78,7 +95,7 @@ module Capistrano
# set :deploy_via, :remote_cache
#
# For faster clone, you can also use shallow cloning. This will set the
# '--depth' flag using the depth specified. This *cannot* be used
# '--depth' flag using the depth specified. This *cannot* be used
# together with the :remote_cache strategy
#
# set :git_shallow_clone, 1
@ -88,8 +105,9 @@ module Capistrano
#
# Garry Dolley http://scie.nti.st
# Contributions by Geoffrey Grosenbach http://topfunky.com
# and Scott Chacon http://jointheconversation.org
# Scott Chacon http://jointheconversation.org
# and Alex Arnell http://twologic.com
class Git < Base
# Sets the default command name for this SCM on your *local* machine.
# Users may override this by setting the :scm_command variable.
@ -102,27 +120,35 @@ module Capistrano
configuration[:branch] || 'HEAD'
end
def origin
configuration[:remote] || 'origin'
end
# Performs a clone on the remote machine, then checkout on the branch
# you want to deploy.
def checkout(revision, destination)
git = command
git = command
remote = origin
branch = head
fail "No branch specified, use for example 'set :branch, \"origin/master\"' in your deploy.rb" unless branch
execute = []
args = []
args << "-o #{remote}" unless remote == 'origin'
if depth = configuration[:git_shallow_clone]
execute << "#{git} clone --depth #{depth} #{configuration[:repository]} #{destination}"
else
execute << "#{git} clone #{configuration[:repository]} #{destination}"
args << "--depth #{depth}"
end
execute << "cd #{destination}"
execute << "#{git} checkout #{branch}"
execute = []
if args.empty?
execute << "#{git} clone #{configuration[:repository]} #{destination}"
else
execute << "#{git} clone #{args.join(' ')} #{configuration[:repository]} #{destination}"
end
# checkout into a local branch rather than a detached HEAD
execute << "cd #{destination} && #{git} checkout -b deploy #{revision}"
if configuration[:git_enable_submodules]
execute << "#{git} submodule init"
execute << "#{git} submodule update"
execute << "#{git} submodule init"
execute << "#{git} submodule update"
end
execute.join(" && ")
@ -131,16 +157,26 @@ module Capistrano
# Merges the changes to 'head' since the last fetch, for remote_cache
# deployment strategy
def sync(revision, destination)
git = command
execute = []
execute << "cd #{destination} && #{git} fetch origin"
git = command
remote = origin
if head == 'HEAD'
execute << "#{git} checkout origin/HEAD"
else
execute << "#{git} checkout #{head}"
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 #{remote} && #{git} reset --hard #{revision}"
if configuration[:git_enable_submodules]
execute << "#{git} submodule update"
end

View file

@ -19,14 +19,21 @@ class DeploySCMGitTest < Test::Unit::TestCase
assert_equal "master", @source.head
end
def origin
asser_equal "origin", @source.origin
@config[:remote] = "git"
assert_equal "git", @source.origin
end
def test_checkout
@config[:repository] = "git@somehost.com:project.git"
dest = "/var/www"
assert_equal "git clone git@somehost.com:project.git /var/www && cd /var/www && git checkout HEAD", @source.checkout('Not used', dest)
rev = 'c2d9e79'
assert_equal "git clone git@somehost.com:project.git /var/www && cd /var/www && git checkout -b deploy #{rev}", @source.checkout(rev, dest)
# With branch
@config[:branch] = "origin/foo"
assert_equal "git clone git@somehost.com:project.git /var/www && cd /var/www && git checkout origin/foo", @source.checkout('Not used', dest)
assert_equal "git clone git@somehost.com:project.git /var/www && cd /var/www && git checkout -b deploy #{rev}", @source.checkout(rev, dest)
end
def test_diff
@ -51,26 +58,55 @@ class DeploySCMGitTest < Test::Unit::TestCase
def test_sync
dest = "/var/www"
assert_equal "cd #{dest} && git fetch origin && git checkout origin/HEAD", @source.sync('Not used', dest)
rev = 'c2d9e79'
assert_equal "cd #{dest} && git fetch origin && git reset --hard #{rev}", @source.sync(rev, dest)
# With branch
@config[:branch] = "origin/foo"
assert_equal "cd #{dest} && git fetch origin && git checkout origin/foo", @source.sync('Not used', dest)
@config[:branch] = "foo"
rev = '92d9e79' # simulate rev change
assert_equal "cd #{dest} && git fetch origin && git reset --hard #{rev}", @source.sync(rev, dest)
# With :scm_command
@config[:scm_command] = "/opt/local/bin/git"
assert_equal "cd #{dest} && /opt/local/bin/git fetch origin && /opt/local/bin/git checkout origin/foo", @source.sync('Not used', dest)
git = "/opt/local/bin/git"
@config[:scm_command] = git
assert_equal "cd #{dest} && #{git} fetch origin && #{git} reset --hard #{rev}", @source.sync(rev, dest)
end
def test_sync_with_remote
dest = "/var/www"
rev = 'c2d9e79'
remote = "username"
repository = "git@somehost.com:project.git"
@config[:repository] = repository
@config[:remote] = remote
assert_equal "cd #{dest} && git config remote.#{remote}.url #{repository} && git config remote.#{remote}.fetch +refs/heads/*:refs/remotes/#{remote}/* && git fetch #{remote} && git reset --hard #{rev}", @source.sync(rev, dest)
end
def test_shallow_clone
@config[:repository] = "git@somehost.com:project.git"
@config[:git_shallow_clone] = 1
dest = "/var/www"
assert_equal "git clone --depth 1 git@somehost.com:project.git /var/www && cd /var/www && git checkout HEAD", @source.checkout('Not used', dest)
rev = 'c2d9e79'
assert_equal "git clone --depth 1 git@somehost.com:project.git /var/www && cd /var/www && git checkout -b deploy #{rev}", @source.checkout(rev, dest)
# With branch
@config[:branch] = "origin/foo"
assert_equal "git clone --depth 1 git@somehost.com:project.git /var/www && cd /var/www && git checkout origin/foo", @source.checkout('Not used', dest)
rev = '92d9e79' # simulate rev change
assert_equal "git clone --depth 1 git@somehost.com:project.git /var/www && cd /var/www && git checkout -b deploy #{rev}", @source.checkout(rev, dest)
end
def test_remote_clone
@config[:repository] = "git@somehost.com:project.git"
@config[:remote] = "username"
dest = "/var/www"
rev = 'c2d9e79'
assert_equal "git clone -o username git@somehost.com:project.git /var/www && cd /var/www && git checkout -b deploy #{rev}", @source.checkout(rev, dest)
# With branch
@config[:branch] = "foo"
assert_equal "git clone -o username git@somehost.com:project.git /var/www && cd /var/www && git checkout -b deploy #{rev}", @source.checkout(rev, dest)
end
# Tests from base_test.rb, makin' sure we didn't break anything up there!