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