Project

General

Profile

Patch #259 » gitdiff-improved.diff

John Goerzen, 2008-03-07 06:35

View differences:

app/helpers/application_helper.rb
270 270
    #     #52 -> Link to issue #52
271 271
    #   Changesets:
272 272
    #     r52 -> Link to revision 52
273
    #     commit:a85130f -> Link to scmid starting with a85130f
273 274
    #   Documents:
274 275
    #     document#17 -> Link to document with id 17
275 276
    #     document:Greetings -> Link to the document with title "Greetings"
......
280 281
    #     version:"1.0 beta 2" -> Link to version named "1.0 beta 2"
281 282
    #   Attachments:
282 283
    #     attachment:file.zip -> Link to the attachment of the current object named file.zip
283
    text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version)?((#|r)(\d+)|(:)([^"][^\s<>]+|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
284
    text = text.gsub(%r{([\s\(,-^])(!)?(attachment|document|version|commit)?((#|r)(\d+)|(:)([^"][^\s<>]+|"[^"]+"))(?=[[:punct:]]|\s|<|$)}) do |m|
284 285
      leading, esc, prefix, sep, oid = $1, $2, $3, $5 || $7, $6 || $8
285 286
      link = nil
286 287
      if esc.nil?
......
325 326
              link = link_to h(version.name), {:only_path => only_path, :controller => 'versions', :action => 'show', :id => version},
326 327
                                              :class => 'version'
327 328
            end
329
          when 'commit'
330
            if project && (changeset = project.changesets.find(:first, :conditions => ["scmid LIKE ?", "#{name}%"]))
331
              link = link_to h("#{name}"), {:only_path => only_path, :controller => 'repositories', :action => 'revision', :id => project.id, :rev => changeset.revision}, :class => 'changeset', :title => truncate(changeset.comments, 100)
332
            end
328 333
          when 'attachment'
329 334
            if attachments && attachment = attachments.detect {|a| a.filename == name }
330 335
              link = link_to h(attachment.filename), {:only_path => only_path, :controller => 'attachments', :action => 'download', :id => attachment},
app/helpers/repositories_helper.rb
76 76
      content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
77 77
  end
78 78

  
79
  def git_field_tags(form, repository)
80
      content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
81
  end
82

  
79 83
  def cvs_field_tags(form, repository)
80 84
      content_tag('p', form.text_field(:root_url, :label => 'CVSROOT', :size => 60, :required => true, :disabled => !repository.new_record?)) +
81 85
      content_tag('p', form.text_field(:url, :label => 'Module', :size => 30, :required => true, :disabled => !repository.new_record?))
app/models/repository/git.rb
1
# redMine - project management software
2
# Copyright (C) 2006-2007  Jean-Philippe Lang
3
# Copyright (C) 2007  Patrick Aljord patcito@ŋmail.com
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require 'redmine/scm/adapters/git_adapter'
19

  
20
class Repository::Git < Repository
21
  attr_protected :root_url
22
  validates_presence_of :url
23

  
24
  def scm_adapter
25
    Redmine::Scm::Adapters::GitAdapter
26
  end
27
  
28
  def self.scm_name
29
    'Git'
30
  end
31
  
32
  def entries(path=nil, identifier=nil)
33
    entries=scm.entries(path, identifier)
34
    if entries
35
      entries.each do |entry|
36
        next unless entry.is_file?
37
        # Search the DB for the entry's last change
38
        change = changes.find(:first, :conditions => ["path = ?", scm.with_leading_slash(entry.path)], :order => "#{Changeset.table_name}.committed_on DESC")
39
        if change
40
          entry.lastrev.identifier = change.changeset.revision
41
          entry.lastrev.name = change.changeset.revision
42
          entry.lastrev.author = change.changeset.committer
43
          entry.lastrev.revision = change.revision
44
        end
45
      end
46
    end
47
    entries
48
  end
49

  
50
  def changesets_for_path(path)
51
    path = "#{path}" unless path.starts_with?('/')
52
    Change.find(:all, :include => :changeset, 
53
                :conditions => ["repository_id = ? AND path = ?", id, path],
54
                :order => "committed_on DESC, #{Changeset.table_name}.revision DESC").collect(&:changeset)
55
  end
56

  
57
  def fetch_changesets
58
    scm_info = scm.info
59
    
60

  
61
    if scm_info
62
      # latest revision found in database
63
      db_revision = latest_changeset ? latest_changeset.scmid : nil
64
      next_rev = latest_changeset ? latest_changeset.revision + 1 : 1
65
      # latest revision in the repository
66
      scm_revision = scm_info.lastrev.scmid
67

  
68
      unless changesets.find_by_scmid(scm_revision)
69

  
70
        revisions = scm.revisions('', db_revision, nil)
71
        transaction do
72
          revisions.reverse_each do |revision|
73
            changeset = Changeset.create(:repository => self,
74
                                         :revision => next_rev,
75
                                         :scmid => revision.scmid,
76
                                         :committer => revision.author, 
77
                                         :committed_on => revision.time,
78
                                         :comments => revision.message)
79
            next_rev += 1
80
            
81
            revision.paths.each do |change|
82
              Change.create(:changeset => changeset,
83
                            :action => change[:action],
84
                            :path => change[:path],
85
                            :from_path => change[:from_path],
86
                            :from_revision => change[:from_revision])
87
            end
88
          end
89
        end
90
      end
91
    end
92
  end
93
end
app/views/repositories/_dir_list_content.rhtml
25 25
<td class="size"><%= (entry.size ? number_to_human_size(entry.size) : "?") unless entry.is_dir? %></td>
26 26
<td class="revision"><%= link_to(entry.lastrev.name, :action => 'revision', :id => @project, :rev => entry.lastrev.identifier) if entry.lastrev && entry.lastrev.identifier %></td>
27 27
<td class="age"><%= distance_of_time_in_words(entry.lastrev.time, Time.now) if entry.lastrev && entry.lastrev.time %></td>
28
<td class="author"><%=h(entry.lastrev.author) if entry.lastrev %></td>
28
<td class="author"><%=h(entry.lastrev.author.split('<').first) if entry.lastrev %></td>
29 29
<% changeset = @project.repository.changesets.find_by_revision(entry.lastrev.identifier) if entry.lastrev %>
30 30
<td class="comments"><%=h truncate(changeset.comments, 50) unless changeset.nil? %></td>
31 31
</tr>
app/views/repositories/_revisions.rhtml
17 17
<td class="checkbox"><%= radio_button_tag('rev', changeset.revision, (line_num==1), :id => "cb-#{line_num}", :onclick => "$('cbto-#{line_num+1}').checked=true;") if show_diff && (line_num < revisions.size) %></td>
18 18
<td class="checkbox"><%= radio_button_tag('rev_to', changeset.revision, (line_num==2), :id => "cbto-#{line_num}", :onclick => "if ($('cb-#{line_num}').checked==true) {$('cb-#{line_num-1}').checked=true;}") if show_diff && (line_num > 1) %></td>
19 19
<td class="committed_on"><%= format_time(changeset.committed_on) %></td>
20
<td class="author"><%=h changeset.committer %></td>
20
<td class="author"><%=h changeset.committer.split('<').first %></td>
21 21
<td class="comments"><%= textilizable(changeset.comments) %></td>
22 22
</tr>
23 23
<% line_num += 1 %>
doc/RUNNING_TESTS
19 19
Mercurial
20 20
---------
21 21
gunzip < test/fixtures/repositories/mercurial_repository.tar.gz | tar -xv -C tmp/test
22

  
23
Git
24
---
25
gunzip < test/fixtures/repositories/git_repository.tar.gz | tar -xv -C tmp/test
26

  
27

  
28
Running Tests
29
=============
30

  
31
Run 
32

  
33
  rake --tasks | grep test
34

  
35
to see available tests.
36

  
37
RAILS_ENV=test rake test will run tests.
lib/redmine.rb
10 10
  # RMagick is not available
11 11
end
12 12

  
13
REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar )
13
REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar Git )
14 14

  
15 15
# Permissions
16 16
Redmine::AccessControl.map do |map|
lib/redmine/scm/adapters/git_adapter.rb
1
# redMine - project management software
2
# Copyright (C) 2006-2007  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require 'redmine/scm/adapters/abstract_adapter'
19

  
20
module Redmine
21
  module Scm
22
    module Adapters    
23
      class GitAdapter < AbstractAdapter
24
        
25
        # Git executable name
26
        GIT_BIN = "git"
27

  
28
        # Convert an identifier to a git revision
29
        def id_to_rev(identifier)
30
          if identifier.nil?
31
            return nil
32
          end
33
          
34
          cmd = "cd #{target('')} && #{GIT_BIN} log --reverse --raw "
35
          cmd << "--skip="
36
          cmd << ((identifier - 1).to_s)
37
          answer = nil
38

  
39
          shellout(cmd) do |io|
40
            
41
            io.each_line do |line|
42
              if answer.nil? && line =~ /^commit ([0-9a-f]{40})$/
43
                answer = $1
44
              else
45
                next
46
              end
47
            end
48
          end
49

  
50
          return answer
51
        end
52

  
53
        #get the revision of a particuliar file
54
	def get_rev (rev,path)
55
          cmd="cd #{target('')} && git show #{rev} -- #{path}" if rev!='latest'
56
          cmd="cd #{target('')} && git log -1 master -- #{path}" if 
57
            rev=='latest' or rev.nil?
58
          rev=[]
59
          i=0
60
          shellout(cmd) do |io|
61
            files=[]
62
            changeset = {}
63
            parsing_descr = 0  #0: not parsing desc or files, 1: parsing desc, 2: parsing files
64
            line_feeds = 0
65

  
66
            io.each_line do |line|
67
              if line =~ /^commit ([0-9a-f]{40})$/
68
                key = "commit"
69
                value = $1
70
                if (parsing_descr == 1 || parsing_descr == 2)
71
                  parsing_descr = 0
72
                  rev = Revision.new({:identifier => nil,
73
                                             :scmid => changeset[:commit],
74
                                             :author => changeset[:author],
75
                                             :time => Time.parse(changeset[:date]),
76
                                             :message => changeset[:description],
77
                                             :paths => files
78
                                            })
79
                  changeset = {}
80
                  files = []
81
                end
82
                changeset[:commit] = $1
83
              elsif (parsing_descr == 0) && line =~ /^(\w+):\s*(.*)$/
84
                key = $1
85
                value = $2
86
                if key == "Author"
87
                  changeset[:author] = value
88
                elsif key == "Date"
89
                  changeset[:date] = value
90
                end
91
              elsif (parsing_descr == 0) && line.chomp.to_s == ""
92
                parsing_descr = 1
93
                changeset[:description] = ""
94
              elsif (parsing_descr == 1 || parsing_descr == 2) && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\s+(.+)$/
95
                parsing_descr = 2
96
                fileaction = $1
97
                filepath = $2
98
                files << {:action => fileaction, :path => filepath}
99
              elsif (parsing_descr == 1) && line.chomp.to_s == ""
100
                parsing_descr = 2
101
              elsif (parsing_descr == 1)
102
                changeset[:description] << line
103
              end
104
            end	
105
            rev = Revision.new({:identifier => nil,
106
                                       :scmid => changeset[:commit],
107
                                       :author => changeset[:author],
108
                                       :time => Time.parse(changeset[:date]),
109
                                       :message => changeset[:description],
110
                                       :paths => files
111
                                      })
112

  
113
          end
114

  
115
          get_rev('latest',path) if rev == []
116

  
117
          return nil if $? && $?.exitstatus != 0
118
          return rev
119
          #         rescue Errno::ENOENT => e
120
          #           raise CommandFailed
121
        end
122

  
123

  
124
        def info
125
          #           cmd = "#{GIT_BIN} -R #{target('')} root"
126
          #           root_url = nil
127
          #           shellout(cmd) do |io|
128
          root_url = target('')
129
          #           end
130
          info = Info.new({:root_url => target(''),
131
                            :lastrev => revisions(root_url,nil,nil,nil).first
132
                          })
133
          info
134
        rescue Errno::ENOENT => e
135
          return nil
136
        end
137
        
138
        def entries(path=nil, identifier=nil)
139
          path ||= ''
140
          entries = Entries.new
141
          cmd = "cd #{target('')} && #{GIT_BIN} ls-tree -l HEAD:#{path}" if identifier.nil?
142
          cmd = "cd #{target('')} && #{GIT_BIN} ls-tree -l #{identifier}:#{path}" if identifier
143
          shellout(cmd)  do |io|
144
            io.each_line do |line|
145
              e = line.chomp.to_s
146
              if e =~ /^\d+\s+(\w+)\s+([0-9a-f]{40})\s+([0-9-]+)\s+(.+)$/
147
                type = $1
148
                sha = $2
149
                size = $3
150
                name = $4
151
                entries << Entry.new({:name => name,
152
                                       :path => (path.empty? ? name : "#{path}/#{name}"),
153
                                       :kind => ((type == "tree") ? 'dir' : 'file'),
154
                                       :size => ((type == "tree") ? nil : size),
155
                                       :lastrev => get_rev(identifier,(path.empty? ? name : "#{path}/#{name}")) 
156
                                                                  
157
                                     }) unless entries.detect{|entry| entry.name == name}
158
              end
159
            end
160
          end
161
          return nil if $? && $?.exitstatus != 0
162
          entries.sort_by_name
163
          #         rescue Errno::ENOENT => e
164
          #           raise CommandFailed
165
        end
166
        
167
        def entry(path=nil, identifier=nil)
168
          path ||= ''
169
          search_path = path.split('/')[0..-2].join('/')
170
          entry_name = path.split('/').last
171
          e = entries(search_path, identifier)
172
          e ? e.detect{|entry| entry.name == entry_name} : nil
173
        end
174
        
175
        def revisions(path, identifier_from, identifier_to, options={})
176
          revisions = Revisions.new
177
          cmd = "cd #{target('')} && #{GIT_BIN} log --raw "
178
          cmd << " #{identifier_from}.. " if identifier_from
179
          cmd << " #{identifier_to} " if identifier_to
180
          #cmd << " HEAD " if !identifier_to
181
          shellout(cmd) do |io|
182
            files=[]
183
            changeset = {}
184
            parsing_descr = 0  #0: not parsing desc or files, 1: parsing desc, 2: parsing files
185
            line_feeds = 0
186
            revno = 1
187

  
188
            io.each_line do |line|
189
              if line =~ /^commit ([0-9a-f]{40})$/
190
                key = "commit"
191
                value = $1
192
                if (parsing_descr == 1 || parsing_descr == 2)
193
                  parsing_descr = 0
194
                  revisions << Revision.new({:identifier => nil,
195
                                             :scmid => changeset[:commit],
196
                                             :author => changeset[:author],
197
                                             :time => Time.parse(changeset[:date]),
198
                                             :message => changeset[:description],
199
                                             :paths => files
200
                                            })
201
                  changeset = {}
202
                  files = []
203
                  revno = revno + 1
204
                end
205
                changeset[:commit] = $1
206
              elsif (parsing_descr == 0) && line =~ /^(\w+):\s*(.*)$/
207
                key = $1
208
                value = $2
209
                if key == "Author"
210
                  changeset[:author] = value
211
                elsif key == "Date"
212
                  changeset[:date] = value
213
                end
214
              elsif (parsing_descr == 0) && line.chomp.to_s == ""
215
                parsing_descr = 1
216
                changeset[:description] = ""
217
              elsif (parsing_descr == 1 || parsing_descr == 2) && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\s+(.+)$/
218
                parsing_descr = 2
219
                fileaction = $1
220
                filepath = $2
221
                files << {:action => fileaction, :path => filepath}
222
              elsif (parsing_descr == 1) && line.chomp.to_s == ""
223
                parsing_descr = 2
224
              elsif (parsing_descr == 1)
225
                changeset[:description] << line[4..-1]
226
              end
227
            end	
228

  
229
            revisions << Revision.new({:identifier => nil,
230
                                       :scmid => changeset[:commit],
231
                                       :author => changeset[:author],
232
                                       :time => Time.parse(changeset[:date]),
233
                                       :message => changeset[:description],
234
                                       :paths => files
235
                                      })
236

  
237
          end
238

  
239
          return nil if $? && $?.exitstatus != 0
240
          revisions
241
        rescue Errno::ENOENT => e
242
          raise CommandFailed
243
        end
244
        
245
        def diff(path, identifier_from, identifier_to=nil, type="inline")
246
          path ||= ''
247
          if identifier_to
248
            identifier_to = identifier_to 
249
          else
250
            identifier_to = nil
251
          end
252

  
253
          identifier_from = id_to_rev(identifier_from)
254
          identifier_to = id_to_rev(identifier_to)
255
          
256
          cmd = "cd #{target('')} && #{GIT_BIN}  diff   #{identifier_from}^!" if identifier_to.nil?
257
          cmd = "cd #{target('')} && #{GIT_BIN}  diff #{identifier_to}  #{identifier_from}" if !identifier_to.nil?
258
          cmd << " -- #{path}" unless path.empty?
259
          diff = []
260
          shellout(cmd) do |io|
261
            io.each_line do |line|
262
              diff << line
263
            end
264
          end
265
          return nil if $? && $?.exitstatus != 0
266
          DiffTableList.new diff, type
267
          
268
        rescue Errno::ENOENT => e
269
          raise CommandFailed
270
        end
271
        
272
        def cat(path, identifier=nil)
273
          identifier = id_to_rev(identifier)
274
          if identifier.nil?
275
            identifier = 'HEAD'
276
          end
277
          cmd = "cd #{target('')} && #{GIT_BIN} show #{identifier}:#{path}"
278
          cat = nil
279
          shellout(cmd) do |io|
280
            io.binmode
281
            cat = io.read
282
          end
283
          return nil if $? && $?.exitstatus != 0
284
          cat
285
        rescue Errno::ENOENT => e
286
          raise CommandFailed
287
        end
288
      end
289
    end
290
  end
291

  
292
end
293

  
test/functional/repositories_git_controller_test.rb
1
# redMine - project management software
2
# Copyright (C) 2006-2007  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.dirname(__FILE__) + '/../test_helper'
19
require 'repositories_controller'
20

  
21
# Re-raise errors caught by the controller.
22
class RepositoriesController; def rescue_action(e) raise e end; end
23

  
24
class RepositoriesGitControllerTest < Test::Unit::TestCase
25
  fixtures :projects, :users, :roles, :members, :repositories, :enabled_modules
26

  
27
  # No '..' in the repository path
28
  REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository'
29

  
30
  def setup
31
    @controller = RepositoriesController.new
32
    @request    = ActionController::TestRequest.new
33
    @response   = ActionController::TestResponse.new
34
    User.current = nil
35
    Repository::Git.create(:project => Project.find(3), :url => REPOSITORY_PATH)
36
  end
37
  
38
  if File.directory?(REPOSITORY_PATH)
39
    def test_show
40
      get :show, :id => 3
41
      assert_response :success
42
      assert_template 'show'
43
      assert_not_nil assigns(:entries)
44
      assert_not_nil assigns(:changesets)
45
    end
46
    
47
    def test_browse_root
48
      get :browse, :id => 3
49
      assert_response :success
50
      assert_template 'browse'
51
      assert_not_nil assigns(:entries)
52
      assert_equal 3, assigns(:entries).size
53
      assert assigns(:entries).detect {|e| e.name == 'images' && e.kind == 'dir'}
54
      assert assigns(:entries).detect {|e| e.name == 'sources' && e.kind == 'dir'}
55
      assert assigns(:entries).detect {|e| e.name == 'README' && e.kind == 'file'}
56
    end
57
    
58
    def test_browse_directory
59
      get :browse, :id => 3, :path => ['images']
60
      assert_response :success
61
      assert_template 'browse'
62
      assert_not_nil assigns(:entries)
63
      assert_equal 2, assigns(:entries).size
64
      entry = assigns(:entries).detect {|e| e.name == 'edit.png'}
65
      assert_not_nil entry
66
      assert_equal 'file', entry.kind
67
      assert_equal 'images/edit.png', entry.path
68
    end
69
    
70
    def test_changes
71
      get :changes, :id => 3, :path => ['images', 'edit.png']
72
      assert_response :success
73
      assert_template 'changes'
74
      assert_tag :tag => 'h2', :content => 'edit.png'
75
    end
76
    
77
    def test_entry_show
78
      get :entry, :id => 3, :path => ['sources', 'watchers_controller.rb']
79
      assert_response :success
80
      assert_template 'entry'
81
      # Line 19
82
      assert_tag :tag => 'th',
83
                 :content => /10/,
84
                 :attributes => { :class => /line-num/ },
85
                 :sibling => { :tag => 'td', :content => /WITHOUT ANY WARRANTY/ }
86
    end
87
    
88
    def test_entry_download
89
      get :entry, :id => 3, :path => ['sources', 'watchers_controller.rb'], :format => 'raw'
90
      assert_response :success
91
      # File content
92
      assert @response.body.include?('WITHOUT ANY WARRANTY')
93
    end
94
  
95
    def test_diff
96
      # Full diff of changeset 4
97
      get :diff, :id => 3, :rev => 4
98
      assert_response :success
99
      assert_template 'diff'
100
      # Line 22 removed
101
      assert_tag :tag => 'th',
102
                 :content => /22/,
103
                 :sibling => { :tag => 'td', 
104
                               :attributes => { :class => /diff_out/ },
105
                               :content => /def remove/ }
106
    end
107
    
108
    def test_annotate
109
      get :annotate, :id => 3, :path => ['sources', 'watchers_controller.rb']
110
      assert_response :success
111
      assert_template 'annotate'
112
      # Line 23, revision 4
113
      assert_tag :tag => 'th', :content => /23/,
114
                 :sibling => { :tag => 'td', :child => { :tag => 'a', :content => /4/ } },
115
                 :sibling => { :tag => 'td', :content => /jsmith/ },
116
                 :sibling => { :tag => 'td', :content => /watcher =/ }
117
    end
118
  else
119
    puts "Git test repository NOT FOUND. Skipping functional tests !!!"
120
    def test_fake; assert true end
121
  end
122
end
test/unit/repository_git_test.rb
1
# redMine - project management software
2
# Copyright (C) 2006-2007  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
# 
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
# 
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.dirname(__FILE__) + '/../test_helper'
19

  
20
class RepositoryGitTest < Test::Unit::TestCase
21
  fixtures :projects
22
  
23
  # No '..' in the repository path
24
  REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository'
25
  
26
  def setup
27
    @project = Project.find(1)
28
    assert @repository = Repository::Git.create(:project => @project, :url => REPOSITORY_PATH)
29
  end
30
  
31
  if File.directory?(REPOSITORY_PATH)  
32
    def test_fetch_changesets_from_scratch
33
      @repository.fetch_changesets
34
      @repository.reload
35
      
36
      assert_equal 6, @repository.changesets.count
37
      assert_equal 11, @repository.changes.count
38
      assert_equal "Initial import.\nThe repository contains 3 files.", @repository.changesets.find_by_revision(1).comments
39
    end
40
    
41
    def test_fetch_changesets_incremental
42
      @repository.fetch_changesets
43
      # Remove changesets with revision > 3
44
      @repository.changesets.find(:all, :conditions => 'revision > 3').each(&:destroy)
45
      @repository.reload
46
      assert_equal 3, @repository.changesets.count
47
      
48
      @repository.fetch_changesets
49
      assert_equal 6, @repository.changesets.count
50
    end
51
  else
52
    puts "Git test repository NOT FOUND. Skipping unit tests !!!"
53
    def test_fake; assert true end
54
  end
55
end
(7-7/9)