To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / app / models / repository / .svn / text-base / git.rb.svn-base @ 441:cbce1fd3b1b7

History | View | Annotate | Download (5.09 KB)

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