]> source.dussan.org Git - redmine.git/commitdiff
add local cache repository for speed purpose (subversion) or for browsing a external...
authorNicolas Chuche <nicolas.chuche@barna.be>
Mon, 22 Sep 2008 18:46:46 +0000 (18:46 +0000)
committerNicolas Chuche <nicolas.chuche@barna.be>
Mon, 22 Sep 2008 18:46:46 +0000 (18:46 +0000)
for SCM that can handle only local copy (git).

git-svn-id: http://redmine.rubyforge.org/svn/branches/nbc@1899 e93f8b46-1217-0410-a6f0-8f06a7374b81

41 files changed:
app/helpers/repositories_helper.rb
app/models/repository.rb
app/models/repository/git.rb
app/models/repository/subversion.rb
app/models/setting.rb
app/views/settings/_repositories.rhtml
config/settings.yml
db/migrate/099_add_local_copy.rb [new file with mode: 0644]
lang/bg.yml
lang/ca.yml
lang/cs.yml
lang/da.yml
lang/de.yml
lang/en.yml
lang/es.yml
lang/fi.yml
lang/fr.yml
lang/he.yml
lang/hu.yml
lang/it.yml
lang/ja.yml
lang/ko.yml
lang/lt.yml
lang/nl.yml
lang/no.yml
lang/pl.yml
lang/pt-br.yml
lang/pt.yml
lang/ro.yml
lang/ru.yml
lang/sr.yml
lang/sv.yml
lang/th.yml
lang/tr.yml
lang/uk.yml
lang/zh-tw.yml
lang/zh.yml
lib/redmine/scm/adapters/abstract_adapter.rb
lib/redmine/scm/adapters/git_adapter.rb
lib/redmine/scm/adapters/subversion_adapter.rb
test/unit/repository_test.rb

index 1a82bb8ce1a8c1aa42e7514517b578ee0d20506c..d798a2a5f0025057e53d2b30bedc6eacb254dd24 100644 (file)
@@ -146,7 +146,8 @@ module RepositoriesHelper
       content_tag('p', form.password_field(:password, :size => 30, :name => 'ignore',
                                            :value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)),
                                            :onfocus => "this.value=''; this.name='repository[password]';",
-                                           :onchange => "this.name='repository[password]';"))
+                                           :onchange => "this.name='repository[password]';")) +
+      content_tag('p',  form.check_box(:cache))
   end
 
   def darcs_field_tags(form, repository)
index 81e6647a271c2fa288f087ec2910a682d5b83dde..9ff22330a7402dc3cf622c3916e445a764f7778e 100644 (file)
@@ -1,3 +1,4 @@
+
 # redMine - project management software
 # Copyright (C) 2006-2007  Jean-Philippe Lang
 #
@@ -19,14 +20,14 @@ class Repository < ActiveRecord::Base
   belongs_to :project
   has_many :changesets, :order => "#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC"
   has_many :changes, :through => :changesets
-  
+
   # Raw SQL to delete changesets and changes in the database
   # has_many :changesets, :dependent => :destroy is too slow for big repositories
   before_destroy :clear_changesets
-  
+
   # Checks if the SCM is enabled when creating a repository
   validate_on_create { |r| r.errors.add(:type, :activerecord_error_invalid) unless Setting.enabled_scm.include?(r.class.name.demodulize) }
-  
+
   # Removes leading and trailing whitespace
   def url=(arg)
     write_attribute(:url, arg ? arg.to_s.strip : nil)
@@ -38,7 +39,8 @@ class Repository < ActiveRecord::Base
   end
 
   def scm
-    @scm ||= self.scm_adapter.new url, root_url, login, password
+    init_cache if cache_path.blank? and respond_to?(:init_cache)
+    @scm ||= self.scm_adapter.new(url, root_url, login, password, cache_path)
     update_attribute(:root_url, @scm.root_url) if root_url.blank?
     @scm
   end
@@ -122,9 +124,28 @@ class Repository < ActiveRecord::Base
   rescue
     nil
   end
