Project

General

Profile

Patch #234 » git_edge_latest_patch.diff

Patrick Aljord, 2008-02-03 11:01

View differences:

app/helpers/repositories_helper.rb (working copy)
73 73
      content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?)))
74 74
  end
75 75

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

  
76 80
  def cvs_field_tags(form, repository)
77 81
      content_tag('p', form.text_field(:root_url, :label => 'CVSROOT', :size => 60, :required => true, :disabled => !repository.new_record?)) +
78 82
      content_tag('p', form.text_field(:url, :label => 'Module', :size => 30, :required => true, :disabled => !repository.new_record?))
app/models/repository/subversion.rb (working copy)
42 42
      db_revision = latest_changeset ? latest_changeset.revision : 0
43 43
      # latest revision in the repository
44 44
      scm_revision = scm_info.lastrev.identifier.to_i
45
      if db_revision < scm_revision
45
      if db_revision.to_i < scm_revision
46 46
        logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug?
47 47
        identifier_from = db_revision + 1
48 48
        while (identifier_from <= scm_revision)
app/models/repository/git.rb (revision 0)
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
    if scm_info
61
      # latest revision found in database
62
      db_revision = latest_changeset ? latest_changeset.revision : nil
63
      # latest revision in the repository
64
      scm_revision = scm_info.lastrev.identifier
65

  
66
      unless changesets.find_by_revision(scm_revision)
67

  
68
        revisions = scm.revisions('', db_revision, nil)
69
        transaction do
70
          revisions.reverse_each do |revision|
71
            changeset = Changeset.create(:repository => self,
72
                                         :revision => revision.identifier,
73
                                         :scmid => revision.scmid,
74
                                         :committer => revision.author, 
75
                                         :committed_on => revision.time,
76
                                         :comments => revision.message)
77
            
78
            revision.paths.each do |change|
79
              Change.create(:changeset => changeset,
80
                            :action => change[:action],
81
                            :path => change[:path],
82
                            :from_path => change[:from_path],
83
                            :from_revision => change[:from_revision])
84
            end
85
          end
86
        end
87
      end
88
    end
89
  end
90
end
app/models/changeset.rb (working copy)
32 32
                     :date_column => 'committed_on'
33 33
  
34 34
  validates_presence_of :repository_id, :revision, :committed_on, :commit_date
35
  validates_numericality_of :revision, :only_integer => true
35
#   validates_numericality_of :revision, :only_integer => true
36 36
  validates_uniqueness_of :revision, :scope => :repository_id
37 37
  validates_uniqueness_of :scmid, :scope => :repository_id, :allow_nil => true
38 38
  
app/controllers/repositories_controller.rb (working copy)
105 105
  end
106 106
  
107 107
  def diff
108
    @rev_to = params[:rev_to] ? params[:rev_to].to_i : (@rev - 1)
108
    get_rev_to
109 109
    @diff_type = ('sbs' == params[:type]) ? 'sbs' : 'inline'
110 110
    
111 111
    @cache_key = "repositories/diff/#{@repository.id}/" + Digest::MD5.hexdigest("#{@path}-#{@rev}-#{@rev_to}-#{@diff_type}")    
......
147 147
    render_404 and return false unless @repository
148 148
    @path = params[:path].join('/') unless params[:path].nil?
149 149
    @path ||= ''
150
    @rev = params[:rev].to_i if params[:rev]
150
    @rev = params[:rev] if params[:rev]
151 151
  rescue ActiveRecord::RecordNotFound
152 152
    render_404
153 153
  end
154 154

  
155
  def get_rev_to
156
    @rev_to = params[:rev_to].to_i ? params[:rev_to].to_i : (@rev.to_i - 1) if @rev !~ /\D/
157
    @rev_to = params[:rev_to] ? params[:rev_to] : (nil) if !(@rev !~ /\D/)
158
  end
159

  
155 160
  def show_error
156 161
    flash.now[:error] = l(:notice_scm_error)
157 162
    render :nothing => true, :layout => true
db/migrate/078_make_revisions_string.rb (revision 0)
1
class MakeRevisionsString < ActiveRecord::Migration
2
  def self.up
