##// END OF EJS Templates
scm: git: code clean up model....
Toshi MARUYAMA -
r5630:cddc5f70a32b
parent child
Show More
@@ -1,169 +1,170
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
1 # Redmine - project management software
2 # Copyright (C) 2006-2011 Jean-Philippe Lang
3 3 # Copyright (C) 2007 Patrick Aljord patcito@ŋmail.com
4 #
4 5 # This program is free software; you can redistribute it and/or
5 6 # modify it under the terms of the GNU General Public License
6 7 # as published by the Free Software Foundation; either version 2
7 8 # of the License, or (at your option) any later version.
8 9 #
9 10 # This program is distributed in the hope that it will be useful,
10 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 13 # GNU General Public License for more details.
13 14 #
14 15 # You should have received a copy of the GNU General Public License
15 16 # along with this program; if not, write to the Free Software
16 17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 18
18 19 require 'redmine/scm/adapters/git_adapter'
19 20
20 21 class Repository::Git < Repository
21 22 attr_protected :root_url
22 23 validates_presence_of :url
23 24
24 25 def self.human_attribute_name(attribute_key_name)
25 26 attr_name = attribute_key_name
26 27 if attr_name == "url"
27 28 attr_name = "path_to_repository"
28 29 end
29 30 super(attr_name)
30 31 end
31 32
32 33 def self.scm_adapter_class
33 34 Redmine::Scm::Adapters::GitAdapter
34 35 end
35 36
36 37 def self.scm_name
37 38 'Git'
38 39 end
39 40
40 41 def extra_report_last_commit
41 42 true
42 43 end
43 44
44 45 def supports_directory_revisions?
45 46 true
46 47 end
47 48
48 49 def repo_log_encoding
49 50 'UTF-8'
50 51 end
51 52
52 53 # Returns the identifier for the given git changeset
53 54 def self.changeset_identifier(changeset)
54 55 changeset.scmid
55 56 end
56 57
57 58 # Returns the readable identifier for the given git changeset
58 59 def self.format_changeset_identifier(changeset)
59 60 changeset.revision[0, 8]
60 61 end
61 62
62 63 def branches
63 64 scm.branches
64 65 end
65 66
66 67 def tags
67 68 scm.tags
68 69 end
69 70
70 71 def find_changeset_by_name(name)
71 72 return nil if name.nil? || name.empty?
72 73 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
73 74 return e if e
74 75 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
75 76 end
76 77
77 78 def entries(path=nil, identifier=nil)
78 79 scm.entries(path,
79 80 identifier,
80 81 options = {:report_last_commit => extra_report_last_commit})
81 82 end
82 83
83 84 # In Git and Mercurial, revisions are not in date order.
84 85 # Mercurial fixed issues.
85 86 # * Redmine Takes Too Long On Large Mercurial Repository
86 87 # http://www.redmine.org/issues/3449
87 88 # * Sorting for changesets might go wrong on Mercurial repos
88 89 # http://www.redmine.org/issues/3567
89 90 # Database revision column is text, so Redmine can not sort by revision.
90 91 # Mercurial has revision number, and revision number guarantees revision order.
91 92 # Mercurial adapter uses "hg log -r 0:tip --limit 10"
92 93 # to get limited revisions from old to new.
93 94 # And Mercurial model stored revisions ordered by database id in database.
94 95 # So, Mercurial can use correct order revisions.
95 96 #
96 97 # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
97 98 #
98 99 # With SCM's that have a sequential commit numbering, redmine is able to be
99 100 # clever and only fetch changesets going forward from the most recent one
100 101 # it knows about.
101 102 # However, with git, you never know if people have merged
102 103 # commits into the middle of the repository history, so we should parse
103 104 # the entire log.
104 105 #
105 106 # Since it's way too slow for large repositories,
106 107 # we only parse 1 week before the last known commit.
107 108 #
108 109 # The repository can still be fully reloaded by calling #clear_changesets
109 110 # before fetching changesets (eg. for offline resync)
110 111 def fetch_changesets
111 112 c = changesets.find(:first, :order => 'committed_on DESC')
112 113 since = (c ? c.committed_on - 7.days : nil)
113 114
114 115 revisions = scm.revisions('', nil, nil, {:all => true, :since => since, :reverse => true})
115 116 return if revisions.nil? || revisions.empty?
116 117
117 118 recent_changesets = changesets.find(:all, :conditions => ['committed_on >= ?', since])
118 119
119 120 # Clean out revisions that are no longer in git
120 121 recent_changesets.each {|c| c.destroy unless revisions.detect {|r| r.scmid.to_s == c.scmid.to_s }}
121 122
122 123 # Subtract revisions that redmine already knows about
123 124 recent_revisions = recent_changesets.map{|c| c.scmid}
124 125 revisions.reject!{|r| recent_revisions.include?(r.scmid)}
125 126
126 127 # Save the remaining ones to the database
127 128 unless revisions.nil?
128 129 revisions.each do |rev|
129 130 transaction do
130 131 save_revision(rev)
131 132 end
132 133 end
133 134 end
134 135 end
135 136
136 137 def save_revision(rev)
137 138 changeset = Changeset.new(
138 139 :repository => self,
139 140 :revision => rev.identifier,
140 141 :scmid => rev.scmid,
141 142 :committer => rev.author,
142 143 :committed_on => rev.time,
143 144 :comments => rev.message
144 145 )
145 146 if changeset.save
146 147 rev.paths.each do |file|
147 148 Change.create(
148 149 :changeset => changeset,
149 150 :action => file[:action],
150 151 :path => file[:path])
151 152 end
152 153 end
153 154 end
154 155 private :save_revision
155 156
156 157 def latest_changesets(path,rev,limit=10)
157 158 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
158 159 return [] if revisions.nil? || revisions.empty?
159 160
160 161 changesets.find(
161 162 :all,
162 163 :conditions => [
163 164 "scmid IN (?)",
164 165 revisions.map!{|c| c.scmid}
165 166 ],
166 167 :order => 'committed_on DESC'
167 168 )
168 169 end
169 170 end
General Comments 0
You need to be logged in to leave comments. Login now