Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #11137 (closed enhancement: fixed)

Opened 2 years ago

Last modified 2 years ago

[PATCH] Distributed Git support for Capistrano 2.1.0

Reported by: voidlock Assigned to: minam
Priority: normal Milestone:
Component: Capistrano Version:
Severity: normal Keywords:
Cc:

Description

The current Git module for Capistrano works great if you are working from a central Git repository. However, Git is a distributed source control system. The Git module still works in a distributed environment, but there are some shortcomings. You can no longer use the remote_cache deployment strategy.

This patch modifies the Git module to work better when using the remote_cache deployment strategy in a distributed development model.

The patch adds a :remote variable that when set causes the remote_cache git repository to track a new remote repository. Changes will be fetched from that new remote and merged into the deploy branch. The patch contains modified comments that explain the usage of this new variable along with updated tests.

In order to make this work properly, I had to change the behavior of both the checkout and sync methods. They both now used the passed in revision instead of looking up the head (:branch) directly from the configuration. This means that the full SHA1 commit id, obtained by the query_revision method, is used on the remote server.

This has only one caveat that I've discovered. Users of this module must make sure that the repository they plan to pull from on the remote server contains the commit they plan to pull down. I think this is a perfectly reasonable expectation, but it could cause some confusion if a user has local commits that they wish to deploy but have forgotten to push those commits out.

Using the full SHA1 commit id also fixes a bug when using the :shallow_clone option. When you use the --depth flag, git does not copy down any of the tag references. So if you were using the :shallow_clone option and you wanted to deploy from a specific tag (set :branch, 'v2.0.3') git would complain about not being able to find that commit and your deployment would consequently fail.

Attachments

capistrano-distributed-git.diff (9.9 kB) - added by voidlock on 02/21/08 17:28:04.
updated to work with latest trunk [8920]

Change History

(follow-up: ↓ 2 ) 02/17/08 01:09:13 changed by voidlock

One more thing that I forgot to mention regarding the use of the SHA1 commit id. Because query_revision operates locally, you don't need to add the remote branch name to the :branch variable.

For example:

set :branch, 'master'

Would look up the commit id for the tip of the master branch locally. That commit id, would then be used on the remote server. If there are multiple remote tracking branches on the remote server it won't matter. The commit id is universal across all of them.

This means that since the commit id is resolved locally, typically you would never need to do things like

set :branch, 'origin/master'

unless you were doing bizarre things.

The above example would still work, but it would resolve to the locally known tip of the master branch on origin and not your local repository.

(in reply to: ↑ 1 ) 02/17/08 01:12:12 changed by voidlock

Correction to previous comment:

The above example would still work, but it would resolve to the locally known tip of the master branch on origin and not the tip of your local master branch.

02/17/08 01:19:26 changed by voidlock

  • summary changed from [PATCH] Distributed Git support for Capistrano to [PATCH] Distributed Git support for Capistrano 2.1.0.

02/21/08 04:24:49 changed by minam

  • status changed from new to assigned.

I'm interested in applying this patch, but I'd applied a few other git patches and now this one doesn't apply cleanly. Any chance I could get you to update the patch for latest trunk?

02/21/08 04:27:13 changed by voidlock

Yup, sure. I'll attach a new patch real soon.

02/21/08 17:28:04 changed by voidlock

  • attachment capistrano-distributed-git.diff added.

updated to work with latest trunk [8920]

02/21/08 17:37:21 changed by voidlock

I have attached a new copy of the patch. I noticed you applied the patch from #10918, I've modified my code to work by the same principles.

The only difference is that I still do the checkout into a local deploy branch. The patch from #10918 will checkout into a detached head. Some early versions of Git did not allow detached heads. I don't know if this would present an issue, but just to be on the safe side I use a local branch. You need at least Git 1.5.0 for the detached head business to work.

The only other difference is that I use git reset --hard on the sync side instead of another checkout. It would be possible to simply do another git checkout in the detached head state, but reset does the same thing on a branch that has already been checked out.

02/22/08 03:38:11 changed by minam

  • status changed from assigned to closed.
  • resolution set to fixed.

(In [8923]) Distributed git support for better operability with remote_cache strategy (closes #11137)

(follow-up: ↓ 9 ) 02/26/08 02:23:15 changed by garrydolley

I have a question about a test that was changed, around line 36, looks like:

assert_equal "git clone git@somehost.com:project.git /var/www && cd /var/www && git checkout -b deploy #{rev}", @source.checkout(rev, dest)

Under the "# With branch" comment.

Problem is, this assertion is just a copy of the one before it. It does not check out "origin/foo". You didn't check to see whether it can checkout a different branch than the line above it.

I don't see anywhere where you have tested that using "set :branch, 'origin/foo'" or "set :branch, 'foo'" will actually work.

Am I missing something?

(in reply to: ↑ 8 ) 02/26/08 17:52:59 changed by voidlock

Replying to garrydolley:

I don't see anywhere where you have tested that using "set :branch, 'origin/foo'" or "set :branch, 'foo'" will actually work. Am I missing something?

The biggest change this patch introduces is the use of the revision parameter on the sync and checkout methods. As I mentioned in previous comments this moves the real branch detection into the query_revision. It will query the local Git repository for the SHA1 id of the :branch commit. So really testing the :branch option inside the sync and checkout tests is somewhat pointless.

I have opened a new ticket with a patch for tests, #11221. This new patch will hopefully resolve some of the confusion. I removed the assertions I feel a no longer needed, and added a comment to the test_head which is the only remaining place that the :branch option will be verified.

(Also, I'm not sure on policy here...hence the new ticket to address the test issues. I'm assuming people in the know will let me know if I should attach the test fixes back to this ticket and re-open, or keep all new comments and patches in the newer ticket.)