3
	change_column :changes, :from_revision, :string
4
        change_column :changesets, :revision, :string
5
  end
6

  
7
  def self.down
8
        change_column :changes, :from_revision, :integer
9
        change_column :changesets, :revision, :integer
10
   end
11
end
lib/redmine/scm/adapters/abstract_adapter.rb (working copy)
172 172
            end
173 173
          }.last
174 174
        end 
175
      end
175
   end
176
   
177

  
178
def get_rev(rev,path)
179
Revision.new
180
end
176 181
      
177 182
      class Revision
178 183
        attr_accessor :identifier, :scmid, :name, :author, :time, :message, :paths, :revision, :branch
lib/redmine/scm/adapters/git_adapter.rb (revision 0)
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

  
29
        #get the revision of a particuliar file
30
	def get_rev (rev,path)
31
cmd="cd #{target('')} && git show #{rev} #{path}" if rev!='latest'
32
cmd="cd #{target('')} && git log -1 master -- #{path}" if 
33
rev=='latest' or rev.nil?
34
puts cmd
35
rev=[]
36
 i=0
37
    shellout(cmd) do |io|
38
          commit_files=[]
39
          params={:commit=>'',:author=>'',:date=>'',:message=>'',:file=>{:path=>'',:action=>''}}
40
         
41
          message=''
42
	io.each_line do |line|
43

  
44
	        i=0 if line=~/^commit/
45
		params[:commit]=line.chomp.gsub("commit ",'') if i==0
46
		
47
		params[:author]=line.chomp.gsub("Author: ",'') if i==1
48
		params[:date]=line.chomp.gsub("Date: ",'') if i==2
49
		params[:message]+= line.chomp.to_s if i==4 and line[0..0]!=':'
50
		params[:file][:action], params[:file][:path]= line.chomp.slice(/[ACDMRTUXB].*/).split(' ', 2) if i>=4 and line[0..0]==':'
51
		commit_files << {:action=>params[:file][:action],:path=>params[:file][:path]}  if i>=4 and line[0..0]==':'
52
		i+=1
53
		end	
54
		
55
		rev = Revision.new({:identifier => params[:commit],
56
                                       :scmid => params[:commit],
57
                                       :author => params[:author],
58
                                       :time => Time.parse(params[:date]),
59
                                       :message => params[:message],
60
                                       :paths => commit_files
61
            				})
62
	end
63

  
64
	get_rev('latest',path) if i==0
65

  
66
          return nil if $? && $?.exitstatus != 0
67
          return rev
68
#         rescue Errno::ENOENT => e
69
#           raise CommandFailed
70
end
71

  
72

  
73
        def info
74
#           cmd = "#{GIT_BIN} -R #{target('')} root"
75
#           root_url = nil
76
#           shellout(cmd) do |io|
77
             root_url = target('')
78
#           end
79
          return nil if $? && $?.exitstatus != 0
80
          info = Info.new({:root_url => target(''),
81
                           :lastrev => revisions(root_url,nil,nil,nil).first
82
                         })
83
          info
84
        rescue Errno::ENOENT => e
85
          return nil
86
        end
87
        
88
        def entries(path=nil, identifier=nil)
89
          path ||= ''
90
          entries = Entries.new
91
          cmd = "cd #{target('')} && #{GIT_BIN} show HEAD:#{path}" if identifier.nil?
92
          cmd = "cd #{target('')} && #{GIT_BIN} show #{identifier}:#{path}" if identifier
93
	shellout(cmd)  do |io|
94
	 io.each_line do |line|
95
              e = line.chomp.split('\\')
96
	unless e.to_s.strip=='' or line[0..3]=='tree'
97
	name=e.first.split('/')[0]
98
              entries << Entry.new({:name => name,
99
                                    :path => (path.empty? ? name : "#{path}/#{name}"),
100
                                    :kind => ((e.first.include? '/') ? 'dir' : 'file'),
101
                                    :lastrev => get_rev(identifier,(path.empty? ? name : "#{path}/#{name}"))
102
                                    }) unless entries.detect{|entry| entry.name == name}
103
 	puts e[0..3]   
104
         end
105
	end
106
	end
