initial commit
[gitredmine.git] / git_patch.diff
blob12a38e89f1bc8e3c6683e2bb9f08247ca6930ae6
1 Index: app/helpers/repositories_helper.rb
2 ===================================================================
3 --- app/helpers/repositories_helper.rb (revision 594)
4 +++ app/helpers/repositories_helper.rb (working copy)
5 @@ -51,6 +51,10 @@
6 content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
7 end
9 + def git_field_tags(form, repository)
10 + content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
11 + end
13 def cvs_field_tags(form, repository)
14 content_tag('p', form.text_field(:root_url, :label => 'CVSROOT', :size => 60, :required => true, :disabled => !repository.new_record?)) +
15 content_tag('p', form.text_field(:url, :label => 'Module', :size => 30, :required => true, :disabled => !repository.new_record?))
16 Index: app/models/repository/subversion.rb
17 ===================================================================
18 --- app/models/repository/subversion.rb (revision 594)
19 +++ app/models/repository/subversion.rb (working copy)
20 @@ -37,7 +37,7 @@
21 db_revision = latest_changeset ? latest_changeset.revision : 0
22 # latest revision in the repository
23 scm_revision = scm_info.lastrev.identifier.to_i
24 - if db_revision < scm_revision
25 + if db_revision.to_i < scm_revision
26 logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
27 identifier_from = db_revision + 1
28 while (identifier_from <= scm_revision)
29 Index: app/models/repository/git.rb
30 ===================================================================
31 --- app/models/repository/git.rb (revision 0)
32 +++ app/models/repository/git.rb (revision 0)
33 @@ -0,0 +1,83 @@
34 +# redMine - project management software
35 +# Copyright (C) 2006-2007 Jean-Philippe Lang
37 +# This program is free software; you can redistribute it and/or
38 +# modify it under the terms of the GNU General Public License
39 +# as published by the Free Software Foundation; either version 2
40 +# of the License, or (at your option) any later version.
41 +#
42 +# This program is distributed in the hope that it will be useful,
43 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
44 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45 +# GNU General Public License for more details.
46 +#
47 +# You should have received a copy of the GNU General Public License
48 +# along with this program; if not, write to the Free Software
49 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
51 +require 'redmine/scm/adapters/git_adapter'
53 +class Repository::Git < Repository
54 + attr_protected :root_url
55 + validates_presence_of :url
57 + def scm_adapter
58 + Redmine::Scm::Adapters::GitAdapter
59 + end
61 + def self.scm_name
62 + 'Git'
63 + end
65 + def entries(path=nil, identifier=nil)
66 + entries=scm.entries(path, identifier)
67 + if entries
68 + entries.each do |entry|
69 + next unless entry.is_file?
70 + # Search the DB for the entry's last change
71 + change = changes.find(:first, :conditions => ["path = ?", scm.with_leading_slash(entry.path)], :order => "#{Changeset.table_name}.committed_on DESC")
72 + if change
73 + entry.lastrev.identifier = change.changeset.revision
74 + entry.lastrev.name = change.changeset.revision
75 + entry.lastrev.author = change.changeset.committer
76 + entry.lastrev.revision = change.revision
77 + end
78 + end
79 + end
80 + entries
81 + end
83 + def fetch_changesets
84 + scm_info = scm.info
86 + if scm_info
87 + # latest revision found in database
88 + db_revision = latest_changeset ? latest_changeset.revision : nil
89 + # latest revision in the repository
90 + scm_revision = scm_info.lastrev.identifier
92 + unless changesets.find_by_revision(scm_revision)
94 + revisions = scm.revisions('', db_revision, nil)
95 + transaction do
96 + revisions.reverse_each do |revision|
97 + changeset = Changeset.create(:repository => self,
98 + :revision => revision.identifier,
99 + :scmid => revision.scmid,
100 + :committer => revision.author,
101 + :committed_on => revision.time,
102 + :comments => revision.message)
104 + revision.paths.each do |change|
105 + Change.create(:changeset => changeset,
106 + :action => change[:action],
107 + :path => change[:path],
108 + :from_path => change[:from_path],
109 + :from_revision => change[:from_revision])
110 + end
111 + end
112 + end
113 + end
114 + end
115 + end
116 +end
117 Index: app/models/changeset.rb
118 ===================================================================
119 --- app/models/changeset.rb (revision 594)
120 +++ app/models/changeset.rb (working copy)
121 @@ -21,7 +21,7 @@
122 has_and_belongs_to_many :issues
124 validates_presence_of :repository_id, :revision, :committed_on, :commit_date
125 - validates_numericality_of :revision, :only_integer => true
126 +# validates_numericality_of :revision, :only_integer => true
127 validates_uniqueness_of :revision, :scope => :repository_id
128 validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
130 Index: app/controllers/repositories_controller.rb
131 ===================================================================
132 --- app/controllers/repositories_controller.rb (revision 594)
133 +++ app/controllers/repositories_controller.rb (working copy)
134 @@ -27,7 +27,7 @@
136 def show
137 # check if new revisions have been committed in the repository
138 - @repository.fetch_changesets if Setting.autofetch_changesets?
139 + @repository.fetch_changesets #if Setting.autofetch_changesets?
140 # get entries for the browse frame
141 @entries = @repository.entries('')
142 # latest changesets
143 @@ -44,8 +44,13 @@
144 @entry = @repository.scm.entry(@path, @rev)
145 show_error and return unless @entry
146 @changes = Change.find(:all, :include => :changeset,
147 - :conditions => ["repository_id = ? AND path = ?", @repository.id, @path.with_leading_slash],
148 - :order => "committed_on DESC")
149 + :conditions => ["repository_id = ? AND path = ?", @repository.id, @path.with_leading_slash],
150 + :order => "committed_on DESC") if @repository.class.to_s!='Repository::Git'
152 + @changes = Change.find(:all, :include => :changeset,
153 + :conditions => ["repository_id = ? AND path = ?", @repository.id, @path],
154 + :order => "committed_on DESC") if @repository.class.to_s=='Repository::Git'
155 +# @path.with_leading_slash
158 def revisions
159 @@ -81,7 +86,8 @@
162 def diff
163 - @rev_to = params[:rev_to] ? params[:rev_to].to_i : (@rev - 1)
164 + @rev_to = params[:rev_to].to_i ? params[:rev_to].to_i : (@rev.to_i - 1) if @repository.class.to_s!='Repository::Git'
165 +@rev_to = params[:rev_to] ? params[:rev_to] : (nil) if @repository.class.to_s=='Repository::Git'
166 @diff_type = ('sbs' == params[:type]) ? 'sbs' : 'inline'
168 @cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")
169 @@ -122,7 +128,7 @@
170 render_404 and return false unless @repository
171 @path = params[:path].squeeze('/') if params[:path]
172 @path ||= ''
173 - @rev = params[:rev].to_i if params[:rev]
174 + @rev = params[:rev] if params[:rev]
175 rescue ActiveRecord::RecordNotFound
176 render_404
178 Index: db/migrate/059_make_revisions_string.rb
179 ===================================================================
180 --- db/migrate/059_make_revisions_string.rb (revision 0)
181 +++ db/migrate/059_make_revisions_string.rb (revision 0)
182 @@ -0,0 +1,11 @@
183 +class MakeRevisionsString < ActiveRecord::Migration
184 + def self.up
185 + change_column :changes, :from_revision, :string
186 + change_column :changesets, :revision, :string
187 + end
189 + def self.down
190 + change_column :changes, :from_revision, :integer
191 + change_column :changesets, :revision, :integer
192 + end
193 +end
194 Index: lib/redmine/scm/adapters/abstract_adapter.rb
195 ===================================================================
196 --- lib/redmine/scm/adapters/abstract_adapter.rb (revision 594)
197 +++ lib/redmine/scm/adapters/abstract_adapter.rb (working copy)
198 @@ -164,7 +164,12 @@
200 }.last
201 end
202 - end
203 + end
206 +def get_rev(rev,path)
207 +Revision.new
208 +end
210 class Revision
211 attr_accessor :identifier, :scmid, :name, :author, :time, :message, :paths, :revision, :branch
212 Index: lib/redmine/scm/adapters/git_adapter.rb
213 ===================================================================
214 --- lib/redmine/scm/adapters/git_adapter.rb (revision 0)
215 +++ lib/redmine/scm/adapters/git_adapter.rb (revision 0)
216 @@ -0,0 +1,200 @@
217 +# redMine - project management software
218 +# Copyright (C) 2006-2007 Jean-Philippe Lang
220 +# This program is free software; you can redistribute it and/or
221 +# modify it under the terms of the GNU General Public License
222 +# as published by the Free Software Foundation; either version 2
223 +# of the License, or (at your option) any later version.
225 +# This program is distributed in the hope that it will be useful,
226 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
227 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
228 +# GNU General Public License for more details.
230 +# You should have received a copy of the GNU General Public License
231 +# along with this program; if not, write to the Free Software
232 +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
234 +require 'redmine/scm/adapters/abstract_adapter'
236 +module Redmine
237 + module Scm
238 + module Adapters
239 + class GitAdapter < AbstractAdapter
241 + # Git executable name
242 + GIT_BIN = "git"
245 + #get the revision of a particuliar file
246 + def get_rev (rev,path)
247 +cmd="cd #{target('')} && git show #{rev} #{path}" if rev!='latest'
248 +cmd="cd #{target('')} && git log -1 #{path}" if rev=='latest' or rev.nil?
249 +puts cmd
250 +rev=[]
251 + i=0
252 + shellout(cmd) do |io|
253 + commit_files=[]
254 + params={:commit=>'',:author=>'',:date=>'',:message=>'',:file=>{:path=>'',:action=>''}}
256 + message=''
257 + io.each_line do |line|
259 + i=0 if line=~/^commit/
260 + params[:commit]=line.chomp.gsub("commit ",'') if i==0
262 + params[:author]=line.chomp.gsub("Author: ",'') if i==1
263 + params[:date]=line.chomp.gsub("Date: ",'') if i==2
264 + params[:message]+= line.chomp.to_s if i==4 and line[0..0]!=':'
265 + params[:file][:action], params[:file][:path]= line.chomp.slice(/[ACDMRTUXB].*/).split(' ', 2) if i>=4 and line[0..0]==':'
266 + commit_files << {:action=>params[:file][:action],:path=>params[:file][:path]} if i>=4 and line[0..0]==':'
267 + i+=1
268 + end
270 + rev = Revision.new({:identifier => params[:commit],
271 + :scmid => params[:commit],
272 + :author => params[:author],
273 + :time => Time.parse(params[:date]),
274 + :message => params[:message],
275 + :paths => commit_files
276 + })
277 + end
279 + get_rev('latest',path) if i==0
281 + return nil if $? && $?.exitstatus != 0
282 + return rev
283 +# rescue Errno::ENOENT => e
284 +# raise CommandFailed
285 +end
288 + def info
289 +# cmd = "#{GIT_BIN} -R #{target('')} root"
290 +# root_url = nil
291 +# shellout(cmd) do |io|
292 + root_url = target('')
293 +# end
294 + return nil if $? && $?.exitstatus != 0
295 + info = Info.new({:root_url => target(''),
296 + :lastrev => revisions(root_url,nil,nil,nil).first
297 + })
298 + info
299 + rescue Errno::ENOENT => e
300 + return nil
301 + end
303 + def entries(path=nil, identifier=nil)
304 + path ||= ''
305 + entries = Entries.new
306 + cmd = "cd #{target('')} && #{GIT_BIN} show HEAD:#{path}" if identifier.nil?
307 + cmd = "cd #{target('')} && #{GIT_BIN} show #{identifier}:#{path}" if identifier
308 + shellout(cmd) do |io|
309 + io.each_line do |line|
310 + e = line.chomp.split('\\')
311 + unless e.to_s.strip=='' or line[0..3]=='tree'
312 + name=e.first.split('/')[0]
313 + entries << Entry.new({:name => name,
314 + :path => (path.empty? ? name : "#{path}/#{name}"),
315 + :kind => ((e.first.include? '/') ? 'dir' : 'file'),
316 + :lastrev => get_rev(identifier,(path.empty? ? name : "#{path}/#{name}"))
317 + }) unless entries.detect{|entry| entry.name == name}
318 + puts e[0..3]
319 + end
320 + end
321 + end
322 + return nil if $? && $?.exitstatus != 0
323 + entries.sort_by_name
324 +# rescue Errno::ENOENT => e
325 +# raise CommandFailed
326 + end
328 + def entry(path=nil, identifier=nil)
329 + path ||= ''
330 + search_path = path.split('/')[0..-2].join('/')
331 + entry_name = path.split('/').last
332 + e = entries(search_path, identifier)
333 + e ? e.detect{|entry| entry.name == entry_name} : nil
334 + end
336 + def revisions(path, identifier_from, identifier_to, options={})
337 + revisions = Revisions.new
338 + cmd = "cd #{target('')} && #{GIT_BIN} whatchanged"
339 + cmd << " #{identifier_from}.. " if identifier_from
340 + cmd << " #{identifier_to} " if identifier_to
341 + shellout(cmd) do |io|
342 + files=[]
343 + params={:commit=>'',:author=>'',:date=>'',:message=>'',:file=>{:path=>'',:action=>''}}
344 + i=0
345 + message=''
346 + io.each_line do |line|
348 + if line=~/^commit/ and i>0
349 + revisions << Revision.new({:identifier => params[:commit],
350 + :scmid => params[:commit],
351 + :author => params[:author],
352 + :time => Time.parse(params[:date]),
353 + :message => params[:message],
354 + :paths => files
355 + })
357 + files=[]
358 + i=0
359 + params={:commit=>'',:author=>'',:date=>'',:message=>'',:file=>{:path=>'',:action=>''}}
360 + end
361 + params[:commit]=line.chomp.gsub("commit ",'') if i==0
362 + params[:author]=line.chomp.gsub("Author: ",'') if i==1
363 + params[:date]=line.chomp.gsub("Date: ",'') if i==2
364 + params[:message]+= line.chomp.to_s if i>=4 and line[0..0]!=':'
365 + params[:file][:action], params[:file][:path]= line.chomp.slice(/[ACDMRTUXB].*/).split(' ', 2) if i>=4 and line[0..0]==':'
366 + files << {:action=>params[:file][:action],:path=>params[:file][:path]} if i>=4 and line[0..0]==':'
367 + i+=1
368 + end
369 + end
371 + return nil if $? && $?.exitstatus != 0
372 + revisions
373 + rescue Errno::ENOENT => e
374 + raise CommandFailed
375 + end
377 + def diff(path, identifier_from, identifier_to=nil, type="inline")
378 + path ||= ''
379 + if identifier_to
380 + identifier_to = identifier_to
381 + else
382 + identifier_to = nil
383 + end
384 + cmd = "cd #{target('')} && #{GIT_BIN} diff #{identifier_to} #{identifier_from}"
385 + cmd << " #{path}" unless path.empty?
386 + diff = []
387 + shellout(cmd) do |io|
388 + io.each_line do |line|
389 + diff << line
390 + end
391 + end
392 + return nil if $? && $?.exitstatus != 0
393 + DiffTableList.new diff, type
395 + rescue Errno::ENOENT => e
396 + raise CommandFailed
397 + end
399 + def cat(path, identifier=nil)
400 + cmd = "cd #{target('')} && #{GIT_BIN} show #{identifier}:#{path}"
401 + cat = nil
402 + shellout(cmd) do |io|
403 + io.binmode
404 + cat = io.read
405 + end
406 + return nil if $? && $?.exitstatus != 0
407 + cat
408 + rescue Errno::ENOENT => e
409 + raise CommandFailed
410 + end
411 + end
412 + end
413 + end
415 +end
417 Index: lib/redmine.rb
418 ===================================================================
419 --- lib/redmine.rb (revision 594)
420 +++ lib/redmine.rb (working copy)
421 @@ -2,4 +2,4 @@
422 require 'redmine/mime_type'
423 require 'redmine/acts_as_watchable/init'
425 -REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs )
426 +REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Git )