##// END OF EJS Templates
Merged r5644 from trunk....
Toshi MARUYAMA -
r5526:4fc2e757f6d0
parent child
Show More
@@ -1,95 +1,110
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 # Copyright (C) 2007 Patrick Aljord patcito@ŋmail.com
3 # Copyright (C) 2007 Patrick Aljord patcito@ŋmail.com
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
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
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.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require 'redmine/scm/adapters/git_adapter'
18 require 'redmine/scm/adapters/git_adapter'
19
19
20 class Repository::Git < Repository
20 class Repository::Git < Repository
21 attr_protected :root_url
21 attr_protected :root_url
22 validates_presence_of :url
22 validates_presence_of :url
23
23
24 def scm_adapter
24 def scm_adapter
25 Redmine::Scm::Adapters::GitAdapter
25 Redmine::Scm::Adapters::GitAdapter
26 end
26 end
27
27
28 def self.scm_name
28 def self.scm_name
29 'Git'
29 'Git'
30 end
30 end
31
31
32 # Returns the identifier for the given git changeset
32 # Returns the identifier for the given git changeset
33 def self.changeset_identifier(changeset)
33 def self.changeset_identifier(changeset)
34 changeset.scmid
34 changeset.scmid
35 end
35 end
36
36
37 # Returns the readable identifier for the given git changeset
37 # Returns the readable identifier for the given git changeset
38 def self.format_changeset_identifier(changeset)
38 def self.format_changeset_identifier(changeset)
39 changeset.revision[0, 8]
39 changeset.revision[0, 8]
40 end
40 end
41
41
42 def branches
42 def branches
43 scm.branches
43 scm.branches
44 end
44 end
45
45
46 def tags
46 def tags
47 scm.tags
47 scm.tags
48 end
48 end
49
49
50 # In Git and Mercurial, revisions are not in date order.
51 # Mercurial fixed issues.
52 # * Redmine Takes Too Long On Large Mercurial Repository
53 # http://www.redmine.org/issues/3449
54 # * Sorting for changesets might go wrong on Mercurial repos
55 # http://www.redmine.org/issues/3567
56 # Database revision column is text, so Redmine can not sort by revision.
57 # Mercurial has revision number, and revision number guarantees revision order.
58 # Mercurial adapter uses "hg log -r 0:tip --limit 10"
59 # to get limited revisions from old to new.
60 # And Mercurial model stored revisions ordered by database id in database.
61 # So, Mercurial can use correct order revisions.
62 #
63 # But, Git 1.7.3.4 does not support --reverse with -n or --skip.
64 #
50 # With SCM's that have a sequential commit numbering, redmine is able to be
65 # With SCM's that have a sequential commit numbering, redmine is able to be
51 # clever and only fetch changesets going forward from the most recent one
66 # clever and only fetch changesets going forward from the most recent one
52 # it knows about.
67 # it knows about.
53 # However, with git, you never know if people have merged
68 # However, with git, you never know if people have merged
54 # commits into the middle of the repository history, so we should parse
69 # commits into the middle of the repository history, so we should parse
55 # the entire log.
70 # the entire log.
56 #
71 #
57 # Since it's way too slow for large repositories,
72 # Since it's way too slow for large repositories,
58 # we only parse 1 week before the last known commit.
73 # we only parse 1 week before the last known commit.
59 #
74 #
60 # The repository can still be fully reloaded by calling #clear_changesets
75 # The repository can still be fully reloaded by calling #clear_changesets
61 # before fetching changesets (eg. for offline resync)
76 # before fetching changesets (eg. for offline resync)
62 def fetch_changesets
77 def fetch_changesets
63 c = changesets.find(:first, :order => 'committed_on DESC')
78 c = changesets.find(:first, :order => 'committed_on DESC')
64 since = (c ? c.committed_on - 7.days : nil)
79 since = (c ? c.committed_on - 7.days : nil)
65
80
66 revisions = scm.revisions('', nil, nil, :all => true, :since => since)
81 revisions = scm.revisions('', nil, nil, :all => true, :since => since)
67 return if revisions.nil? || revisions.empty?
82 return if revisions.nil? || revisions.empty?
68
83
69 recent_changesets = changesets.find(:all, :conditions => ['committed_on >= ?', since])
84 recent_changesets = changesets.find(:all, :conditions => ['committed_on >= ?', since])
70
85
71 # Clean out revisions that are no longer in git
86 # Clean out revisions that are no longer in git
72 recent_changesets.each {|c| c.destroy unless revisions.detect {|r| r.scmid.to_s == c.scmid.to_s }}
87 recent_changesets.each {|c| c.destroy unless revisions.detect {|r| r.scmid.to_s == c.scmid.to_s }}
73
88
74 # Subtract revisions that redmine already knows about
89 # Subtract revisions that redmine already knows about
75 recent_revisions = recent_changesets.map{|c| c.scmid}
90 recent_revisions = recent_changesets.map{|c| c.scmid}
76 revisions.reject!{|r| recent_revisions.include?(r.scmid)}
91 revisions.reject!{|r| recent_revisions.include?(r.scmid)}
77
92
78 # Save the remaining ones to the database
93 # Save the remaining ones to the database
79 revisions.each{|r| r.save(self)} unless revisions.nil?
94 revisions.each{|r| r.save(self)} unless revisions.nil?
80 end
95 end
81
96
82 def latest_changesets(path,rev,limit=10)
97 def latest_changesets(path,rev,limit=10)
83 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
98 revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false)
84 return [] if revisions.nil? || revisions.empty?
99 return [] if revisions.nil? || revisions.empty?
85
100
86 changesets.find(
101 changesets.find(
87 :all,
102 :all,
88 :conditions => [
103 :conditions => [
89 "scmid IN (?)",
104 "scmid IN (?)",
90 revisions.map!{|c| c.scmid}
105 revisions.map!{|c| c.scmid}
91 ],
106 ],
92 :order => 'committed_on DESC'
107 :order => 'committed_on DESC'
93 )
108 )
94 end
109 end
95 end
110 end
General Comments 0
You need to be logged in to leave comments. Login now