107
          return nil if $? && $?.exitstatus != 0
108
          entries.sort_by_name
109
#         rescue Errno::ENOENT => e
110
#           raise CommandFailed
111
        end
112
  
113
        def entry(path=nil, identifier=nil)
114
          path ||= ''
115
          search_path = path.split('/')[0..-2].join('/')
116
          entry_name = path.split('/').last
117
          e = entries(search_path, identifier)
118
          e ? e.detect{|entry| entry.name == entry_name} : nil
119
        end
120
          
121
		def revisions(path, identifier_from, identifier_to, options={})
122
		revisions = Revisions.new
123
		cmd = "cd #{target('')} && #{GIT_BIN} whatchanged "
124
		cmd << " #{identifier_from}.. " if identifier_from
125
		cmd << " #{identifier_to} " if identifier_to
126
                #cmd << " HEAD " if !identifier_to
127
		puts cmd
128
		shellout(cmd) do |io|
129
		files=[]
130
		params={:commit=>'',:author=>'',:date=>'',:message=>'',:file=>{:path=>'',:action=>''}}
131
		i=0
132
		message=''
133
		io.each_line do |line|
134
	
135
			if line=~/^commit/ and i>0
136
			revisions << Revision.new({:identifier => params[:commit],
137
					:scmid => params[:commit],
138
					:author => params[:author],
139
					:time => Time.parse(params[:date]),
140
					:message => params[:message],
141
					:paths => files
142
						})
143
	
144
			files=[]	
145
			i=0
146
			params={:commit=>'',:author=>'',:date=>'',:message=>'',:file=>{:path=>'',:action=>''}}
147
			end
148
			params[:commit]=line.chomp.gsub("commit ",'') if i==0
149
			params[:author]=line.chomp.gsub("Author: ",'') if i==1
150
			params[:date]=line.chomp.gsub("Date: ",'') if i==2
151
			params[:message]+= line.chomp.to_s if i>=4 and line[0..0]!=':'
152
			params[:file][:action], params[:file][:path]= line.chomp.slice(/[ACDMRTUXB].*/).split(' ', 2) if i>=4 and line[0..0]==':'
153
			files << {:action=>params[:file][:action],:path=>params[:file][:path]}  if i>=4 and line[0..0]==':'
154
			i+=1
155
			end	
156
		end
157

  
158
          return nil if $? && $?.exitstatus != 0
159
          revisions
160
        rescue Errno::ENOENT => e
161
          raise CommandFailed
162
     puts 'revs: #{revisions}'
163
	   end
164
        
165
        def diff(path, identifier_from, identifier_to=nil, type="inline")
166
          path ||= ''
167
          if identifier_to
168
            identifier_to = identifier_to 
169
          else
170
            identifier_to = nil
171
          end
172
          cmd = "cd #{target('')} && #{GIT_BIN}  diff   #{identifier_from}^!" if identifier_to.nil?
173
          cmd = "cd #{target('')} && #{GIT_BIN}  diff #{identifier_to}  #{identifier_from}" if !identifier_to.nil?
174
          cmd << " #{path}" unless path.empty?
175
          diff = []
176
          shellout(cmd) do |io|
177
            io.each_line do |line|
178
              diff << line
179
            end
180
          end
181
          return nil if $? && $?.exitstatus != 0
182
          DiffTableList.new diff, type
183
    
184
        rescue Errno::ENOENT => e
185
          raise CommandFailed
186
        end
187
        
188
        def cat(path, identifier=nil)
189
          cmd = "cd #{target('')} && #{GIT_BIN} show #{identifier}:#{path}"
190
          cat = nil
191
          shellout(cmd) do |io|
192
            io.binmode
193
            cat = io.read
194
          end
195
          return nil if $? && $?.exitstatus != 0
196
          cat
197
        rescue Errno::ENOENT => e
198
          raise CommandFailed
199
        end
200
      end
201
    end
202
  end
203

  
204
end
205

  
lib/redmine.rb (working copy)
10 10
  # RMagick is not available
11 11
end
12 12

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

  
15 15
# Permissions
16 16
Redmine::AccessControl.map do |map|
(2-2/4)