Revision 442:753f1380d6bc app/models/repository
| app/models/repository/.svn/entries | ||
|---|---|---|
| 1 | 1 |
10 |
| 2 | 2 |
|
| 3 | 3 |
dir |
| 4 |
4993
|
|
| 5 |
http://redmine.rubyforge.org/svn/trunk/app/models/repository
|
|
| 4 |
6000
|
|
| 5 |
http://redmine.rubyforge.org/svn/branches/1.2-stable/app/models/repository
|
|
| 6 | 6 |
http://redmine.rubyforge.org/svn |
| 7 | 7 |
|
| 8 | 8 |
|
| 9 | 9 |
|
| 10 |
2011-03-01T10:27:30.170724Z
|
|
| 11 |
4982
|
|
| 10 |
2011-05-19T22:58:38.288878Z
|
|
| 11 |
5858
|
|
| 12 | 12 |
tmaruyama |
| 13 | 13 |
|
| 14 | 14 |
|
| ... | ... | |
| 32 | 32 |
|
| 33 | 33 |
|
| 34 | 34 |
|
| 35 |
2011-03-03T11:40:18.000000Z
|
|
| 36 |
b9f366b3f38bd42149e09e6ed0ed8755
|
|
| 37 |
2011-02-28T12:09:32.515358Z
|
|
| 38 |
4962
|
|
| 35 |
2011-06-06T13:18:33.000000Z
|
|
| 36 |
2950b88e98eed34048c7f007a8f7fb21
|
|
| 37 |
2011-05-12T07:15:39.740135Z
|
|
| 38 |
5751
|
|
| 39 | 39 |
tmaruyama |
| 40 | 40 |
has-props |
| 41 | 41 |
|
| ... | ... | |
| 58 | 58 |
|
| 59 | 59 |
|
| 60 | 60 |
|
| 61 |
3358
|
|
| 61 |
3397
|
|
| 62 | 62 |
|
| 63 | 63 |
bazaar.rb |
| 64 | 64 |
file |
| ... | ... | |
| 66 | 66 |
|
| 67 | 67 |
|
| 68 | 68 |
|
| 69 |
2011-03-03T11:40:18.000000Z
|
|
| 70 |
d6a230859a110341c0d64865248db51c
|
|
| 71 |
2011-03-01T10:27:30.170724Z
|
|
| 72 |
4982
|
|
| 69 |
2011-06-06T13:18:33.000000Z
|
|
| 70 |
d4568bac22baf6121a7ea8883b59c58c
|
|
| 71 |
2011-05-18T07:11:41.584755Z
|
|
| 72 |
5834
|
|
| 73 | 73 |
tmaruyama |
| 74 | 74 |
has-props |
| 75 | 75 |
|
| ... | ... | |
| 92 | 92 |
|
| 93 | 93 |
|
| 94 | 94 |
|
| 95 |
3877
|
|
| 95 |
3916
|
|
| 96 | 96 |
|
| 97 | 97 |
git.rb |
| 98 | 98 |
file |
| ... | ... | |
| 100 | 100 |
|
| 101 | 101 |
|
| 102 | 102 |
|
| 103 |
2011-03-03T11:40:18.000000Z
|
|
| 104 |
dfce133f28c5c85af0740865903d5320
|
|
| 105 |
2011-03-01T05:14:03.146872Z
|
|
| 106 |
4975
|
|
| 103 |
2011-06-06T13:18:33.000000Z
|
|
| 104 |
b12b4b9bf012b30d430ddabf73eb4962
|
|
| 105 |
2011-05-19T22:58:38.288878Z
|
|
| 106 |
5858
|
|
| 107 | 107 |
tmaruyama |
| 108 | 108 |
has-props |
| 109 | 109 |
|
| ... | ... | |
| 126 | 126 |
|
| 127 | 127 |
|
| 128 | 128 |
|
| 129 |
4245
|
|
| 129 |
5213
|
|
| 130 | 130 |
|
| 131 | 131 |
mercurial.rb |
| 132 | 132 |
file |
| ... | ... | |
| 134 | 134 |
|
| 135 | 135 |
|
| 136 | 136 |
|
| 137 |
2011-03-03T11:40:18.000000Z
|
|
| 138 |
d659744391dfa02d54481d4dd8752930
|
|
| 139 |
2011-03-01T05:14:03.146872Z
|
|
| 140 |
4975
|
|
| 137 |
2011-06-06T13:18:33.000000Z
|
|
| 138 |
c02be7ffad5bb78d0cc096a7f88c45fc
|
|
| 139 |
2011-05-12T07:52:14.217350Z
|
|
| 140 |
5756
|
|
| 141 | 141 |
tmaruyama |
| 142 | 142 |
has-props |
| 143 | 143 |
|
| ... | ... | |
| 160 | 160 |
|
| 161 | 161 |
|
| 162 | 162 |
|
| 163 |
4022
|
|
| 163 |
5217
|
|
| 164 | 164 |
|
| 165 | 165 |
filesystem.rb |
| 166 | 166 |
file |
| ... | ... | |
| 168 | 168 |
|
| 169 | 169 |
|
| 170 | 170 |
|
| 171 |
2011-03-03T11:40:18.000000Z
|
|
| 172 |
994276556c2feac05d149117eea01413
|
|
| 173 |
2011-03-01T05:14:03.146872Z
|
|
| 174 |
4975
|
|
| 171 |
2011-06-06T13:18:33.000000Z
|
|
| 172 |
a2170e3cb1161b0ea016414b724438f0
|
|
| 173 |
2011-05-12T07:41:08.517774Z
|
|
| 174 |
5754
|
|
| 175 | 175 |
tmaruyama |
| 176 | 176 |
has-props |
| 177 | 177 |
|
| ... | ... | |
| 194 | 194 |
|
| 195 | 195 |
|
| 196 | 196 |
|
| 197 |
1451
|
|
| 197 |
1491
|
|
| 198 | 198 |
|
| 199 | 199 |
cvs.rb |
| 200 | 200 |
file |
| ... | ... | |
| 202 | 202 |
|
| 203 | 203 |
|
| 204 | 204 |
|
| 205 |
2011-03-03T11:40:18.000000Z
|
|
| 206 |
5eecf7abe1216489c4d1c2f6a107c36b
|
|
| 207 |
2011-03-01T10:27:30.170724Z
|
|
| 208 |
4982
|
|
| 205 |
2011-06-06T13:18:33.000000Z
|
|
| 206 |
a5f74e302ec1d5d5d4a0677b6537c399
|
|
| 207 |
2011-05-12T07:16:20.564757Z
|
|
| 208 |
5753
|
|
| 209 | 209 |
tmaruyama |
| 210 | 210 |
has-props |
| 211 | 211 |
|
| ... | ... | |
| 228 | 228 |
|
| 229 | 229 |
|
| 230 | 230 |
|
| 231 |
6952
|
|
| 231 |
7651
|
|
| 232 | 232 |
|
| 233 | 233 |
darcs.rb |
| 234 | 234 |
file |
| ... | ... | |
| 236 | 236 |
|
| 237 | 237 |
|
| 238 | 238 |
|
| 239 |
2011-03-03T11:40:18.000000Z
|
|
| 240 |
03bf9128aa09528266cabb76ff0808a9
|
|
| 241 |
2011-03-01T10:27:30.170724Z
|
|
| 242 |
4982
|
|
| 239 |
2011-06-06T13:18:33.000000Z
|
|
| 240 |
5fa94193e544a8c9d94a2cb501a273de
|
|
| 241 |
2011-05-12T07:41:29.099665Z
|
|
| 242 |
5755
|
|
| 243 | 243 |
tmaruyama |
| 244 | 244 |
has-props |
| 245 | 245 |
|
| ... | ... | |
| 262 | 262 |
|
| 263 | 263 |
|
| 264 | 264 |
|
| 265 |
3826
|
|
| 265 |
3881
|
|
| 266 | 266 |
|
| app/models/repository/.svn/text-base/bazaar.rb.svn-base | ||
|---|---|---|
| 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 |
# |
| 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. |
| ... | ... | |
| 21 | 21 |
attr_protected :root_url |
| 22 | 22 |
validates_presence_of :url, :log_encoding |
| 23 | 23 |
|
| 24 |
ATTRIBUTE_KEY_NAMES = {
|
|
| 25 |
"url" => "Root directory", |
|
| 26 |
"log_encoding" => "Commit messages encoding", |
|
| 27 |
} |
|
| 28 | 24 |
def self.human_attribute_name(attribute_key_name) |
| 29 |
ATTRIBUTE_KEY_NAMES[attribute_key_name] || super |
|
| 25 |
attr_name = attribute_key_name |
|
| 26 |
if attr_name == "url" |
|
| 27 |
attr_name = "path_to_repository" |
|
| 28 |
end |
|
| 29 |
super(attr_name) |
|
| 30 | 30 |
end |
| 31 | 31 |
|
| 32 | 32 |
def self.scm_adapter_class |
| ... | ... | |
| 47 | 47 |
full_path = File.join(root_url, e.path) |
| 48 | 48 |
e.size = File.stat(full_path).size if File.file?(full_path) |
| 49 | 49 |
end |
| 50 |
c = Change.find(:first, |
|
| 51 |
:include => :changeset, |
|
| 52 |
:conditions => ["#{Change.table_name}.revision = ? and #{Changeset.table_name}.repository_id = ?", e.lastrev.revision, id],
|
|
| 53 |
:order => "#{Changeset.table_name}.revision DESC")
|
|
| 50 |
c = Change.find( |
|
| 51 |
:first, |
|
| 52 |
:include => :changeset, |
|
| 53 |
:conditions => [ |
|
| 54 |
"#{Change.table_name}.revision = ? and #{Changeset.table_name}.repository_id = ?",
|
|
| 55 |
e.lastrev.revision, |
|
| 56 |
id |
|
| 57 |
], |
|
| 58 |
:order => "#{Changeset.table_name}.revision DESC")
|
|
| 54 | 59 |
if c |
| 55 | 60 |
e.lastrev.identifier = c.changeset.revision |
| 56 |
e.lastrev.name = c.changeset.revision |
|
| 57 |
e.lastrev.author = c.changeset.committer |
|
| 61 |
e.lastrev.name = c.changeset.revision
|
|
| 62 |
e.lastrev.author = c.changeset.committer
|
|
| 58 | 63 |
end |
| 59 | 64 |
end |
| 60 | 65 |
end |
| 61 | 66 |
end |
| 62 |
|
|
| 67 |
|
|
| 63 | 68 |
def fetch_changesets |
| 64 | 69 |
scm_info = scm.info |
| 65 | 70 |
if scm_info |
| ... | ... | |
| 76 | 81 |
revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
|
| 77 | 82 |
transaction do |
| 78 | 83 |
revisions.reverse_each do |revision| |
| 79 |
changeset = Changeset.create(:repository => self, |
|
| 80 |
:revision => revision.identifier,
|
|
| 81 |
:committer => revision.author,
|
|
| 84 |
changeset = Changeset.create(:repository => self,
|
|
| 85 |
:revision => revision.identifier,
|
|
| 86 |
:committer => revision.author,
|
|
| 82 | 87 |
:committed_on => revision.time, |
| 83 |
:scmid => revision.scmid, |
|
| 84 |
:comments => revision.message) |
|
| 85 |
|
|
| 88 |
:scmid => revision.scmid,
|
|
| 89 |
:comments => revision.message)
|
|
| 90 |
|
|
| 86 | 91 |
revision.paths.each do |change| |
| 87 | 92 |
Change.create(:changeset => changeset, |
| 88 |
:action => change[:action], |
|
| 89 |
:path => change[:path], |
|
| 90 |
:revision => change[:revision]) |
|
| 93 |
:action => change[:action],
|
|
| 94 |
:path => change[:path],
|
|
| 95 |
:revision => change[:revision])
|
|
| 91 | 96 |
end |
| 92 | 97 |
end |
| 93 | 98 |
end unless revisions.nil? |
| app/models/repository/.svn/text-base/cvs.rb.svn-base | ||
|---|---|---|
| 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 |
# |
| 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. |
| ... | ... | |
| 21 | 21 |
class Repository::Cvs < Repository |
| 22 | 22 |
validates_presence_of :url, :root_url, :log_encoding |
| 23 | 23 |
|
| 24 |
ATTRIBUTE_KEY_NAMES = {
|
|
| 25 |
"url" => "CVSROOT", |
|
| 26 |
"root_url" => "Module", |
|
| 27 |
"log_encoding" => "Commit messages encoding", |
|
| 28 |
} |
|
| 29 | 24 |
def self.human_attribute_name(attribute_key_name) |
| 30 |
ATTRIBUTE_KEY_NAMES[attribute_key_name] || super |
|
| 25 |
attr_name = attribute_key_name |
|
| 26 |
if attr_name == "root_url" |
|
| 27 |
attr_name = "cvsroot" |
|
| 28 |
elsif attr_name == "url" |
|
| 29 |
attr_name = "cvs_module" |
|
| 30 |
end |
|
| 31 |
super(attr_name) |
|
| 31 | 32 |
end |
| 32 | 33 |
|
| 33 | 34 |
def self.scm_adapter_class |
| ... | ... | |
| 42 | 43 |
rev = identifier.nil? ? nil : changesets.find_by_revision(identifier) |
| 43 | 44 |
scm.entry(path, rev.nil? ? nil : rev.committed_on) |
| 44 | 45 |
end |
| 45 |
|
|
| 46 |
|
|
| 46 | 47 |
def entries(path=nil, identifier=nil) |
| 47 |
rev = identifier.nil? ? nil : changesets.find_by_revision(identifier) |
|
| 48 |
rev = nil |
|
| 49 |
if ! identifier.nil? |
|
| 50 |
rev = changesets.find_by_revision(identifier) |
|
| 51 |
return nil if rev.nil? |
|
| 52 |
end |
|
| 48 | 53 |
entries = scm.entries(path, rev.nil? ? nil : rev.committed_on) |
| 49 | 54 |
if entries |
| 50 | 55 |
entries.each() do |entry| |
| 51 |
unless entry.lastrev.nil? || entry.lastrev.identifier |
|
| 52 |
change=changes.find_by_revision_and_path( entry.lastrev.revision, scm.with_leading_slash(entry.path) ) |
|
| 56 |
if ( ! entry.lastrev.nil? ) && ( ! entry.lastrev.revision.nil? ) |
|
| 57 |
change=changes.find_by_revision_and_path( |
|
| 58 |
entry.lastrev.revision, |
|
| 59 |
scm.with_leading_slash(entry.path) ) |
|
| 53 | 60 |
if change |
| 54 |
entry.lastrev.identifier=change.changeset.revision
|
|
| 55 |
entry.lastrev.author=change.changeset.committer
|
|
| 56 |
entry.lastrev.revision=change.revision
|
|
| 57 |
entry.lastrev.branch=change.branch
|
|
| 61 |
entry.lastrev.identifier = change.changeset.revision
|
|
| 62 |
entry.lastrev.revision = change.changeset.revision
|
|
| 63 |
entry.lastrev.author = change.changeset.committer
|
|
| 64 |
# entry.lastrev.branch = change.branch
|
|
| 58 | 65 |
end |
| 59 | 66 |
end |
| 60 | 67 |
end |
| 61 | 68 |
end |
| 62 | 69 |
entries |
| 63 | 70 |
end |
| 64 |
|
|
| 71 |
|
|
| 65 | 72 |
def cat(path, identifier=nil) |
| 66 |
rev = identifier.nil? ? nil : changesets.find_by_revision(identifier) |
|
| 73 |
rev = nil |
|
| 74 |
if ! identifier.nil? |
|
| 75 |
rev = changesets.find_by_revision(identifier) |
|
| 76 |
return nil if rev.nil? |
|
| 77 |
end |
|
| 67 | 78 |
scm.cat(path, rev.nil? ? nil : rev.committed_on) |
| 68 | 79 |
end |
| 69 |
|
|
| 80 |
|
|
| 81 |
def annotate(path, identifier=nil) |
|
| 82 |
rev = nil |
|
| 83 |
if ! identifier.nil? |
|
| 84 |
rev = changesets.find_by_revision(identifier) |
|
| 85 |
return nil if rev.nil? |
|
| 86 |
end |
|
| 87 |
scm.annotate(path, rev.nil? ? nil : rev.committed_on) |
|
| 88 |
end |
|
| 89 |
|
|
| 70 | 90 |
def diff(path, rev, rev_to) |
| 71 |
#convert rev to revision. CVS can't handle changesets here |
|
| 91 |
# convert rev to revision. CVS can't handle changesets here
|
|
| 72 | 92 |
diff=[] |
| 73 |
changeset_from=changesets.find_by_revision(rev)
|
|
| 74 |
if rev_to.to_i > 0
|
|
| 75 |
changeset_to=changesets.find_by_revision(rev_to)
|
|
| 93 |
changeset_from = changesets.find_by_revision(rev)
|
|
| 94 |
if rev_to.to_i > 0 |
|
| 95 |
changeset_to = changesets.find_by_revision(rev_to)
|
|
| 76 | 96 |
end |
| 77 | 97 |
changeset_from.changes.each() do |change_from| |
| 78 |
|
|
| 79 |
revision_from=nil |
|
| 80 |
revision_to=nil |
|
| 81 |
|
|
| 82 |
revision_from=change_from.revision if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path)) |
|
| 83 |
|
|
| 98 |
revision_from = nil |
|
| 99 |
revision_to = nil |
|
| 100 |
if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path)) |
|
| 101 |
revision_from = change_from.revision |
|
| 102 |
end |
|
| 84 | 103 |
if revision_from |
| 85 | 104 |
if changeset_to |
| 86 | 105 |
changeset_to.changes.each() do |change_to| |
| 87 |
revision_to=change_to.revision if change_to.path==change_from.path
|
|
| 106 |
revision_to = change_to.revision if change_to.path == change_from.path
|
|
| 88 | 107 |
end |
| 89 | 108 |
end |
| 90 | 109 |
unless revision_to |
| 91 |
revision_to=scm.get_previous_revision(revision_from)
|
|
| 110 |
revision_to = scm.get_previous_revision(revision_from)
|
|
| 92 | 111 |
end |
| 93 | 112 |
file_diff = scm.diff(change_from.path, revision_from, revision_to) |
| 94 | 113 |
diff = diff + file_diff unless file_diff.nil? |
| ... | ... | |
| 96 | 115 |
end |
| 97 | 116 |
return diff |
| 98 | 117 |
end |
| 99 |
|
|
| 118 |
|
|
| 100 | 119 |
def fetch_changesets |
| 101 | 120 |
# some nifty bits to introduce a commit-id with cvs |
| 102 |
# natively cvs doesn't provide any kind of changesets, there is only a revision per file. |
|
| 121 |
# natively cvs doesn't provide any kind of changesets, |
|
| 122 |
# there is only a revision per file. |
|
| 103 | 123 |
# we now take a guess using the author, the commitlog and the commit-date. |
| 104 |
|
|
| 105 |
# last one is the next step to take. the commit-date is not equal for all
|
|
| 124 |
|
|
| 125 |
# last one is the next step to take. the commit-date is not equal for all |
|
| 106 | 126 |
# commits in one changeset. cvs update the commit-date when the *,v file was touched. so |
| 107 | 127 |
# we use a small delta here, to merge all changes belonging to _one_ changeset |
| 108 |
time_delta=10.seconds |
|
| 109 |
|
|
| 128 |
time_delta = 10.seconds |
|
| 110 | 129 |
fetch_since = latest_changeset ? latest_changeset.committed_on : nil |
| 111 | 130 |
transaction do |
| 112 | 131 |
tmp_rev_num = 1 |
| 113 |
scm.revisions('', fetch_since, nil, :with_paths => true) do |revision|
|
|
| 132 |
scm.revisions('', fetch_since, nil, :log_encoding => repo_log_encoding) do |revision|
|
|
| 114 | 133 |
# only add the change to the database, if it doen't exists. the cvs log |
| 115 |
# is not exclusive at all.
|
|
| 134 |
# is not exclusive at all. |
|
| 116 | 135 |
tmp_time = revision.time.clone |
| 117 | 136 |
unless changes.find_by_path_and_revision( |
| 118 |
scm.with_leading_slash(revision.paths[0][:path]), revision.paths[0][:revision]) |
|
| 137 |
scm.with_leading_slash(revision.paths[0][:path]), |
|
| 138 |
revision.paths[0][:revision] |
|
| 139 |
) |
|
| 119 | 140 |
cmt = Changeset.normalize_comments(revision.message, repo_log_encoding) |
| 120 |
cs = changesets.find(:first, :conditions=>{
|
|
| 121 |
:committed_on=>tmp_time - time_delta .. tmp_time + time_delta, |
|
| 122 |
:committer=>revision.author, |
|
| 123 |
:comments=>cmt |
|
| 124 |
}) |
|
| 125 |
|
|
| 126 |
# create a new changeset.... |
|
| 141 |
author_utf8 = Changeset.to_utf8(revision.author, repo_log_encoding) |
|
| 142 |
cs = changesets.find( |
|
| 143 |
:first, |
|
| 144 |
:conditions => {
|
|
| 145 |
:committed_on => tmp_time - time_delta .. tmp_time + time_delta, |
|
| 146 |
:committer => author_utf8, |
|
| 147 |
:comments => cmt |
|
| 148 |
} |
|
| 149 |
) |
|
| 150 |
# create a new changeset.... |
|
| 127 | 151 |
unless cs |
| 128 | 152 |
# we use a temporaray revision number here (just for inserting) |
| 129 | 153 |
# later on, we calculate a continous positive number |
| 130 | 154 |
tmp_time2 = tmp_time.clone.gmtime |
| 131 |
branch = revision.paths[0][:branch] |
|
| 132 |
scmid = branch + "-" + tmp_time2.strftime("%Y%m%d-%H%M%S")
|
|
| 133 |
cs = Changeset.create(:repository => self, |
|
| 134 |
:revision => "tmp#{tmp_rev_num}",
|
|
| 135 |
:scmid => scmid, |
|
| 136 |
:committer => revision.author,
|
|
| 155 |
branch = revision.paths[0][:branch]
|
|
| 156 |
scmid = branch + "-" + tmp_time2.strftime("%Y%m%d-%H%M%S")
|
|
| 157 |
cs = Changeset.create(:repository => self,
|
|
| 158 |
:revision => "tmp#{tmp_rev_num}",
|
|
| 159 |
:scmid => scmid,
|
|
| 160 |
:committer => revision.author,
|
|
| 137 | 161 |
:committed_on => tmp_time, |
| 138 |
:comments => revision.message) |
|
| 162 |
:comments => revision.message)
|
|
| 139 | 163 |
tmp_rev_num += 1 |
| 140 | 164 |
end |
| 141 |
|
|
| 142 |
#convert CVS-File-States to internal Action-abbrevations |
|
| 143 |
#default action is (M)odified |
|
| 144 |
action="M" |
|
| 145 |
if revision.paths[0][:action]=="Exp" && revision.paths[0][:revision]=="1.1" |
|
| 146 |
action="A" #add-action always at first revision (= 1.1) |
|
| 147 |
elsif revision.paths[0][:action]=="dead" |
|
| 148 |
action="D" #dead-state is similar to Delete |
|
| 165 |
# convert CVS-File-States to internal Action-abbrevations |
|
| 166 |
# default action is (M)odified |
|
| 167 |
action = "M" |
|
| 168 |
if revision.paths[0][:action] == "Exp" && revision.paths[0][:revision] == "1.1" |
|
| 169 |
action = "A" # add-action always at first revision (= 1.1) |
|
| 170 |
elsif revision.paths[0][:action] == "dead" |
|
| 171 |
action = "D" # dead-state is similar to Delete |
|
| 149 | 172 |
end |
| 150 |
|
|
| 151 |
Change.create(:changeset => cs,
|
|
| 152 |
:action => action,
|
|
| 153 |
:path => scm.with_leading_slash(revision.paths[0][:path]),
|
|
| 154 |
:revision => revision.paths[0][:revision],
|
|
| 155 |
:branch => revision.paths[0][:branch]
|
|
| 156 |
) |
|
| 173 |
Change.create( |
|
| 174 |
:changeset => cs,
|
|
| 175 |
:action => action,
|
|
| 176 |
:path => scm.with_leading_slash(revision.paths[0][:path]),
|
|
| 177 |
:revision => revision.paths[0][:revision],
|
|
| 178 |
:branch => revision.paths[0][:branch]
|
|
| 179 |
)
|
|
| 157 | 180 |
end |
| 158 | 181 |
end |
| 159 |
|
|
| 182 |
|
|
| 160 | 183 |
# Renumber new changesets in chronological order |
| 161 | 184 |
changesets.find( |
| 162 |
:all, :order => 'committed_on ASC, id ASC', :conditions => "revision LIKE 'tmp%'" |
|
| 185 |
:all, |
|
| 186 |
:order => 'committed_on ASC, id ASC', |
|
| 187 |
:conditions => "revision LIKE 'tmp%'" |
|
| 163 | 188 |
).each do |changeset| |
| 164 | 189 |
changeset.update_attribute :revision, next_revision_number |
| 165 | 190 |
end |
| 166 | 191 |
end # transaction |
| 167 | 192 |
@current_revision_number = nil |
| 168 | 193 |
end |
| 169 |
|
|
| 194 |
|
|
| 170 | 195 |
private |
| 171 |
|
|
| 196 |
|
|
| 172 | 197 |
# Returns the next revision number to assign to a CVS changeset |
| 173 | 198 |
def next_revision_number |
| 174 | 199 |
# Need to retrieve existing revision numbers to sort them as integers |
| app/models/repository/.svn/text-base/darcs.rb.svn-base | ||
|---|---|---|
| 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 |
# |
| 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. |
| ... | ... | |
| 20 | 20 |
class Repository::Darcs < Repository |
| 21 | 21 |
validates_presence_of :url, :log_encoding |
| 22 | 22 |
|
| 23 |
ATTRIBUTE_KEY_NAMES = {
|
|
| 24 |
"url" => "Root directory", |
|
| 25 |
"log_encoding" => "Commit messages encoding", |
|
| 26 |
} |
|
| 27 | 23 |
def self.human_attribute_name(attribute_key_name) |
| 28 |
ATTRIBUTE_KEY_NAMES[attribute_key_name] || super |
|
| 24 |
attr_name = attribute_key_name |
|
| 25 |
if attr_name == "url" |
|
| 26 |
attr_name = "path_to_repository" |
|
| 27 |
end |
|
| 28 |
super(attr_name) |
|
| 29 | 29 |
end |
| 30 | 30 |
|
| 31 | 31 |
def self.scm_adapter_class |
| ... | ... | |
| 36 | 36 |
'Darcs' |
| 37 | 37 |
end |
| 38 | 38 |
|
| 39 |
def supports_directory_revisions? |
|
| 40 |
true |
|
| 41 |
end |
|
| 42 |
|
|
| 39 | 43 |
def entry(path=nil, identifier=nil) |
| 40 | 44 |
patch = identifier.nil? ? nil : changesets.find_by_revision(identifier) |
| 41 | 45 |
scm.entry(path, patch.nil? ? nil : patch.scmid) |
| 42 | 46 |
end |
| 43 |
|
|
| 47 |
|
|
| 44 | 48 |
def entries(path=nil, identifier=nil) |
| 45 |
patch = identifier.nil? ? nil : changesets.find_by_revision(identifier) |
|
| 49 |
patch = nil |
|
| 50 |
if ! identifier.nil? |
|
| 51 |
patch = changesets.find_by_revision(identifier) |
|
| 52 |
return nil if patch.nil? |
|
| 53 |
end |
|
| 46 | 54 |
entries = scm.entries(path, patch.nil? ? nil : patch.scmid) |
| 47 | 55 |
if entries |
| 48 | 56 |
entries.each do |entry| |
| 49 | 57 |
# Search the DB for the entry's last change |
| 50 |
changeset = changesets.find_by_scmid(entry.lastrev.scmid) if entry.lastrev && !entry.lastrev.scmid.blank? |
|
| 58 |
if entry.lastrev && !entry.lastrev.scmid.blank? |
|
| 59 |
changeset = changesets.find_by_scmid(entry.lastrev.scmid) |
|
| 60 |
end |
|
| 51 | 61 |
if changeset |
| 52 | 62 |
entry.lastrev.identifier = changeset.revision |
| 53 |
entry.lastrev.name = changeset.revision |
|
| 54 |
entry.lastrev.time = changeset.committed_on |
|
| 55 |
entry.lastrev.author = changeset.committer |
|
| 63 |
entry.lastrev.name = changeset.revision
|
|
| 64 |
entry.lastrev.time = changeset.committed_on
|
|
| 65 |
entry.lastrev.author = changeset.committer
|
|
| 56 | 66 |
end |
| 57 | 67 |
end |
| 58 | 68 |
end |
| 59 | 69 |
entries |
| 60 | 70 |
end |
| 61 |
|
|
| 71 |
|
|
| 62 | 72 |
def cat(path, identifier=nil) |
| 63 | 73 |
patch = identifier.nil? ? nil : changesets.find_by_revision(identifier.to_s) |
| 64 | 74 |
scm.cat(path, patch.nil? ? nil : patch.scmid) |
| 65 | 75 |
end |
| 66 |
|
|
| 76 |
|
|
| 67 | 77 |
def diff(path, rev, rev_to) |
| 68 | 78 |
patch_from = changesets.find_by_revision(rev) |
| 69 | 79 |
return nil if patch_from.nil? |
| ... | ... | |
| 73 | 83 |
end |
| 74 | 84 |
patch_from ? scm.diff(path, patch_from.scmid, patch_to ? patch_to.scmid : nil) : nil |
| 75 | 85 |
end |
| 76 |
|
|
| 86 |
|
|
| 77 | 87 |
def fetch_changesets |
| 78 | 88 |
scm_info = scm.info |
| 79 | 89 |
if scm_info |
| 80 | 90 |
db_last_id = latest_changeset ? latest_changeset.scmid : nil |
| 81 |
next_rev = latest_changeset ? latest_changeset.revision.to_i + 1 : 1
|
|
| 91 |
next_rev = latest_changeset ? latest_changeset.revision.to_i + 1 : 1
|
|
| 82 | 92 |
# latest revision in the repository |
| 83 |
scm_revision = scm_info.lastrev.scmid
|
|
| 93 |
scm_revision = scm_info.lastrev.scmid |
|
| 84 | 94 |
unless changesets.find_by_scmid(scm_revision) |
| 85 | 95 |
revisions = scm.revisions('', db_last_id, nil, :with_path => true)
|
| 86 | 96 |
transaction do |
| 87 | 97 |
revisions.reverse_each do |revision| |
| 88 |
changeset = Changeset.create(:repository => self, |
|
| 89 |
:revision => next_rev, |
|
| 90 |
:scmid => revision.scmid, |
|
| 91 |
:committer => revision.author,
|
|
| 98 |
changeset = Changeset.create(:repository => self,
|
|
| 99 |
:revision => next_rev,
|
|
| 100 |
:scmid => revision.scmid,
|
|
| 101 |
:committer => revision.author,
|
|
| 92 | 102 |
:committed_on => revision.time, |
| 93 |
:comments => revision.message) |
|
| 94 |
|
|
| 103 |
:comments => revision.message) |
|
| 95 | 104 |
revision.paths.each do |change| |
| 96 | 105 |
changeset.create_change(change) |
| 97 | 106 |
end |
| app/models/repository/.svn/text-base/filesystem.rb.svn-base | ||
|---|---|---|
| 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 |
# |
| 4 | 4 |
# FileSystem adapter |
| 5 | 5 |
# File written by Paul Rivier, at Demotera. |
| ... | ... | |
| 8 | 8 |
# modify it under the terms of the GNU General Public License |
| 9 | 9 |
# as published by the Free Software Foundation; either version 2 |
| 10 | 10 |
# of the License, or (at your option) any later version. |
| 11 |
#
|
|
| 11 |
# |
|
| 12 | 12 |
# This program is distributed in the hope that it will be useful, |
| 13 | 13 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | 14 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | 15 |
# GNU General Public License for more details. |
| 16 |
#
|
|
| 16 |
# |
|
| 17 | 17 |
# You should have received a copy of the GNU General Public License |
| 18 | 18 |
# along with this program; if not, write to the Free Software |
| 19 | 19 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| ... | ... | |
| 24 | 24 |
attr_protected :root_url |
| 25 | 25 |
validates_presence_of :url |
| 26 | 26 |
|
| 27 |
ATTRIBUTE_KEY_NAMES = {
|
|
| 28 |
"url" => "Root directory", |
|
| 29 |
} |
|
| 30 | 27 |
def self.human_attribute_name(attribute_key_name) |
| 31 |
ATTRIBUTE_KEY_NAMES[attribute_key_name] || super |
|
| 28 |
attr_name = attribute_key_name |
|
| 29 |
if attr_name == "url" |
|
| 30 |
attr_name = "root_directory" |
|
| 31 |
end |
|
| 32 |
super(attr_name) |
|
| 32 | 33 |
end |
| 33 | 34 |
|
| 34 | 35 |
def self.scm_adapter_class |
| ... | ... | |
| 39 | 40 |
'Filesystem' |
| 40 | 41 |
end |
| 41 | 42 |
|
| 43 |
def supports_all_revisions? |
|
| 44 |
false |
|
| 45 |
end |
|
| 46 |
|
|
| 42 | 47 |
def entries(path=nil, identifier=nil) |
| 43 | 48 |
scm.entries(path, identifier) |
| 44 | 49 |
end |
| ... | ... | |
| 46 | 51 |
def fetch_changesets |
| 47 | 52 |
nil |
| 48 | 53 |
end |
| 49 |
|
|
| 50 | 54 |
end |
| app/models/repository/.svn/text-base/git.rb.svn-base | ||
|---|---|---|
| 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. |
| ... | ... | |
| 21 | 22 |
attr_protected :root_url |
| 22 | 23 |
validates_presence_of :url |
| 23 | 24 |
|
| 24 |
ATTRIBUTE_KEY_NAMES = {
|
|
| 25 |
"url" => "Path to repository", |
|
| 26 |
} |
|
| 27 | 25 |
def self.human_attribute_name(attribute_key_name) |
| 28 |
ATTRIBUTE_KEY_NAMES[attribute_key_name] || super |
|
| 26 |
attr_name = attribute_key_name |
|
| 27 |
if attr_name == "url" |
|
| 28 |
attr_name = "path_to_repository" |
|
| 29 |
end |
|
| 30 |
super(attr_name) |
|
| 29 | 31 |
end |
| 30 | 32 |
|
| 31 | 33 |
def self.scm_adapter_class |
| ... | ... | |
| 36 | 38 |
'Git' |
| 37 | 39 |
end |
| 38 | 40 |
|
| 41 |
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 |
|
|
| 39 | 56 |
def repo_log_encoding |
| 40 | 57 |
'UTF-8' |
| 41 | 58 |
end |
| ... | ... | |
| 65 | 82 |
changesets.find(:first, :conditions => ['scmid LIKE ?', "#{name}%"])
|
| 66 | 83 |
end |
| 67 | 84 |
|
| 68 |
# With SCM's that have a sequential commit numbering, redmine is able to be |
|
| 69 |
# clever and only fetch changesets going forward from the most recent one |
|
| 70 |
# it knows about. However, with git, you never know if people have merged |
|
| 71 |
# commits into the middle of the repository history, so we should parse |
|
| 72 |
# the entire log. Since it's way too slow for large repositories, we only |
|
| 73 |
# parse 1 week before the last known commit. |
|
| 85 |
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 |
# |
|
| 74 | 107 |
# The repository can still be fully reloaded by calling #clear_changesets |
| 75 | 108 |
# before fetching changesets (eg. for offline resync) |
| 76 | 109 |
def fetch_changesets |
| 77 |
c = changesets.find(:first, :order => 'committed_on DESC') |
|
| 78 |
since = (c ? c.committed_on - 7.days : nil) |
|
| 79 |
|
|
| 80 |
revisions = scm.revisions('', nil, nil, :all => true, :since => since)
|
|
| 81 |
return if revisions.nil? || revisions.empty? |
|
| 82 |
|
|
| 83 |
recent_changesets = changesets.find(:all, :conditions => ['committed_on >= ?', since]) |
|
| 84 |
|
|
| 85 |
# Clean out revisions that are no longer in git |
|
| 86 |
recent_changesets.each {|c| c.destroy unless revisions.detect {|r| r.scmid.to_s == c.scmid.to_s }}
|
|
| 87 |
|
|
| 88 |
# Subtract revisions that redmine already knows about |
|
| 89 |
recent_revisions = recent_changesets.map{|c| c.scmid}
|
|
| 90 |
revisions.reject!{|r| recent_revisions.include?(r.scmid)}
|
|
| 91 |
|
|
| 92 |
# Save the remaining ones to the database |
|
| 93 |
unless revisions.nil? |
|
| 94 |
revisions.each do |rev| |
|
| 110 |
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) |
|
| 95 | 131 |
transaction do |
| 96 |
changeset = Changeset.new( |
|
| 97 |
:repository => self, |
|
| 98 |
:revision => rev.identifier, |
|
| 99 |
:scmid => rev.scmid, |
|
| 100 |
:committer => rev.author, |
|
| 101 |
:committed_on => rev.time, |
|
| 102 |
:comments => rev.message) |
|
| 103 |
|
|
| 104 |
if changeset.save |
|
| 105 |
rev.paths.each do |file| |
|
| 106 |
Change.create( |
|
| 107 |
:changeset => changeset, |
|
| 108 |
:action => file[:action], |
|
| 109 |
:path => file[:path]) |
|
| 110 |
end |
|
| 132 |
if db_rev.nil? |
|
| 133 |
save_revision(rev) |
|
| 111 | 134 |
end |
| 135 |
h["branches"][br]["last_scmid"] = rev.scmid |
|
| 136 |
merge_extra_info(h) |
|
| 137 |
self.save |
|
| 112 | 138 |
end |
| 113 | 139 |
end |
| 114 | 140 |
end |
| 115 | 141 |
end |
| 116 | 142 |
|
| 143 |
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 |
|
|
| 117 | 163 |
def latest_changesets(path,rev,limit=10) |
| 118 | 164 |
revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false) |
| 119 | 165 |
return [] if revisions.nil? || revisions.empty? |
| 120 | 166 |
|
| 121 | 167 |
changesets.find( |
| 122 |
:all,
|
|
| 168 |
:all, |
|
| 123 | 169 |
:conditions => [ |
| 124 |
"scmid IN (?)",
|
|
| 170 |
"scmid IN (?)", |
|
| 125 | 171 |
revisions.map!{|c| c.scmid}
|
| 126 | 172 |
], |
| 127 | 173 |
:order => 'committed_on DESC' |
| app/models/repository/.svn/text-base/mercurial.rb.svn-base | ||
|---|---|---|
| 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 |
# |
| 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. |
| ... | ... | |
| 26 | 26 |
|
| 27 | 27 |
FETCH_AT_ONCE = 100 # number of changesets to fetch at once |
| 28 | 28 |
|
| 29 |
ATTRIBUTE_KEY_NAMES = {
|
|
| 30 |
"url" => "Root directory", |
|
| 31 |
} |
|
| 32 | 29 |
def self.human_attribute_name(attribute_key_name) |
| 33 |
ATTRIBUTE_KEY_NAMES[attribute_key_name] || super |
|
| 30 |
attr_name = attribute_key_name |
|
| 31 |
if attr_name == "url" |
|
| 32 |
attr_name = "path_to_repository" |
|
| 33 |
end |
|
| 34 |
super(attr_name) |
|
| 34 | 35 |
end |
| 35 | 36 |
|
| 36 | 37 |
def self.scm_adapter_class |
| ... | ... | |
| 41 | 42 |
'Mercurial' |
| 42 | 43 |
end |
| 43 | 44 |
|
| 45 |
def supports_directory_revisions? |
|
| 46 |
true |
|
| 47 |
end |
|
| 48 |
|
|
| 44 | 49 |
def repo_log_encoding |
| 45 | 50 |
'UTF-8' |
| 46 | 51 |
end |
| ... | ... | |
| 55 | 60 |
changeset.scmid |
| 56 | 61 |
end |
| 57 | 62 |
|
| 58 |
def branches |
|
| 59 |
nil |
|
| 60 |
end |
|
| 61 |
|
|
| 62 |
def tags |
|
| 63 |
nil |
|
| 64 |
end |
|
| 65 |
|
|
| 66 | 63 |
def diff_format_revisions(cs, cs_to, sep=':') |
| 67 | 64 |
super(cs, cs_to, ' ') |
| 68 | 65 |
end |
| ... | ... | |
| 80 | 77 |
end |
| 81 | 78 |
|
| 82 | 79 |
# Returns the latest changesets for +path+; sorted by revision number |
| 83 |
# Default behavior is to search in cached changesets |
|
| 80 |
# |
|
| 81 |
# Because :order => 'id DESC' is defined at 'has_many', |
|
| 82 |
# there is no need to set 'order'. |
|
| 83 |
# But, MySQL test fails. |
|
| 84 |
# Sqlite3 and PostgreSQL pass. |
|
| 85 |
# Is this MySQL bug? |
|
| 84 | 86 |
def latest_changesets(path, rev, limit=10) |
| 85 |
if path.blank? |
|
| 86 |
changesets.find(:all, :include => :user, :limit => limit) |
|
| 87 |
else |
|
| 88 |
changesets.find(:all, :select => "DISTINCT #{Changeset.table_name}.*",
|
|
| 89 |
:joins => :changes, |
|
| 90 |
:conditions => ["#{Change.table_name}.path = ? OR #{Change.table_name}.path LIKE ? ESCAPE ?",
|
|
| 91 |
path.with_leading_slash, |
|
| 92 |
"#{path.with_leading_slash.gsub(/[%_\\]/) { |s| "\\#{s}" }}/%", '\\'],
|
|
| 93 |
:include => :user, :limit => limit) |
|
| 87 |
changesets.find(:all, :include => :user, |
|
| 88 |
:conditions => latest_changesets_cond(path, rev, limit), |
|
| 89 |
:limit => limit, :order => "#{Changeset.table_name}.id DESC")
|
|
| 90 |
end |
|
| 91 |
|
|
| 92 |
def latest_changesets_cond(path, rev, limit) |
|
| 93 |
cond, args = [], [] |
|
| 94 |
if scm.branchmap.member? rev |
|
| 95 |
# Mercurial named branch is *stable* in each revision. |
|
| 96 |
# So, named branch can be stored in database. |
|
| 97 |
# Mercurial provides *bookmark* which is equivalent with git branch. |
|
| 98 |
# But, bookmark is not implemented. |
|
| 99 |
cond << "#{Changeset.table_name}.scmid IN (?)"
|
|
| 100 |
# Revisions in root directory and sub directory are not equal. |
|
| 101 |
# So, in order to get correct limit, we need to get all revisions. |
|
| 102 |
# But, it is very heavy. |
|
| 103 |
# Mercurial does not treat direcotry. |
|
| 104 |
# So, "hg log DIR" is very heavy. |
|
| 105 |
branch_limit = path.blank? ? limit : ( limit * 5 ) |
|
| 106 |
args << scm.nodes_in_branch(rev, :limit => branch_limit) |
|
| 107 |
elsif last = rev ? find_changeset_by_name(scm.tagmap[rev] || rev) : nil |
|
| 108 |
cond << "#{Changeset.table_name}.id <= ?"
|
|
| 109 |
args << last.id |
|
| 94 | 110 |
end |
| 111 |
|
|
| 112 |
unless path.blank? |
|
| 113 |
cond << "EXISTS (SELECT * FROM #{Change.table_name}
|
|
| 114 |
WHERE #{Change.table_name}.changeset_id = #{Changeset.table_name}.id
|
|
| 115 |
AND (#{Change.table_name}.path = ?
|
|
| 116 |
OR #{Change.table_name}.path LIKE ? ESCAPE ?))"
|
|
| 117 |
args << path.with_leading_slash |
|
| 118 |
args << "#{path.with_leading_slash.gsub(/[%_\\]/) { |s| "\\#{s}" }}/%" << '\\'
|
|
| 119 |
end |
|
| 120 |
|
|
| 121 |
[cond.join(' AND '), *args] unless cond.empty?
|
|
| 95 | 122 |
end |
| 123 |
private :latest_changesets_cond |
|
| 96 | 124 |
|
| 97 | 125 |
def fetch_changesets |
| 98 | 126 |
scm_rev = scm.info.lastrev.revision.to_i |
| app/models/repository/.svn/text-base/subversion.rb.svn-base | ||
|---|---|---|
| 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 |
# |
| 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. |
| ... | ... | |
| 30 | 30 |
'Subversion' |
| 31 | 31 |
end |
| 32 | 32 |
|
| 33 |
def supports_directory_revisions? |
|
| 34 |
true |
|
| 35 |
end |
|
| 36 |
|
|
| 33 | 37 |
def repo_log_encoding |
| 34 | 38 |
'UTF-8' |
| 35 | 39 |
end |
| ... | ... | |
| 38 | 42 |
revisions = scm.revisions(path, rev, nil, :limit => limit) |
| 39 | 43 |
revisions ? changesets.find_all_by_revision(revisions.collect(&:identifier), :order => "committed_on DESC", :include => :user) : [] |
| 40 | 44 |
end |
| 41 |
|
|
| 45 |
|
|
| 42 | 46 |
# Returns a path relative to the url of the repository |
| 43 | 47 |
def relative_path(path) |
| 44 | 48 |
path.gsub(Regexp.new("^\/?#{Regexp.escape(relative_url)}"), '')
|
| 45 | 49 |
end |
| 46 |
|
|
| 50 |
|
|
| 47 | 51 |
def fetch_changesets |
| 48 | 52 |
scm_info = scm.info |
| 49 | 53 |
if scm_info |
| ... | ... | |
| 60 | 64 |
revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
|
| 61 | 65 |
revisions.reverse_each do |revision| |
| 62 | 66 |
transaction do |
| 63 |
changeset = Changeset.create(:repository => self, |
|
| 64 |
:revision => revision.identifier,
|
|
| 65 |
:committer => revision.author,
|
|
| 67 |
changeset = Changeset.create(:repository => self,
|
|
| 68 |
:revision => revision.identifier,
|
|
| 69 |
:committer => revision.author,
|
|
| 66 | 70 |
:committed_on => revision.time, |
| 67 |
:comments => revision.message) |
|
| 68 |
|
|
| 71 |
:comments => revision.message)
|
|
| 72 |
|
|
| 69 | 73 |
revision.paths.each do |change| |
| 70 | 74 |
changeset.create_change(change) |
| 71 | 75 |
end unless changeset.new_record? |
| ... | ... | |
| 76 | 80 |
end |
| 77 | 81 |
end |
| 78 | 82 |
end |
| 79 |
|
|
| 83 |
|
|
| 80 | 84 |
private |
| 81 |
|
|
| 85 |
|
|
| 82 | 86 |
# Returns the relative url of the repository |
| 83 | 87 |
# Eg: root_url = file:///var/svn/foo |
| 84 | 88 |
# url = file:///var/svn/foo/bar |
| app/models/repository/bazaar.rb | ||
|---|---|---|
| 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 |
# |
| 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. |
| ... | ... | |
| 21 | 21 |
attr_protected :root_url |
| 22 | 22 |
validates_presence_of :url, :log_encoding |
| 23 | 23 |
|
| 24 |
ATTRIBUTE_KEY_NAMES = {
|
|
| 25 |
"url" => "Root directory", |
|
| 26 |
"log_encoding" => "Commit messages encoding", |
|
| 27 |
} |
|
| 28 | 24 |
def self.human_attribute_name(attribute_key_name) |
| 29 |
ATTRIBUTE_KEY_NAMES[attribute_key_name] || super |
|
| 25 |
attr_name = attribute_key_name |
|
| 26 |
if attr_name == "url" |
|
| 27 |
attr_name = "path_to_repository" |
|
| 28 |
end |
|
| 29 |
super(attr_name) |
|
| 30 | 30 |
end |
| 31 | 31 |
|
| 32 | 32 |
def self.scm_adapter_class |
| ... | ... | |
| 47 | 47 |
full_path = File.join(root_url, e.path) |
| 48 | 48 |
e.size = File.stat(full_path).size if File.file?(full_path) |
| 49 | 49 |
end |
| 50 |
c = Change.find(:first, |
|
| 51 |
:include => :changeset, |
|
| 52 |
:conditions => ["#{Change.table_name}.revision = ? and #{Changeset.table_name}.repository_id = ?", e.lastrev.revision, id],
|
|
| 53 |
:order => "#{Changeset.table_name}.revision DESC")
|
|
| 50 |
c = Change.find( |
|
| 51 |
:first, |
|
| 52 |
:include => :changeset, |
|
| 53 |
:conditions => [ |
|
| 54 |
"#{Change.table_name}.revision = ? and #{Changeset.table_name}.repository_id = ?",
|
|
| 55 |
e.lastrev.revision, |
|
| 56 |
id |
|
| 57 |
], |
|
| 58 |
:order => "#{Changeset.table_name}.revision DESC")
|
|
| 54 | 59 |
if c |
| 55 | 60 |
e.lastrev.identifier = c.changeset.revision |
| 56 |
e.lastrev.name = c.changeset.revision |
|
| 57 |
e.lastrev.author = c.changeset.committer |
|
| 61 |
e.lastrev.name = c.changeset.revision
|
|
| 62 |
e.lastrev.author = c.changeset.committer
|
|
| 58 | 63 |
end |
| 59 | 64 |
end |
| 60 | 65 |
end |
| 61 | 66 |
end |
| 62 |
|
|
| 67 |
|
|
| 63 | 68 |
def fetch_changesets |
| 64 | 69 |
scm_info = scm.info |
| 65 | 70 |
if scm_info |
| ... | ... | |
| 76 | 81 |
revisions = scm.revisions('', identifier_to, identifier_from, :with_paths => true)
|
| 77 | 82 |
transaction do |
| 78 | 83 |
revisions.reverse_each do |revision| |
| 79 |
changeset = Changeset.create(:repository => self, |
|
| 80 |
:revision => revision.identifier,
|
|
| 81 |
:committer => revision.author,
|
|
| 84 |
changeset = Changeset.create(:repository => self,
|
|
| 85 |
:revision => revision.identifier,
|
|
| 86 |
:committer => revision.author,
|
|
| 82 | 87 |
:committed_on => revision.time, |
| 83 |
:scmid => revision.scmid, |
|
| 84 |
:comments => revision.message) |
|
| 85 |
|
|
| 88 |
:scmid => revision.scmid,
|
|
| 89 |
:comments => revision.message)
|
|
| 90 |
|
|
| 86 | 91 |
revision.paths.each do |change| |
| 87 | 92 |
Change.create(:changeset => changeset, |
| 88 |
:action => change[:action], |
|
| 89 |
:path => change[:path], |
|
| 90 |
:revision => change[:revision]) |
|
| 93 |
:action => change[:action],
|
|
| 94 |
:path => change[:path],
|
|
| 95 |
:revision => change[:revision])
|
|
| 91 | 96 |
end |
| 92 | 97 |
end |
| 93 | 98 |
end unless revisions.nil? |
| app/models/repository/cvs.rb | ||
|---|---|---|
| 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 |
# |
| 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. |
| ... | ... | |
| 21 | 21 |
class Repository::Cvs < Repository |
| 22 | 22 |
validates_presence_of :url, :root_url, :log_encoding |
| 23 | 23 |
|
| 24 |
ATTRIBUTE_KEY_NAMES = {
|
|
| 25 |
"url" => "CVSROOT", |
|
| 26 |
"root_url" => "Module", |
|
| 27 |
"log_encoding" => "Commit messages encoding", |
|
| 28 |
} |
|
| 29 | 24 |
def self.human_attribute_name(attribute_key_name) |
| 30 |
ATTRIBUTE_KEY_NAMES[attribute_key_name] || super |
|
| 25 |
attr_name = attribute_key_name |
|
| 26 |
if attr_name == "root_url" |
|
| 27 |
attr_name = "cvsroot" |
|
| 28 |
elsif attr_name == "url" |
|
| 29 |
attr_name = "cvs_module" |
|
| 30 |
end |
|
| 31 |
super(attr_name) |
|
| 31 | 32 |
end |
| 32 | 33 |
|
| 33 | 34 |
def self.scm_adapter_class |
| ... | ... | |
| 42 | 43 |
rev = identifier.nil? ? nil : changesets.find_by_revision(identifier) |
| 43 | 44 |
scm.entry(path, rev.nil? ? nil : rev.committed_on) |
| 44 | 45 |
end |
| 45 |
|
|
| 46 |
|
|
| 46 | 47 |
def entries(path=nil, identifier=nil) |
| 47 |
rev = identifier.nil? ? nil : changesets.find_by_revision(identifier) |
|
| 48 |
rev = nil |
|
| 49 |
if ! identifier.nil? |
|
| 50 |
rev = changesets.find_by_revision(identifier) |
|
| 51 |
return nil if rev.nil? |
|
| 52 |
end |
|
| 48 | 53 |
entries = scm.entries(path, rev.nil? ? nil : rev.committed_on) |
| 49 | 54 |
if entries |
| 50 | 55 |
entries.each() do |entry| |
| 51 |
unless entry.lastrev.nil? || entry.lastrev.identifier |
|
| 52 |
change=changes.find_by_revision_and_path( entry.lastrev.revision, scm.with_leading_slash(entry.path) ) |
|
| 56 |
if ( ! entry.lastrev.nil? ) && ( ! entry.lastrev.revision.nil? ) |
|
| 57 |
change=changes.find_by_revision_and_path( |
|
| 58 |
entry.lastrev.revision, |
|
| 59 |
scm.with_leading_slash(entry.path) ) |
|
| 53 | 60 |
if change |
| 54 |
entry.lastrev.identifier=change.changeset.revision
|
|
| 55 |
entry.lastrev.author=change.changeset.committer
|
|
| 56 |
entry.lastrev.revision=change.revision
|
|
| 57 |
entry.lastrev.branch=change.branch
|
|
| 61 |
entry.lastrev.identifier = change.changeset.revision
|
|
| 62 |
entry.lastrev.revision = change.changeset.revision
|
|
| 63 |
entry.lastrev.author = change.changeset.committer
|
|
| 64 |
# entry.lastrev.branch = change.branch
|
|
| 58 | 65 |
end |
| 59 | 66 |
end |
| 60 | 67 |
end |
| 61 | 68 |
end |
| 62 | 69 |
entries |
| 63 | 70 |
end |
| 64 |
|
|
| 71 |
|
|
| 65 | 72 |
def cat(path, identifier=nil) |
| 66 |
rev = identifier.nil? ? nil : changesets.find_by_revision(identifier) |
|
| 73 |
rev = nil |
|
| 74 |
if ! identifier.nil? |
|
| 75 |
rev = changesets.find_by_revision(identifier) |
|
| 76 |
return nil if rev.nil? |
|
| 77 |
end |
|
| 67 | 78 |
scm.cat(path, rev.nil? ? nil : rev.committed_on) |
| 68 | 79 |
end |
| 69 |
|
|
| 80 |
|
|
| 81 |
def annotate(path, identifier=nil) |
|
| 82 |
rev = nil |
|
| 83 |
if ! identifier.nil? |
|
| 84 |
rev = changesets.find_by_revision(identifier) |
|
| 85 |
return nil if rev.nil? |
|
| 86 |
end |
|
| 87 |
scm.annotate(path, rev.nil? ? nil : rev.committed_on) |
|
| 88 |
end |
|
| 89 |
|
|
| 70 | 90 |
def diff(path, rev, rev_to) |
| 71 |
#convert rev to revision. CVS can't handle changesets here |
|
| 91 |
# convert rev to revision. CVS can't handle changesets here
|
|
| 72 | 92 |
diff=[] |
| 73 |
changeset_from=changesets.find_by_revision(rev)
|
|
| 74 |
if rev_to.to_i > 0
|
|
| 75 |
changeset_to=changesets.find_by_revision(rev_to)
|
|
| 93 |
changeset_from = changesets.find_by_revision(rev)
|
|
| 94 |
if rev_to.to_i > 0 |
|
| 95 |
changeset_to = changesets.find_by_revision(rev_to)
|
|
| 76 | 96 |
end |
| 77 | 97 |
changeset_from.changes.each() do |change_from| |
| 78 |
|
|
| 79 |
revision_from=nil |
|
| 80 |
revision_to=nil |
|
| 81 |
|
|
| 82 |
revision_from=change_from.revision if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path)) |
|
| 83 |
|
|
| 98 |
revision_from = nil |
|
| 99 |
revision_to = nil |
|
| 100 |
if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path)) |
|
| 101 |
revision_from = change_from.revision |
|
| 102 |
end |
|
| 84 | 103 |
if revision_from |
| 85 | 104 |
if changeset_to |
| 86 | 105 |
changeset_to.changes.each() do |change_to| |
| 87 |
revision_to=change_to.revision if change_to.path==change_from.path
|
|
| 106 |
revision_to = change_to.revision if change_to.path == change_from.path
|
|
| 88 | 107 |
end |
| 89 | 108 |
end |
| 90 | 109 |
unless revision_to |
| 91 |
revision_to=scm.get_previous_revision(revision_from)
|
|
| 110 |
revision_to = scm.get_previous_revision(revision_from)
|
|
| 92 | 111 |
end |
| 93 | 112 |
file_diff = scm.diff(change_from.path, revision_from, revision_to) |
| 94 | 113 |
diff = diff + file_diff unless file_diff.nil? |
| ... | ... | |
| 96 | 115 |
end |
| 97 | 116 |
return diff |
| 98 | 117 |
end |
| 99 |
|
|
| 118 |
|
|
| 100 | 119 |
def fetch_changesets |
| 101 | 120 |
# some nifty bits to introduce a commit-id with cvs |
| 102 |
# natively cvs doesn't provide any kind of changesets, there is only a revision per file. |
|
| 121 |
# natively cvs doesn't provide any kind of changesets, |
|
| 122 |
# there is only a revision per file. |
|
| 103 | 123 |
# we now take a guess using the author, the commitlog and the commit-date. |
| 104 |
|
|
| 105 |
# last one is the next step to take. the commit-date is not equal for all
|
|
| 124 |
|
|
| 125 |
# last one is the next step to take. the commit-date is not equal for all |
|
| 106 | 126 |
# commits in one changeset. cvs update the commit-date when the *,v file was touched. so |
| 107 | 127 |
# we use a small delta here, to merge all changes belonging to _one_ changeset |
| 108 |
time_delta=10.seconds |
|
| 109 |
|
|
| 128 |
time_delta = 10.seconds |
|
| 110 | 129 |
fetch_since = latest_changeset ? latest_changeset.committed_on : nil |
| 111 | 130 |
transaction do |
| 112 | 131 |
tmp_rev_num = 1 |
| 113 |
scm.revisions('', fetch_since, nil, :with_paths => true) do |revision|
|
|
| 132 |
scm.revisions('', fetch_since, nil, :log_encoding => repo_log_encoding) do |revision|
|
|
| 114 | 133 |
# only add the change to the database, if it doen't exists. the cvs log |
| 115 |
# is not exclusive at all.
|
|
| 134 |
# is not exclusive at all. |
|
| 116 | 135 |
tmp_time = revision.time.clone |
| 117 | 136 |
unless changes.find_by_path_and_revision( |
| 118 |
scm.with_leading_slash(revision.paths[0][:path]), revision.paths[0][:revision]) |
|
| 137 |
scm.with_leading_slash(revision.paths[0][:path]), |
|
| 138 |
revision.paths[0][:revision] |
|
| 139 |
) |
|
| 119 | 140 |
cmt = Changeset.normalize_comments(revision.message, repo_log_encoding) |
| 120 |
cs = changesets.find(:first, :conditions=>{
|
|
| 121 |
:committed_on=>tmp_time - time_delta .. tmp_time + time_delta, |
|
| 122 |
:committer=>revision.author, |
|
| 123 |
:comments=>cmt |
|
| 124 |
}) |
|
| 125 |
|
|
| 126 |
# create a new changeset.... |
|
| 141 |
author_utf8 = Changeset.to_utf8(revision.author, repo_log_encoding) |
|
| 142 |
cs = changesets.find( |
|
| 143 |
:first, |
|
| 144 |
:conditions => {
|
|
| 145 |
:committed_on => tmp_time - time_delta .. tmp_time + time_delta, |
|
| 146 |
:committer => author_utf8, |
|
| 147 |
:comments => cmt |
|
| 148 |
} |
|
| 149 |
) |
|
| 150 |
# create a new changeset.... |
|
| 127 | 151 |
unless cs |
| 128 | 152 |
# we use a temporaray revision number here (just for inserting) |
| 129 | 153 |
# later on, we calculate a continous positive number |
| 130 | 154 |
tmp_time2 = tmp_time.clone.gmtime |
| 131 |
branch = revision.paths[0][:branch] |
|
| 132 |
scmid = branch + "-" + tmp_time2.strftime("%Y%m%d-%H%M%S")
|
|
| 133 |
cs = Changeset.create(:repository => self, |
|
| 134 |
:revision => "tmp#{tmp_rev_num}",
|
|
| 135 |
:scmid => scmid, |
|
| 136 |
:committer => revision.author,
|
|
| 155 |
branch = revision.paths[0][:branch]
|
|
| 156 |
scmid = branch + "-" + tmp_time2.strftime("%Y%m%d-%H%M%S")
|
|
| 157 |
cs = Changeset.create(:repository => self,
|
|
| 158 |
:revision => "tmp#{tmp_rev_num}",
|
|
| 159 |
:scmid => scmid,
|
|
| 160 |
:committer => revision.author,
|
|
| 137 | 161 |
:committed_on => tmp_time, |
| 138 |
:comments => revision.message) |
|
| 162 |
:comments => revision.message)
|
|
| 139 | 163 |
tmp_rev_num += 1 |
| 140 | 164 |
end |
| 141 |
|
|
| 142 |
#convert CVS-File-States to internal Action-abbrevations |
|
| 143 |
#default action is (M)odified |
|
| 144 |
action="M" |
|
| 145 |
if revision.paths[0][:action]=="Exp" && revision.paths[0][:revision]=="1.1" |
|
| 146 |
action="A" #add-action always at first revision (= 1.1) |
|
| 147 |
elsif revision.paths[0][:action]=="dead" |
|
| 148 |
action="D" #dead-state is similar to Delete |
|
| 165 |
# convert CVS-File-States to internal Action-abbrevations |
|
| 166 |
# default action is (M)odified |
|
| 167 |
action = "M" |
|
| 168 |
if revision.paths[0][:action] == "Exp" && revision.paths[0][:revision] == "1.1" |
|
| 169 |
action = "A" # add-action always at first revision (= 1.1) |
|
| 170 |
elsif revision.paths[0][:action] == "dead" |
|
| 171 |
action = "D" # dead-state is similar to Delete |
|
| 149 | 172 |
end |
| 150 |
|
|
| 151 |
Change.create(:changeset => cs,
|
|
| 152 |
:action => action,
|
|
| 153 |
:path => scm.with_leading_slash(revision.paths[0][:path]),
|
|
| 154 |
:revision => revision.paths[0][:revision],
|
|
| 155 |
:branch => revision.paths[0][:branch]
|
|
| 156 |
) |
|
| 173 |
Change.create( |
|
| 174 |
:changeset => cs,
|
|
| 175 |
:action => action,
|
|
| 176 |
:path => scm.with_leading_slash(revision.paths[0][:path]),
|
|
| 177 |
:revision => revision.paths[0][:revision],
|
|
| 178 |
:branch => revision.paths[0][:branch]
|
|
| 179 |
)
|
|
| 157 | 180 |
end |
| 158 | 181 |
end |
Also available in: Unified diff