-  
+
+  def remove_cache
+    scm.remove_cache if cache
+  end
+
+  def create_or_sync_cache
+    begin
+      scm.create_cache 
+    rescue => e
+      # clean if problem in creation
+      scm.remove_cache
+    end
+    scm.synchronize
+  end
+
   private
-  
+
+  def repositories_cache_directory
+    dir = Setting.repositories_cache_directory.gsub(/^([^#{File::SEPARATOR}].*)/, RAILS_ROOT + '/\1')
+    return dir if File.directory?(dir)
+  end
+
   def before_save
     # Strips url and root_url
     url.strip!
index 2f440fe29b805ee64e4d3423da8ab47dc9fd035a..f6b9c2fef34cba3ad144009cfb7162d3994c81ec 100644 (file)
@@ -21,6 +21,17 @@ class Repository::Git < Repository
   attr_protected :root_url
   validates_presence_of :url
 
+  before_destroy :remove_cache
+
+  def init_cache
+    return unless dir = repositories_cache_directory
+    # we need to use a cache only if repository isn't local and dir exists
+    if url[/^(rsync|https?|git|ssh):\/\//]
+      update_attribute(:cache_path, dir + project.identifier)
+      update_attribute(:cache, true)
+    end
+  end
+
   def scm_adapter
     Redmine::Scm::Adapters::GitAdapter
   end
@@ -36,6 +47,8 @@ class Repository::Git < Repository
   end
 
   def fetch_changesets
+    create_or_sync_cache if cache
+
     scm_info = scm.info
     if scm_info
       # latest revision found in database
index 3981d6f4c4540a62f27993183d3c2d43f327dfee..e29c42bb9baed677ab3249e5d114b7f7c53eafd9 100644 (file)
@@ -22,6 +22,16 @@ class Repository::Subversion < Repository
   validates_presence_of :url
   validates_format_of :url, :with => /^(http|https|svn|svn\+ssh|file):\/\/.+/i
 
+  before_destroy :remove_cache
+
+  def init_cache
+    return unless dir = repositories_cache_directory
+    # we need to use a cache only if repository isn't local and dir exists
+    if cache and url[/^(svn|https?|svn\+ssh):\/\//]
+      update_attribute(:cache_path, dir + project.identifier)
+    end
+  end
+
   def scm_adapter
     Redmine::Scm::Adapters::SubversionAdapter
   end
@@ -41,6 +51,8 @@ class Repository::Subversion < Repository
   end
   
   def fetch_changesets
+    create_or_sync_cache if cache
+
     scm_info = scm.info
     if scm_info
       # latest revision found in database
index 072afa0db12f099f7733cdc7046b67fef2f861ea..c59925a9ffc378eab91b81be39e48ccf5fce222d 100644 (file)
@@ -161,4 +161,14 @@ private
     setting = find_by_name(name)
     setting ||= new(:name => name, :value => @@available_settings[name]['default']) if @@available_settings.has_key? name
   end
+
+  protected
+
+  def validate
+    if self.name.to_s == "repositories_cache_directory" and not File.directory?(self.value.to_s)
+      logger.error("Le repertoire #{self.value.to_s} n'existe pas")
+      errors.add("Le repertoire #{self.value.to_s} n'existe pas")
+    end
+  end
+  
 end
index a8c924430ac7fb43659d39e42698c17af6cb1e50..fb4e88f4ce2d6aa20d691b9eb658cb9fbc760cd4 100644 (file)
@@ -17,6 +17,9 @@
 <p><label><%= l(:setting_repositories_encodings) %></label>
 <%= text_field_tag 'settings[repositories_encodings]', Setting.repositories_encodings, :size => 60 %><br /><em><%= l(:text_comma_separated) %></em></p>
 
+<p><label><%= l(:setting_repositories_cache_directory) %></label>
+<%= text_field_tag 'settings[repositories_cache_directory]', Setting.repositories_cache_directory, :size => 60 %></p>
+
 <p><label><%= l(:setting_commit_logs_encoding) %></label>
 <%= select_tag 'settings[commit_logs_encoding]', options_for_select(Setting::ENCODINGS, Setting.commit_logs_encoding) %></p>
 </div>
index e1ad341def107e36420bd7ae9160fd8a9d4962b3..52f7bed87ebf2e56237498fcbe2f3de303fd422a 100644 (file)
@@ -124,6 +124,8 @@ sequential_project_identifiers:
 # multiple values accepted, comma separated
 repositories_encodings:
   default: ''
+repositories_cache_directory:
+  default: 'tmp/scm/'
 # encoding used to convert commit logs to UTF-8
 commit_logs_encoding:
   default: 'UTF-8'
diff --git a/db/migrate/099_add_local_copy.rb b/db/migrate/099_add_local_copy.rb
new file mode 100644 (file)
index 0000000..2532f87
--- /dev/null
@@ -0,0 +1,12 @@
+class AddLocalCopy < ActiveRecord::Migration
+  def self.up
+    add_column :repositories, :cache, :boolean
+    add_column :repositories, :cache_path, :string, :limit => 255, :default => ""
+
+  end
+
+  def self.down
+    remove_column :repositories, :cache
+    remove_column :repositories, :cache_path
+  end
+end
index f8d2e5e2ca62d0951bb2592f35ca052d1564c664..7c171a4612871ca4cd0808b7af5ca0ed9d374c4f 100644 (file)
@@ -640,3 +640,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 30348b060ea4bef78e49bbc250f7f33acad526a3..0641d781b7efc0074a0e11aa90d0a2a990e75b8e 100644 (file)
@@ -642,3 +642,5 @@ field_comments: Comment
 setting_commit_logs_encoding: Commit messages encoding
 label_renamed: renamed\r
 label_copied: copied\r
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index cf2cb09929817c115b297fd13874547d1e88adf2..29babd3a95cf61043a9861f6e965eeb43695c697 100644 (file)
@@ -645,3 +645,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 0ee1b25122744833d348b72299d364a00c9f7ab5..92f5501a2bb70697083f7f2ac3a6247b588638c8 100644 (file)
@@ -641,3 +641,5 @@ default_activity_development: Udvikling
 enumeration_issue_priorities: Sagsprioriteter
 enumeration_doc_categories: Dokumentkategorier
 enumeration_activities: Aktiviteter (tidsregistrering)
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 7aa2d971b7844139618936ce0da3d5267e7646c7..dbbb1183d8b612af524947fe7f49f1897a2dd2db 100644 (file)
@@ -641,3 +641,5 @@ default_activity_development: Entwicklung
 enumeration_issue_priorities: Ticket-Prioritäten
 enumeration_doc_categories: Dokumentenkategorien
 enumeration_activities: Aktivitäten (Zeiterfassung)
+field_cache: Local cache
+setting_repositories_cache_directory: Cache directory for repositories
index 8a73a3992605a2ae1054ef8660607e4463d88ef8..22543af267053c9fde6690b8116d329bb26c92ec 100644 (file)
@@ -184,6 +184,7 @@ field_searchable: Searchable
 field_default_value: Default value
 field_comments_sorting: Display comments
 field_parent_title: Parent page
+field_cache: Local cache
 
 setting_app_title: Application title
 setting_app_subtitle: Application subtitle
@@ -221,6 +222,7 @@ setting_enabled_scm: Enabled SCM
 setting_mail_handler_api_enabled: Enable WS for incoming emails
 setting_mail_handler_api_key: API key
 setting_sequential_project_identifiers: Generate sequential project identifiers
+setting_repositories_cache_directory: Cache directory for repositories
 
 project_module_issue_tracking: Issue tracking
 project_module_time_tracking: Time tracking
index ae367d8429700dd25c262f23ed3f108e9de24ed1..05d42549c79c37c67c67658fe40cd0e8d333cc32 100644 (file)
@@ -643,3 +643,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 225563b37f93020c859a40c0868d854dad28a21a..d674568ef1206572583e30fce9c1dd8d5d5c91ad 100644 (file)
@@ -640,3 +640,5 @@ setting_commit_logs_encoding: Commit messages encoding
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index b640780681737b1c109ce8081956f58681ca8648..77c358a9bcb9e3756d244507f275bfbcfd401a80 100644 (file)
@@ -221,6 +221,7 @@ setting_enabled_scm: SCM activés
 setting_mail_handler_api_enabled: "Activer le WS pour la réception d'emails"
 setting_mail_handler_api_key: Clé de protection de l'API
 setting_sequential_project_identifiers: Générer des identifiants de projet séquentiels
+setting_repositories_cache_directory: Répertoire du cache pour les dépôts
 
 project_module_issue_tracking: Suivi des demandes
 project_module_time_tracking: Suivi du temps passé
@@ -641,3 +642,4 @@ enumeration_issue_priorities: Priorités des demandes
 enumeration_doc_categories: Catégories des documents
 enumeration_activities: Activités (suivi du temps)
 notice_unable_delete_version: Unable to delete version
+field_cache: Cache local
index 07962d2de039aa1ae2be6a99eddbb0fc4c1589ec..f95843b85a768358ae818867a89a8ca0ccbcd7ff 100644 (file)
@@ -640,3 +640,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 3a3d18a12e82f5635499865d0a5612a46415d131..28008aabbc643260855ea8ac58b5cbfb8be6dd3c 100644 (file)
@@ -641,3 +641,5 @@ setting_sequential_project_identifiers: Szekvenciális projekt azonosítók gene
 notice_unable_delete_version: A verziót nem lehet törölni
 label_renamed: átnevezve
 label_copied: lemásolva
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index bca755605587d8c58778f5c2be42cc49852994fc..20e53472c42213ad7fabe357b631a4e186f6934b 100644 (file)
@@ -640,3 +640,5 @@ setting_sequential_project_identifiers: Genera progetti con identificativi in se
 notice_unable_delete_version: Impossibile cancellare la versione
 label_renamed: rinominato
 label_copied: copiato
+field_cache: Local cache
+setting_repositories_cache_directory: Cache directory for repositories
index 4e46212b20e8e71b3483d02491df11e3d8b4ea26..95c632b8d0cdb97096b6e1e4d743fa7273bce991 100644 (file)
@@ -641,3 +641,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index c23ea71cdc08a8220ea81ba13b39797e37a99f17..0d96274f2bffa8cb1c6856da0db855f789437e94 100644 (file)
@@ -640,3 +640,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index f29c28c4f8aefe3b55014102aa1c2192bc460f45..ffb8315752f3cb0c9891246d7a50a01e2d89572a 100644 (file)
@@ -642,3 +642,5 @@ button_quote: Cituoti
 notice_unable_delete_version: Neimanoma panaikinti versiją
 label_renamed: pervardintas
 label_copied: nukopijuotas
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 8fd96d1c17fcb325af84aeaf98ccc37e6d85adb9..18954534a3fa881793ad6fa3df29415cf6226a7f 100644 (file)
@@ -643,3 +643,5 @@ setting_sequential_project_identifiers: Genereer sequentiele project identiteite
 notice_unable_delete_version: Onmogelijk om deze versie te verwijderen.
 label_renamed: hernoemt
 label_copied: gekopieerd
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 8cd6952c62988999e09b41b0a614b26eb694b8d0..9b3be9ae182dd2aac80f62b26099276ab76c24d9 100644 (file)
@@ -641,3 +641,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 5003db73975517bf83144620d95d372ffb3d7933..dc49dce4bd950f1adb22d6209fa662b668f3362b 100644 (file)
@@ -640,3 +640,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 3e314af8cb900303d75ee9e44c47c5314c3edc31..74ee2486c4775718bdd41354b0908bbdb3c94a2c 100644 (file)
@@ -641,3 +641,5 @@ enumeration_activities: Atividades (time tracking)
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed\r
 label_copied: copied\r
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index e968ef3b473c1a0dea22827c24964a69baa8c7bc..98f13108bbd5ac93f53d5ae7965e9bdb316d622a 100644 (file)
@@ -640,3 +640,5 @@ setting_sequential_project_identifiers: Gerar identificador sequencial
 notice_unable_delete_version: Impossível apagar esta versão
 label_renamed: renomeado
 label_copied: copiado
+field_cache: Local cache
+setting_repositories_cache_directory: Cache directory for repositories
index 94278256e29ef4238199a69f7d5cc64ff9526a82..1f399989c769467c12a677b2bfaa5bbaf01c4bdf 100644 (file)
@@ -640,3 +640,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index ce5e43b7d84f542f9744e6c847bde32aa5c0c501..bcc7121b2f7f97adef6e5234ba8961ac36f59bd9 100644 (file)
@@ -673,3 +673,5 @@ text_user_wrote: '%s написал(а):'
 text_wiki_destroy_confirmation: Вы уверены, что хотите удалить данную Wiki и все содержимое?
 text_workflow_edit: Выберите роль и трекер для редактирования последовательности состояний
 
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 720dfcdffa07c8f162ba40e625fe5e2773bb68ff..3ac7b7cd94a0b932f8a4163bd3cbfb9e203c7186 100644 (file)
@@ -641,3 +641,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 393ade8187318c03ed1932d2a2804364d7636419..5df46232de287712ab092d4985e7f0429db12f41 100644 (file)
@@ -641,3 +641,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 362e447569ba74fad92d62dafd53d683046a5a3d..ca2db8bcc759bc8e7255b2e020fb5d99f357c26e 100644 (file)
@@ -643,3 +643,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index ba9c0b41b63b82bb12c0224cfcb5fc6fdec27aa9..56bf3311ad59b2404f2f0b0a17ff377d5977863f 100644 (file)
@@ -641,3 +641,5 @@ general_csv_decimal_separator: '.'
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index de5f65eb0c019b9aff9c9d8ef9ce9f75d154a09c..dd3954a902b382c24d48fe96e7fac5e9eb4342df 100644 (file)
@@ -642,3 +642,5 @@ setting_sequential_project_identifiers: Generate sequential project identifiers
 notice_unable_delete_version: Unable to delete version
 label_renamed: renamed
 label_copied: copied
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 6feb0a0e809ab06c18de2a4aeb756ac98ad767b4..3ddf1402e15d5b666a75189765706c095e20b27e 100644 (file)
@@ -641,3 +641,5 @@ default_activity_development: 開發
 enumeration_issue_priorities: 項目優先權
 enumeration_doc_categories: 文件分類
 enumeration_activities: 活動 (時間追蹤)
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index d2e571b4d3849f5e7229d9cf39250912448004f0..cd2d3e407efb614fe23110906387a5c8827fe9a7 100644 (file)
@@ -641,3 +641,5 @@ default_activity_development: 开发
 enumeration_issue_priorities: 问题优先级
 enumeration_doc_categories: 文档类别
 enumeration_activities: 活动(时间跟踪)
+setting_repositories_cache_directory: Cache directory for repositories
+field_cache: Local cache
index 9f400880dc395b9e27cb06d4028e6055bc11cba4..7e09d1611c0ba586b8d61189fcb6e2ade21bd70d 100644 (file)
@@ -47,11 +47,17 @@ module Redmine
           end
         end
                 
-        def initialize(url, root_url=nil, login=nil, password=nil)
+        def initialize(url, root_url=nil, login=nil, password=nil, cache_path=nil)
           @url = url
           @login = login if login && !login.empty?
           @password = (password || "") if @login
-          @root_url = root_url.blank? ? retrieve_root_url : root_url
+
+          if cache_path.blank?
+            @root_url = root_url.blank? ? retrieve_root_url : root_url
+          else
+            @orig_url = @url
+            @url = @root_url = cache_path
+          end
         end
         
         def adapter_name
@@ -145,7 +151,22 @@ module Redmine
           end
         end
 
+        def remove_cache
+          remove_directory(@root_url) if not @orig_url.blank? and File.directory?(@root_url) 
+        end
+
       private
+        def remove_directory(path)
+          Dir.entries(path).each do |f|
+            next if %w[. ..].include?(f)
+            name = "#{path}/#{f}"
+            File.directory?(name) ? remove_directory(name)  : File.unlink(name)
+          end
+          Dir.rmdir path
+        rescue Errno::ENOENT => e
+          logger.error(e.to_s)
+        end
+
         def retrieve_root_url
           info = self.info
           info ? info.root_url : nil
@@ -194,7 +215,7 @@ module Redmine
           self.class.strip_credential(cmd)
         end
       end
-      
+
       class Entries < Array
         def sort_by_name
           sort {|x,y| 
index 30d6240017abbb1af71f876cd85fee38b5b08136..c1f3e335b4e8cb9db9693fe579faf3ea0e5fa70a 100644 (file)
@@ -25,6 +25,11 @@ module Redmine
         # Git executable name
         GIT_BIN = "git"
 
+        def initialize(url, root_url=nil, login=nil, password=nil, cache_path=nil)
+          super(url, root_url, login, password, cache_path)
+          @url += "/.git/" unless cache_path.blank?
+        end
+
         # Get the revision of a particuliar file
         def get_rev (rev,path)
         
@@ -263,9 +268,20 @@ module Redmine
           return nil if $? && $?.exitstatus != 0
           cat
         end
+
+        def create_cache
+          cmd = "#{GIT_BIN} clone #{@orig_url} #{@root_url}"
+          shellout(cmd) { |io| io.read }
+        end
+
+        def synchronize
+          return unless File.directory?(@url)
+          cmd = "#{GIT_BIN} --git-dir #{@url} pull"
+          shellout(cmd)
+        end
+
       end
     end
   end
-
 end
 
index 2b7f0192e12ab30cc4735c9a00c6330e4bc1b668..109e9e756d34bf89830a3cf64cc7abf2d2d9ab51 100644 (file)
@@ -25,7 +25,7 @@ module Redmine
       \r
         # SVN executable name\r
         SVN_BIN = "svn"\r
-        \r
+\r
         class << self\r
           def client_version\r
             @@client_version ||= (svn_binary_version || [])\r
@@ -213,6 +213,18 @@ module Redmine
           return nil if $? && $?.exitstatus != 0\r
           blame\r
         end\r
+\r
+        def create_cache\r
+          return if @orig_url.blank?\r
+          cmd = "#{SVN_BIN} checkout --non-interactive #{@orig_url} #{@root_url}"\r
+          shellout(cmd) { |io| io.read }\r
+        end\r
+\r
+        def synchronize\r
+          return if @orig_url.blank?\r
+          cmd = "#{SVN_BIN} update --non-interactive"\r
+          Dir.chdir(@root_url) { shellout(cmd) { |io| io.read } }\r
+        end\r
         \r
         private\r
         \r
@@ -222,6 +234,7 @@ module Redmine
           str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?\r
           str\r
         end\r
+\r
       end\r
     end\r
   end\r
index 9ea9fdd45fa919df32d6d51ad932caa2a825d8e7..0973c7fdba5ab91dd10f24ed6f0d951555dc1398 100644 (file)
@@ -127,4 +127,26 @@ class RepositoryTest < Test::Unit::TestCase
     assert_equal ':pserver:login:password@host:/path/to/the/repository', repository.url
     assert_equal 'foo', repository.root_url
   end
+
+  def test_local_cache
+    dir = Setting.repositories_cache_directory.gsub(/^([^#{File::SEPARATOR}].*)/, RAILS_ROOT + '/\1')
+
+    project = projects(:projects_001)
+
+    repository = Repository::Git.new(:project => Project.find_by_name(project.name), :url => "git://github.com/olabini/paipr.git")
+    repository.scm
+    assert_equal(dir + project.identifier, repository.cache_path)
+
+    repository = Repository::Git.new(:project => Project.find(:first), :url => "/var/cache/git/paipr/.git")
+    repository.init_cache
+    assert repository.cache_path.blank?
+
+    repository = Repository::Subversion.new(:project => Project.find(:first), :url => "svn://github.com/olabini/paipr.git")
+    repository.init_cache
+    assert repository.cache_path.blank?
+
+    repository = Repository::Subversion.new(:project => Project.find_by_name(project.name), :url => "svn://github.com/olabini/paipr.git", :cache => true)
+    repository.init_cache
+    assert_equal(dir + project.identifier, repository.cache_path)
+  end
 end