##// END OF EJS Templates
scm: git: insert revisions to database with reverse commit order (#7821, #5357)....
Toshi MARUYAMA -
r4953:6dc57e752dc4
parent child
Show More
@@ -1,130 +1,130
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 ATTRIBUTE_KEY_NAMES = {
25 25 "url" => "Path to repository",
26 26 }
27 27 def self.human_attribute_name(attribute_key_name)
28 28 ATTRIBUTE_KEY_NAMES[attribute_key_name] || super
29 29 end
30 30
31 31 def self.scm_adapter_class
32 32 Redmine::Scm::Adapters::GitAdapter
33 33 end
34 34
35 35 def self.scm_name
36 36 'Git'
37 37 end
38 38
39 39 def repo_log_encoding
40 40 'UTF-8'
41 41 end
42 42
43 43 # Returns the identifier for the given git changeset
44 44 def self.changeset_identifier(changeset)
45 45 changeset.scmid
46 46 end
47 47
48 48 # Returns the readable identifier for the given git changeset
49 49 def self.format_changeset_identifier(changeset)
50 50 changeset.revision[0, 8]
51 51 end
52 52
53 53 def branches
54 54 scm.branches
55 55 end
56 56
57 57 def tags
58 58 scm.tags
59 59 end
60 60
61 61 def find_changeset_by_name(name)
62 62 return nil if name.nil? || name.empty?
63 63 e = changesets.find(:first, :conditions => ['revision = ?', name.to_s])
64 64 return e if e
65 65 changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
66 66 end
67 67
68 68 # With SCM's that have a sequential commit numbering, redmine is able to be
69 69 # clever and only fetch changesets going forward from the most recent one
70 70 # it knows about. However, with git, you never know if people have merged
71 71 # commits into the middle of the repository history, so we should parse
72 72 # the entire log. Since it's way too slow for large repositories, we only
73 73 # parse 1 week before the last known commit.
74 74 # The repository can still be fully reloaded by calling #clear_changesets
75 75 # before fetching changesets (eg. for offline resync)
76 76 def fetch_changesets
77 77 c = changesets.find(:first, :order => 'committed_on DESC')
78 78 since = (c ? c.committed_on - 7.days : nil)
79 79
80 revisions = scm.revisions('', nil, nil, :all => true, :since => since)
80 revisions = scm.revisions('', nil, nil, {:all => true, :since => since, :reverse => true})
81 81 return if revisions.nil? || revisions.empty?
82 82
83 83 recent_changesets = changesets.find(:all, :conditions => ['committed_on >= ?', since])
84 84
85 85 # Clean out revisions that are no longer in git
86 86 recent_changesets.each {|c| c.destroy unless revisions.detect {|r| r.scmid.to_s == c.scmid.to_s }}
87 87
88 88 # Subtract revisions that redmine already knows about
89 89 recent_revisions = recent_changesets.map{|c| c.scmid}
90 90 revisions.reject!{|r| recent_revisions.include?(r.scmid)}
91 91
92 92 # Save the remaining ones to the database
93 93 unless revisions.nil?
94 94 revisions.each do |rev|
95 95 transaction do
96 96 changeset = Changeset.new(
97 97 :repository => self,
98 98 :revision => rev.identifier,
99 99 :scmid => rev.scmid,
100 100 :committer => rev.author,
101 101 :committed_on => rev.time,
102 102 :comments => rev.message)
103 103
104 104 if changeset.save
105 105 rev.paths.each do |file|
106 106 Change.create(
107 107 :changeset => changeset,
108 108 :action => file[:action],
109 109 :path => file[:path])
110 110 end
111 111 end
112 112 end
113 113 end
114 114 end
115 115 end
116 116
117 117 def latest_changesets(path,rev,limit=10)
118 118 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
119 119 return [] if revisions.nil? || revisions.empty?
120 120
121 121 changesets.find(
122 122 :all,
123 123 :conditions => [
124 124 "scmid IN (?)",
125 125 revisions.map!{|c| c.scmid}
126 126 ],
127 127 :order => 'committed_on DESC'
128 128 )
129 129 end
130 130 end
General Comments 0
You need to be logged in to leave comments. Login now