Commit 76a4cbe464a4472e82065c670d1190552db67cc6

Authored by Dmitriy Zaporozhets
2 parents 273741fb 8a6bf09a

Merge branch 'refactor/gitlab_git'

Showing 72 changed files with 918 additions and 836 deletions   Show diff stats
app/contexts/commit_load_context.rb
@@ -12,7 +12,6 @@ class CommitLoadContext < BaseContext @@ -12,7 +12,6 @@ class CommitLoadContext < BaseContext
12 commit = project.repository.commit(params[:id]) 12 commit = project.repository.commit(params[:id])
13 13
14 if commit 14 if commit
15 - commit = CommitDecorator.decorate(commit)  
16 line_notes = project.notes.for_commit_id(commit.id).inline 15 line_notes = project.notes.for_commit_id(commit.id).inline
17 16
18 result[:commit] = commit 17 result[:commit] = commit
app/controllers/blame_controller.rb
@@ -8,7 +8,6 @@ class BlameController < ProjectResourceController @@ -8,7 +8,6 @@ class BlameController < ProjectResourceController
8 before_filter :require_non_empty_project 8 before_filter :require_non_empty_project
9 9
10 def show 10 def show
11 - @repo = @project.repo  
12 - @blame = Grit::Blob.blame(@repo, @commit.id, @path) 11 + @blame = Gitlab::Git::Blame.new(project.repository, @commit.id, @path)
13 end 12 end
14 end 13 end
app/controllers/commits_controller.rb
@@ -13,7 +13,6 @@ class CommitsController < ProjectResourceController @@ -13,7 +13,6 @@ class CommitsController < ProjectResourceController
13 @limit, @offset = (params[:limit] || 40), (params[:offset] || 0) 13 @limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
14 14
15 @commits = @repo.commits(@ref, @path, @limit, @offset) 15 @commits = @repo.commits(@ref, @path, @limit, @offset)
16 - @commits = CommitDecorator.decorate_collection(@commits)  
17 16
18 respond_to do |format| 17 respond_to do |format|
19 format.html # index.html.erb 18 format.html # index.html.erb
app/controllers/compare_controller.rb
@@ -8,15 +8,13 @@ class CompareController < ProjectResourceController @@ -8,15 +8,13 @@ class CompareController < ProjectResourceController
8 end 8 end
9 9
10 def show 10 def show
11 - result = Commit.compare(project, params[:from], params[:to]) 11 + compare = Gitlab::Git::Compare.new(project.repository, params[:from], params[:to])
12 12
13 - @commits = result[:commits]  
14 - @commit = result[:commit]  
15 - @diffs = result[:diffs]  
16 - @refs_are_same = result[:same] 13 + @commits = compare.commits
  14 + @commit = compare.commit
  15 + @diffs = compare.diffs
  16 + @refs_are_same = compare.same
17 @line_notes = [] 17 @line_notes = []
18 -  
19 - @commits = CommitDecorator.decorate_collection(@commits)  
20 end 18 end
21 19
22 def create 20 def create
app/controllers/merge_requests_controller.rb
@@ -94,12 +94,10 @@ class MergeRequestsController < ProjectResourceController @@ -94,12 +94,10 @@ class MergeRequestsController < ProjectResourceController
94 94
95 def branch_from 95 def branch_from
96 @commit = @repository.commit(params[:ref]) 96 @commit = @repository.commit(params[:ref])
97 - @commit = CommitDecorator.decorate(@commit)  
98 end 97 end
99 98
100 def branch_to 99 def branch_to
101 @commit = @repository.commit(params[:ref]) 100 @commit = @repository.commit(params[:ref])
102 - @commit = CommitDecorator.decorate(@commit)  
103 end 101 end
104 102
105 def ci_status 103 def ci_status
@@ -143,7 +141,6 @@ class MergeRequestsController < ProjectResourceController @@ -143,7 +141,6 @@ class MergeRequestsController < ProjectResourceController
143 # Get commits from repository 141 # Get commits from repository
144 # or from cache if already merged 142 # or from cache if already merged
145 @commits = @merge_request.commits 143 @commits = @merge_request.commits
146 - @commits = CommitDecorator.decorate_collection(@commits)  
147 144
148 @allowed_to_merge = allowed_to_merge? 145 @allowed_to_merge = allowed_to_merge?
149 @show_merge_controls = @merge_request.opened? && @commits.any? && @allowed_to_merge 146 @show_merge_controls = @merge_request.opened? && @commits.any? && @allowed_to_merge
app/controllers/refs_controller.rb
@@ -34,7 +34,6 @@ class RefsController < ProjectResourceController @@ -34,7 +34,6 @@ class RefsController < ProjectResourceController
34 @logs = contents.map do |content| 34 @logs = contents.map do |content|
35 file = params[:path] ? File.join(params[:path], content.name) : content.name 35 file = params[:path] ? File.join(params[:path], content.name) : content.name
36 last_commit = @repo.commits(@commit.id, file, 1).last 36 last_commit = @repo.commits(@commit.id, file, 1).last
37 - last_commit = CommitDecorator.decorate(last_commit)  
38 { 37 {
39 file_name: content.name, 38 file_name: content.name,
40 commit: last_commit 39 commit: last_commit
@@ -49,9 +48,7 @@ class RefsController < ProjectResourceController @@ -49,9 +48,7 @@ class RefsController < ProjectResourceController
49 48
50 @repo = project.repository 49 @repo = project.repository
51 @commit = @repo.commit(@ref) 50 @commit = @repo.commit(@ref)
52 - @commit = CommitDecorator.decorate(@commit)  
53 @tree = Tree.new(@commit.tree, @ref, params[:path]) 51 @tree = Tree.new(@commit.tree, @ref, params[:path])
54 - @tree = TreeDecorator.new(@tree)  
55 @hex_path = Digest::SHA1.hexdigest(params[:path] || "") 52 @hex_path = Digest::SHA1.hexdigest(params[:path] || "")
56 53
57 if params[:path] 54 if params[:path]
app/decorators/commit_decorator.rb
@@ -1,93 +0,0 @@ @@ -1,93 +0,0 @@
1 -class CommitDecorator < ApplicationDecorator  
2 - decorates :commit  
3 -  
4 - # Returns a string describing the commit for use in a link title  
5 - #  
6 - # Example  
7 - #  
8 - # "Commit: Alex Denisov - Project git clone panel"  
9 - def link_title  
10 - "Commit: #{author_name} - #{title}"  
11 - end  
12 -  
13 - # Returns the commits title.  
14 - #  
15 - # Usually, the commit title is the first line of the commit message.  
16 - # In case this first line is longer than 80 characters, it is cut off  
17 - # after 70 characters and ellipses (`&hellp;`) are appended.  
18 - def title  
19 - title = safe_message  
20 -  
21 - return no_commit_message if title.blank?  
22 -  
23 - title_end = title.index(/\n/)  
24 - if (!title_end && title.length > 80) || (title_end && title_end > 80)  
25 - title[0..69] << "&hellip;".html_safe  
26 - else  
27 - title.split(/\n/, 2).first  
28 - end  
29 - end  
30 -  
31 - # Returns the commits description  
32 - #  
33 - # cut off, ellipses (`&hellp;`) are prepended to the commit message.  
34 - def description  
35 - description = safe_message  
36 -  
37 - title_end = description.index(/\n/)  
38 - if (!title_end && description.length > 80) || (title_end && title_end > 80)  
39 - "&hellip;".html_safe << description[70..-1]  
40 - else  
41 - description.split(/\n/, 2)[1].try(:chomp)  
42 - end  
43 - end  
44 -  
45 - # Returns a link to the commit author. If the author has a matching user and  
46 - # is a member of the current @project it will link to the team member page.  
47 - # Otherwise it will link to the author email as specified in the commit.  
48 - #  
49 - # options:  
50 - # avatar: true will prepend the avatar image  
51 - # size: size of the avatar image in px  
52 - def author_link(options = {})  
53 - person_link(options.merge source: :author)  
54 - end  
55 -  
56 - # Just like #author_link but for the committer.  
57 - def committer_link(options = {})  
58 - person_link(options.merge source: :committer)  
59 - end  
60 -  
61 - protected  
62 -  
63 - def no_commit_message  
64 - "--no commit message"  
65 - end  
66 -  
67 - # Private: Returns a link to a person. If the person has a matching user and  
68 - # is a member of the current @project it will link to the team member page.  
69 - # Otherwise it will link to the person email as specified in the commit.  
70 - #  
71 - # options:  
72 - # source: one of :author or :committer  
73 - # avatar: true will prepend the avatar image  
74 - # size: size of the avatar image in px  
75 - def person_link(options = {})  
76 - source_name = send "#{options[:source]}_name".to_sym  
77 - source_email = send "#{options[:source]}_email".to_sym  
78 - text = if options[:avatar]  
79 - avatar = h.image_tag h.gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: ""  
80 - %Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}  
81 - else  
82 - source_name  
83 - end  
84 -  
85 - user = User.where('name like ? or email like ?', source_name, source_email).first  
86 -  
87 - if user.nil?  
88 - h.mail_to(source_email, text.html_safe, class: "commit-#{options[:source]}-link")  
89 - else  
90 - h.link_to(text.html_safe, h.user_path(user), class: "commit-#{options[:source]}-link")  
91 - end  
92 - end  
93 -end  
app/decorators/tree_decorator.rb
@@ -1,33 +0,0 @@ @@ -1,33 +0,0 @@
1 -class TreeDecorator < ApplicationDecorator  
2 - decorates :tree  
3 -  
4 - def breadcrumbs(max_links = 2)  
5 - if path  
6 - part_path = ""  
7 - parts = path.split("\/")  
8 -  
9 - yield('..', nil) if parts.count > max_links  
10 -  
11 - parts.each do |part|  
12 - part_path = File.join(part_path, part) unless part_path.empty?  
13 - part_path = part if part_path.empty?  
14 -  
15 - next unless parts.last(2).include?(part) if parts.count > max_links  
16 - yield(part, h.tree_join(ref, part_path))  
17 - end  
18 - end  
19 - end  
20 -  
21 - def up_dir?  
22 - path.present?  
23 - end  
24 -  
25 - def up_dir_path  
26 - file = File.join(path, "..")  
27 - h.tree_join(ref, file)  
28 - end  
29 -  
30 - def readme  
31 - @readme ||= contents.find { |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }  
32 - end  
33 -end  
app/helpers/application_helper.rb
@@ -96,7 +96,7 @@ module ApplicationHelper @@ -96,7 +96,7 @@ module ApplicationHelper
96 ] 96 ]
97 97
98 project_nav = [] 98 project_nav = []
99 - if @project && @project.repository && @project.repository.root_ref 99 + if @project && @project.repository.exists? && @project.repository.root_ref
100 project_nav = [ 100 project_nav = [
101 { label: "#{simple_sanitize(@project.name_with_namespace)} - Issues", url: project_issues_path(@project) }, 101 { label: "#{simple_sanitize(@project.name_with_namespace)} - Issues", url: project_issues_path(@project) },
102 { label: "#{simple_sanitize(@project.name_with_namespace)} - Commits", url: project_commits_path(@project, @ref || @project.repository.root_ref) }, 102 { label: "#{simple_sanitize(@project.name_with_namespace)} - Commits", url: project_commits_path(@project, @ref || @project.repository.root_ref) },
app/helpers/commits_helper.rb
1 module CommitsHelper 1 module CommitsHelper
  2 + # Returns a link to the commit author. If the author has a matching user and
  3 + # is a member of the current @project it will link to the team member page.
  4 + # Otherwise it will link to the author email as specified in the commit.
  5 + #
  6 + # options:
  7 + # avatar: true will prepend the avatar image
  8 + # size: size of the avatar image in px
  9 + def commit_author_link(commit, options = {})
  10 + commit_person_link(commit, options.merge(source: :author))
  11 + end
  12 +
  13 + # Just like #author_link but for the committer.
  14 + def commit_committer_link(commit, options = {})
  15 + commit_person_link(commit, options.merge(source: :committer))
  16 + end
  17 +
2 def identification_type(line) 18 def identification_type(line)
3 if line[0] == "+" 19 if line[0] == "+"
4 "new" 20 "new"
@@ -93,9 +109,7 @@ module CommitsHelper @@ -93,9 +109,7 @@ module CommitsHelper
93 end 109 end
94 110
95 def commit_to_html commit 111 def commit_to_html commit
96 - if commit.model  
97 - escape_javascript(render 'commits/commit', commit: commit)  
98 - end 112 + escape_javascript(render 'commits/commit', commit: commit)
99 end 113 end
100 114
101 def diff_line_content(line) 115 def diff_line_content(line)
@@ -105,4 +119,58 @@ module CommitsHelper @@ -105,4 +119,58 @@ module CommitsHelper
105 line 119 line
106 end 120 end
107 end 121 end
  122 +
  123 + # Breadcrumb links for a Project and, if applicable, a tree path
  124 + def commits_breadcrumbs
  125 + return unless @project && @ref
  126 +
  127 + # Add the root project link and the arrow icon
  128 + crumbs = content_tag(:li) do
  129 + content_tag(:span, nil, class: 'arrow') +
  130 + link_to(@project.name, project_commits_path(@project, @ref))
  131 + end
  132 +
  133 + if @path
  134 + parts = @path.split('/')
  135 +
  136 + parts.each_with_index do |part, i|
  137 + crumbs += content_tag(:span, '/', class: 'divider')
  138 + crumbs += content_tag(:li) do
  139 + # The text is just the individual part, but the link needs all the parts before it
  140 + link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/')))
  141 + end
  142 + end
  143 + end
  144 +
  145 + crumbs.html_safe
  146 + end
  147 +
  148 + protected
  149 +
  150 + # Private: Returns a link to a person. If the person has a matching user and
  151 + # is a member of the current @project it will link to the team member page.
  152 + # Otherwise it will link to the person email as specified in the commit.
  153 + #
  154 + # options:
  155 + # source: one of :author or :committer
  156 + # avatar: true will prepend the avatar image
  157 + # size: size of the avatar image in px
  158 + def commit_person_link(commit, options = {})
  159 + source_name = commit.send "#{options[:source]}_name".to_sym
  160 + source_email = commit.send "#{options[:source]}_email".to_sym
  161 + text = if options[:avatar]
  162 + avatar = image_tag(gravatar_icon(source_email, options[:size]), class: "avatar #{"s#{options[:size]}" if options[:size]}", width: options[:size], alt: "")
  163 + %Q{#{avatar} <span class="commit-#{options[:source]}-name">#{source_name}</span>}
  164 + else
  165 + source_name
  166 + end
  167 +
  168 + user = User.where('name like ? or email like ?', source_name, source_email).first
  169 +
  170 + if user.nil?
  171 + mail_to(source_email, text.html_safe, class: "commit-#{options[:source]}-link")
  172 + else
  173 + link_to(text.html_safe, user_path(user), class: "commit-#{options[:source]}-link")
  174 + end
  175 + end
108 end 176 end
app/helpers/tree_helper.rb
@@ -70,28 +70,26 @@ module TreeHelper @@ -70,28 +70,26 @@ module TreeHelper
70 end 70 end
71 end 71 end
72 72
73 - # Breadcrumb links for a Project and, if applicable, a tree path  
74 - def breadcrumbs  
75 - return unless @project && @ref  
76 -  
77 - # Add the root project link and the arrow icon  
78 - crumbs = content_tag(:li) do  
79 - content_tag(:span, nil, class: 'arrow') +  
80 - link_to(@project.name, project_commits_path(@project, @ref))  
81 - end 73 + def tree_breadcrumbs(tree, max_links = 2)
  74 + if tree.path
  75 + part_path = ""
  76 + parts = tree.path.split("\/")
  77 +
  78 + yield('..', nil) if parts.count > max_links
82 79
83 - if @path  
84 - parts = @path.split('/') 80 + parts.each do |part|
  81 + part_path = File.join(part_path, part) unless part_path.empty?
  82 + part_path = part if part_path.empty?
85 83
86 - parts.each_with_index do |part, i|  
87 - crumbs += content_tag(:span, '/', class: 'divider')  
88 - crumbs += content_tag(:li) do  
89 - # The text is just the individual part, but the link needs all the parts before it  
90 - link_to part, project_commits_path(@project, tree_join(@ref, parts[0..i].join('/')))  
91 - end 84 + next unless parts.last(2).include?(part) if parts.count > max_links
  85 + yield(part, tree_join(tree.ref, part_path))
92 end 86 end
93 end 87 end
  88 + end
94 89
95 - crumbs.html_safe 90 + def up_dir_path tree
  91 + file = File.join(tree.path, "..")
  92 + tree_join(tree.ref, file)
96 end 93 end
  94 +
97 end 95 end
app/mailers/emails/notes.rb
@@ -3,7 +3,6 @@ module Emails @@ -3,7 +3,6 @@ module Emails
3 def note_commit_email(recipient_id, note_id) 3 def note_commit_email(recipient_id, note_id)
4 @note = Note.find(note_id) 4 @note = Note.find(note_id)
5 @commit = @note.noteable 5 @commit = @note.noteable
6 - @commit = CommitDecorator.decorate(@commit)  
7 @project = @note.project 6 @project = @note.project
8 mail(to: recipient(recipient_id), subject: subject("note for commit #{@commit.short_id}", @commit.title)) 7 mail(to: recipient(recipient_id), subject: subject("note for commit #{@commit.short_id}", @commit.title))
9 end 8 end
app/models/commit.rb
@@ -8,174 +8,70 @@ class Commit @@ -8,174 +8,70 @@ class Commit
8 # 8 #
9 DIFF_SAFE_SIZE = 100 9 DIFF_SAFE_SIZE = 100
10 10
11 - attr_accessor :commit, :head, :refs  
12 -  
13 - delegate :message, :authored_date, :committed_date, :parents, :sha,  
14 - :date, :committer, :author, :diffs, :tree, :id, :stats,  
15 - :to_patch, to: :commit  
16 -  
17 - class << self  
18 - def find_or_first(repo, commit_id = nil, root_ref)  
19 - commit = if commit_id  
20 - repo.commit(commit_id)  
21 - else  
22 - repo.commits(root_ref).first  
23 - end  
24 -  
25 - Commit.new(commit) if commit  
26 - end  
27 -  
28 - def fresh_commits(repo, n = 10)  
29 - commits = repo.heads.map do |h|  
30 - repo.commits(h.name, n).map { |c| Commit.new(c, h) }  
31 - end.flatten.uniq { |c| c.id }  
32 -  
33 - commits.sort! do |x, y|  
34 - y.committed_date <=> x.committed_date  
35 - end  
36 -  
37 - commits[0...n]  
38 - end  
39 -  
40 - def commits_with_refs(repo, n = 20)  
41 - commits = repo.branches.map { |ref| Commit.new(ref.commit, ref) }  
42 -  
43 - commits.sort! do |x, y|  
44 - y.committed_date <=> x.committed_date  
45 - end  
46 -  
47 - commits[0..n]  
48 - end  
49 -  
50 - def commits_since(repo, date)  
51 - commits = repo.heads.map do |h|  
52 - repo.log(h.name, nil, since: date).each { |c| Commit.new(c, h) }  
53 - end.flatten.uniq { |c| c.id }  
54 -  
55 - commits.sort! do |x, y|  
56 - y.committed_date <=> x.committed_date  
57 - end  
58 -  
59 - commits  
60 - end  
61 -  
62 - def commits(repo, ref, path = nil, limit = nil, offset = nil)  
63 - if path  
64 - repo.log(ref, path, max_count: limit, skip: offset)  
65 - elsif limit && offset  
66 - repo.commits(ref, limit, offset)  
67 - else  
68 - repo.commits(ref)  
69 - end.map{ |c| Commit.new(c) }  
70 - end  
71 -  
72 - def commits_between(repo, from, to)  
73 - repo.commits_between(from, to).map { |c| Commit.new(c) }  
74 - end  
75 -  
76 - def compare(project, from, to)  
77 - result = {  
78 - commits: [],  
79 - diffs: [],  
80 - commit: nil,  
81 - same: false  
82 - }  
83 -  
84 - return result unless from && to  
85 -  
86 - first = project.repository.commit(to.try(:strip))  
87 - last = project.repository.commit(from.try(:strip))  
88 -  
89 - if first && last  
90 - result[:same] = (first.id == last.id)  
91 - result[:commits] = project.repo.commits_between(last.id, first.id).map {|c| Commit.new(c)}  
92 -  
93 - # Dont load diff for 100+ commits  
94 - result[:diffs] = if result[:commits].size > 100  
95 - []  
96 - else  
97 - project.repo.diff(last.id, first.id) rescue []  
98 - end  
99 -  
100 - result[:commit] = Commit.new(first)  
101 - end  
102 -  
103 - result  
104 - end  
105 - end  
106 -  
107 - def initialize(raw_commit, head = nil)  
108 - raise "Nil as raw commit passed" unless raw_commit  
109 -  
110 - @commit = raw_commit  
111 - @head = head  
112 - end  
113 -  
114 - def short_id(length = 10)  
115 - id.to_s[0..length] 11 + def self.decorate(commits)
  12 + commits.map { |c| self.new(c) }
116 end 13 end
117 14
118 - def safe_message  
119 - @safe_message ||= message  
120 - end  
121 -  
122 - def created_at  
123 - committed_date  
124 - end 15 + attr_accessor :raw
125 16
126 - def author_email  
127 - author.email  
128 - end 17 + def initialize(raw_commit)
  18 + raise "Nil as raw commit passed" unless raw_commit
129 19
130 - def author_name  
131 - author.name 20 + @raw = raw_commit
132 end 21 end
133 22
134 - # Was this commit committed by a different person than the original author?  
135 - def different_committer?  
136 - author_name != committer_name || author_email != committer_email 23 + def id
  24 + @raw.id
137 end 25 end
138 26
139 - def committer_name  
140 - committer.name 27 + # Returns a string describing the commit for use in a link title
  28 + #
  29 + # Example
  30 + #
  31 + # "Commit: Alex Denisov - Project git clone panel"
  32 + def link_title
  33 + "Commit: #{author_name} - #{title}"
141 end 34 end
142 35
143 - def committer_email  
144 - committer.email 36 + # Returns the commits title.
  37 + #
  38 + # Usually, the commit title is the first line of the commit message.
  39 + # In case this first line is longer than 80 characters, it is cut off
  40 + # after 70 characters and ellipses (`&hellp;`) are appended.
  41 + def title
  42 + title = safe_message
  43 +
  44 + return no_commit_message if title.blank?
  45 +
  46 + title_end = title.index(/\n/)
  47 + if (!title_end && title.length > 80) || (title_end && title_end > 80)
  48 + title[0..69] << "&hellip;".html_safe
  49 + else
  50 + title.split(/\n/, 2).first
  51 + end
145 end 52 end
146 53
147 - def prev_commit  
148 - @prev_commit ||= if parents.present?  
149 - Commit.new(parents.first)  
150 - else  
151 - nil  
152 - end 54 + # Returns the commits description
  55 + #
  56 + # cut off, ellipses (`&hellp;`) are prepended to the commit message.
  57 + def description
  58 + description = safe_message
  59 +
  60 + title_end = description.index(/\n/)
  61 + if (!title_end && description.length > 80) || (title_end && title_end > 80)
  62 + "&hellip;".html_safe << description[70..-1]
  63 + else
  64 + description.split(/\n/, 2)[1].try(:chomp)
  65 + end
153 end 66 end
154 67
155 - def prev_commit_id  
156 - prev_commit.try :id 68 + def method_missing(m, *args, &block)
  69 + @raw.send(m, *args, &block)
157 end 70 end
158 71
159 - # Shows the diff between the commit's parent and the commit.  
160 - #  
161 - # Cuts out the header and stats from #to_patch and returns only the diff.  
162 - def to_diff  
163 - # see Grit::Commit#show  
164 - patch = to_patch  
165 -  
166 - # discard lines before the diff  
167 - lines = patch.split("\n")  
168 - while !lines.first.start_with?("diff --git") do  
169 - lines.shift  
170 - end  
171 - lines.pop if lines.last =~ /^[\d.]+$/ # Git version  
172 - lines.pop if lines.last == "-- " # end of diff  
173 - lines.join("\n")  
174 - end 72 + def respond_to?(method)
  73 + return true if @raw.respond_to?(method)
175 74
176 - def has_zero_stats?  
177 - stats.total.zero?  
178 - rescue  
179 - true 75 + super
180 end 76 end
181 end 77 end
app/models/gollum_wiki.rb
@@ -50,7 +50,7 @@ class GollumWiki @@ -50,7 +50,7 @@ class GollumWiki
50 # Returns the last 30 Commit objects across the entire 50 # Returns the last 30 Commit objects across the entire
51 # repository. 51 # repository.
52 def recent_history 52 def recent_history
53 - Commit.fresh_commits(wiki.repo, 30) 53 + Gitlab::Git::Commit.fresh_commits(wiki.repo, 30)
54 end 54 end
55 55
56 # Finds a page within the repository based on a tile 56 # Finds a page within the repository based on a tile
@@ -90,13 +90,17 @@ class GollumWiki @@ -90,13 +90,17 @@ class GollumWiki
90 private 90 private
91 91
92 def create_repo! 92 def create_repo!
93 - if gitlab_shell.add_repository(path_with_namespace) 93 + if init_repo(path_with_namespace)
94 Gollum::Wiki.new(path_to_repo) 94 Gollum::Wiki.new(path_to_repo)
95 else 95 else
96 raise CouldNotCreateWikiError 96 raise CouldNotCreateWikiError
97 end 97 end
98 end 98 end
99 99
  100 + def init_repo(path_with_namespace)
  101 + gitlab_shell.add_repository(path_with_namespace)
  102 + end
  103 +
100 def commit_details(action, message = nil, title = nil) 104 def commit_details(action, message = nil, title = nil)
101 commit_message = message || default_message(action, title) 105 commit_message = message || default_message(action, title)
102 106
@@ -114,5 +118,4 @@ class GollumWiki @@ -114,5 +118,4 @@ class GollumWiki
114 def path_to_repo 118 def path_to_repo
115 @path_to_repo ||= File.join(Gitlab.config.gitlab_shell.repos_path, "#{path_with_namespace}.git") 119 @path_to_repo ||= File.join(Gitlab.config.gitlab_shell.repos_path, "#{path_with_namespace}.git")
116 end 120 end
117 -  
118 end 121 end
app/models/merge_request.rb
@@ -152,7 +152,17 @@ class MergeRequest &lt; ActiveRecord::Base @@ -152,7 +152,17 @@ class MergeRequest &lt; ActiveRecord::Base
152 end 152 end
153 153
154 def commits 154 def commits
155 - st_commits || [] 155 + if st_commits.present?
  156 + # check if merge request commits are valid
  157 + if st_commits.first.respond_to?(:short_id)
  158 + st_commits
  159 + else
  160 + # if commits are invalid - simply reload it from repo
  161 + reloaded_commits
  162 + end
  163 + else
  164 + []
  165 + end
156 end 166 end
157 167
158 def probably_merged? 168 def probably_merged?
@@ -169,9 +179,8 @@ class MergeRequest &lt; ActiveRecord::Base @@ -169,9 +179,8 @@ class MergeRequest &lt; ActiveRecord::Base
169 end 179 end
170 180
171 def unmerged_commits 181 def unmerged_commits
172 - self.project.repo. 182 + self.project.repository.
173 commits_between(self.target_branch, self.source_branch). 183 commits_between(self.target_branch, self.source_branch).
174 - map {|c| Commit.new(c)}.  
175 sort_by(&:created_at). 184 sort_by(&:created_at).
176 reverse 185 reverse
177 end 186 end
app/models/network/commit.rb
@@ -8,7 +8,7 @@ module Network @@ -8,7 +8,7 @@ module Network
8 attr_accessor :time, :spaces, :parent_spaces 8 attr_accessor :time, :spaces, :parent_spaces
9 9
10 def initialize(raw_commit, refs) 10 def initialize(raw_commit, refs)
11 - @commit = ::Commit.new(raw_commit) 11 + @commit = Gitlab::Git::Commit.new(raw_commit)
12 @time = -1 12 @time = -1
13 @spaces = [] 13 @spaces = []
14 @parent_spaces = [] 14 @parent_spaces = []
app/models/project.rb
@@ -141,13 +141,7 @@ class Project &lt; ActiveRecord::Base @@ -141,13 +141,7 @@ class Project &lt; ActiveRecord::Base
141 end 141 end
142 142
143 def repository 143 def repository
144 - if path  
145 - @repository ||= Repository.new(path_with_namespace, default_branch)  
146 - else  
147 - nil  
148 - end  
149 - rescue Grit::NoSuchPathError  
150 - nil 144 + @repository ||= Repository.new(path_with_namespace, default_branch)
151 end 145 end
152 146
153 def saved? 147 def saved?
@@ -332,14 +326,14 @@ class Project &lt; ActiveRecord::Base @@ -332,14 +326,14 @@ class Project &lt; ActiveRecord::Base
332 end 326 end
333 327
334 def valid_repo? 328 def valid_repo?
335 - repo 329 + repository.exists?
336 rescue 330 rescue
337 errors.add(:path, "Invalid repository path") 331 errors.add(:path, "Invalid repository path")
338 false 332 false
339 end 333 end
340 334
341 def empty_repo? 335 def empty_repo?
342 - !repository || repository.empty? 336 + !repository.exists? || repository.empty?
343 end 337 end
344 338
345 def ensure_satellite_exists 339 def ensure_satellite_exists
@@ -363,7 +357,7 @@ class Project &lt; ActiveRecord::Base @@ -363,7 +357,7 @@ class Project &lt; ActiveRecord::Base
363 end 357 end
364 358
365 def repo_exists? 359 def repo_exists?
366 - @repo_exists ||= (repository && repository.branches.present?) 360 + @repo_exists ||= repository.exists?
367 rescue 361 rescue
368 @repo_exists = false 362 @repo_exists = false
369 end 363 end
app/models/repository.rb
1 class Repository 1 class Repository
2 - include Gitlab::Popen 2 + attr_accessor :raw_repository
3 3
4 - # Repository directory name with namespace direcotry  
5 - # Examples:  
6 - # gitlab/gitolite  
7 - # diaspora  
8 - #  
9 - attr_accessor :path_with_namespace  
10 -  
11 - # Grit repo object  
12 - attr_accessor :repo  
13 -  
14 - # Default branch in the repository  
15 - attr_accessor :root_ref  
16 -  
17 - def initialize(path_with_namespace, root_ref = 'master')  
18 - @root_ref = root_ref || "master"  
19 - @path_with_namespace = path_with_namespace  
20 -  
21 - # Init grit repo object  
22 - repo  
23 - end  
24 -  
25 - def raw  
26 - repo  
27 - end  
28 -  
29 - def path_to_repo  
30 - @path_to_repo ||= File.join(Gitlab.config.gitlab_shell.repos_path, "#{path_with_namespace}.git")  
31 - end  
32 -  
33 - def repo  
34 - @repo ||= Grit::Repo.new(path_to_repo)  
35 - end  
36 -  
37 - def commit(commit_id = nil)  
38 - Commit.find_or_first(repo, commit_id, root_ref) 4 + def initialize(path_with_namespace, default_branch)
  5 + @raw_repository = Gitlab::Git::Repository.new(path_with_namespace, default_branch)
  6 + rescue Gitlab::Git::Repository::NoRepository
  7 + nil
39 end 8 end
40 9
41 - def fresh_commits(n = 10)  
42 - Commit.fresh_commits(repo, n) 10 + def exists?
  11 + raw_repository
43 end 12 end
44 13
45 - def commits_with_refs(n = 20)  
46 - Commit.commits_with_refs(repo, n) 14 + def empty?
  15 + raw_repository.empty?
47 end 16 end
48 17
49 - def commits_since(date)  
50 - Commit.commits_since(repo, date) 18 + def commit(id = nil)
  19 + commit = raw_repository.commit(id)
  20 + commit = Commit.new(commit) if commit
  21 + commit
51 end 22 end
52 23
53 def commits(ref, path = nil, limit = nil, offset = nil) 24 def commits(ref, path = nil, limit = nil, offset = nil)
54 - Commit.commits(repo, ref, path, limit, offset)  
55 - end  
56 -  
57 - def last_commit_for(ref, path = nil)  
58 - commits(ref, path, 1).first  
59 - end  
60 -  
61 - def commits_between(from, to)  
62 - Commit.commits_between(repo, from, to) 25 + commits = raw_repository.commits(ref, path, limit, offset)
  26 + commits = Commit.decorate(commits) if commits.present?
  27 + commits
63 end 28 end
64 29
65 - # Returns an Array of branch names  
66 - # sorted by name ASC  
67 - def branch_names  
68 - branches.map(&:name) 30 + def commits_between(target, source)
  31 + commits = raw_repository.commits_between(target, source)
  32 + commits = Commit.decorate(commits) if commits.present?
  33 + commits
69 end 34 end
70 35
71 - # Returns an Array of Branches  
72 - def branches  
73 - repo.branches.sort_by(&:name) 36 + def method_missing(m, *args, &block)
  37 + raw_repository.send(m, *args, &block)
74 end 38 end
75 39
76 - # Returns an Array of tag names  
77 - def tag_names  
78 - repo.tags.collect(&:name).sort.reverse  
79 - end  
80 -  
81 - # Returns an Array of Tags  
82 - def tags  
83 - repo.tags.sort_by(&:name).reverse  
84 - end  
85 -  
86 - # Returns an Array of branch and tag names  
87 - def ref_names  
88 - [branch_names + tag_names].flatten  
89 - end  
90 -  
91 - def heads  
92 - @heads ||= repo.heads  
93 - end  
94 -  
95 - def tree(fcommit, path = nil)  
96 - fcommit = commit if fcommit == :head  
97 - tree = fcommit.tree  
98 - path ? (tree / path) : tree  
99 - end  
100 -  
101 - def has_commits?  
102 - !!commit  
103 - rescue Grit::NoSuchPathError  
104 - false  
105 - end  
106 -  
107 - def empty?  
108 - !has_commits?  
109 - end  
110 -  
111 - # Discovers the default branch based on the repository's available branches  
112 - #  
113 - # - If no branches are present, returns nil  
114 - # - If one branch is present, returns its name  
115 - # - If two or more branches are present, returns the one that has a name  
116 - # matching root_ref (default_branch or 'master' if default_branch is nil)  
117 - def discover_default_branch  
118 - if branch_names.length == 0  
119 - nil  
120 - elsif branch_names.length == 1  
121 - branch_names.first  
122 - else  
123 - branch_names.select { |v| v == root_ref }.first  
124 - end  
125 - end  
126 -  
127 - # Archive Project to .tar.gz  
128 - #  
129 - # Already packed repo archives stored at  
130 - # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz  
131 - #  
132 - def archive_repo(ref)  
133 - ref = ref || self.root_ref  
134 - commit = self.commit(ref)  
135 - return nil unless commit  
136 -  
137 - # Build file path  
138 - file_name = self.path_with_namespace.gsub("/","_") + "-" + commit.id.to_s + ".tar.gz"  
139 - storage_path = Rails.root.join("tmp", "repositories")  
140 - file_path = File.join(storage_path, self.path_with_namespace, file_name)  
141 -  
142 - # Put files into a directory before archiving  
143 - prefix = File.basename(self.path_with_namespace) + "/"  
144 -  
145 - # Create file if not exists  
146 - unless File.exists?(file_path)  
147 - FileUtils.mkdir_p File.dirname(file_path)  
148 - file = self.repo.archive_to_file(ref, prefix, file_path)  
149 - end  
150 -  
151 - file_path  
152 - end  
153 -  
154 - # Return repo size in megabytes  
155 - # Cached in redis  
156 - def size  
157 - Rails.cache.fetch(cache_key(:size)) do  
158 - size = popen('du -s', path_to_repo).first.strip.to_i  
159 - (size.to_f / 1024).round(2)  
160 - end  
161 - end  
162 -  
163 - def expire_cache  
164 - Rails.cache.delete(cache_key(:size))  
165 - end 40 + def respond_to?(method)
  41 + return true if raw_repository.respond_to?(method)
166 42
167 - def cache_key(type)  
168 - "#{type}:#{path_with_namespace}" 43 + super
169 end 44 end
170 end 45 end
app/models/tree.rb
@@ -26,4 +26,12 @@ class Tree @@ -26,4 +26,12 @@ class Tree
26 def empty? 26 def empty?
27 data.blank? 27 data.blank?
28 end 28 end
  29 +
  30 + def up_dir?
  31 + path.present?
  32 + end
  33 +
  34 + def readme
  35 + @readme ||= contents.find { |c| c.is_a?(Grit::Blob) and c.name =~ /^readme/i }
  36 + end
29 end 37 end
app/models/wiki_page.rb
@@ -79,14 +79,14 @@ class WikiPage @@ -79,14 +79,14 @@ class WikiPage
79 def version 79 def version
80 return nil unless persisted? 80 return nil unless persisted?
81 81
82 - @version ||= Commit.new(@page.version) 82 + @version ||= Commit.new(Gitlab::Git::Commit.new(@page.version))
83 end 83 end
84 84
85 # Returns an array of Gitlab Commit instances. 85 # Returns an array of Gitlab Commit instances.
86 def versions 86 def versions
87 return [] unless persisted? 87 return [] unless persisted?
88 88
89 - @page.versions.map { |v| Commit.new(v) } 89 + @page.versions.map { |v| Commit.new(Gitlab::Git::Commit.new(v)) }
90 end 90 end
91 91
92 # Returns the Date that this latest version was 92 # Returns the Date that this latest version was
app/views/admin/projects/show.html.haml
@@ -46,18 +46,21 @@ @@ -46,18 +46,21 @@
46 %span.light ssh: 46 %span.light ssh:
47 %strong 47 %strong
48 = link_to @project.ssh_url_to_repo 48 = link_to @project.ssh_url_to_repo
49 - %li  
50 - %span.light fs:  
51 - %strong  
52 - = @repository.path_to_repo 49 + - if @project.repository.exists?
  50 + %li
  51 + %span.light fs:
  52 + %strong
  53 + = @repository.path_to_repo
53 54
54 - %li  
55 - %span.light last commit:  
56 - %strong  
57 - - if @repository 55 + %li
  56 + %span.light last commit:
  57 + %strong
58 = last_commit(@project) 58 = last_commit(@project)
59 - - else  
60 - never 59 + - else
  60 + %li
  61 + %span.light repository:
  62 + %strong.cred
  63 + does not exist
61 64
62 %li 65 %li
63 %span.light access: 66 %span.light access:
app/views/blame/show.html.haml
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 %i.icon-angle-right 6 %i.icon-angle-right
7 = link_to project_tree_path(@project, @ref) do 7 = link_to project_tree_path(@project, @ref) do
8 = @project.name 8 = @project.name
9 - - @tree.breadcrumbs(6) do |link| 9 + - tree_breadcrumbs(@tree, 6) do |link|
10 \/ 10 \/
11 %li= link 11 %li= link
12 .clear 12 .clear
@@ -22,13 +22,13 @@ @@ -22,13 +22,13 @@
22 %table 22 %table
23 - current_line = 1 23 - current_line = 1
24 - @blame.each do |commit, lines| 24 - @blame.each do |commit, lines|
25 - - commit = CommitDecorator.decorate(Commit.new(commit)) 25 + - commit = Commit.new(commit)
26 %tr 26 %tr
27 %td.blame-commit 27 %td.blame-commit
28 %span.commit 28 %span.commit
29 = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id" 29 = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
30 &nbsp; 30 &nbsp;
31 - = commit.author_link avatar: true, size: 16 31 + = commit_author_link(commit, avatar: true, size: 16)
32 &nbsp; 32 &nbsp;
33 = link_to_gfm truncate(commit.title, length: 20), project_commit_path(@project, commit.id), class: "row_title" 33 = link_to_gfm truncate(commit.title, length: 20), project_commit_path(@project, commit.id), class: "row_title"
34 %td.lines.blame-numbers 34 %td.lines.blame-numbers
app/views/commit/_commit_box.html.haml
@@ -24,14 +24,14 @@ @@ -24,14 +24,14 @@
24 .row 24 .row
25 .span5 25 .span5
26 .author 26 .author
27 - = @commit.author_link avatar: true, size: 32 27 + = commit_author_link(@commit, avatar: true, size: 32)
28 authored 28 authored
29 %time{title: @commit.authored_date.stamp("Aug 21, 2011 9:23pm")} 29 %time{title: @commit.authored_date.stamp("Aug 21, 2011 9:23pm")}
30 #{time_ago_in_words(@commit.authored_date)} ago 30 #{time_ago_in_words(@commit.authored_date)} ago
31 - if @commit.different_committer? 31 - if @commit.different_committer?
32 .committer 32 .committer
33 &rarr; 33 &rarr;
34 - = @commit.committer_link 34 + = commit_committer_link(@commit)
35 committed 35 committed
36 %time{title: @commit.committed_date.stamp("Aug 21, 2011 9:23pm")} 36 %time{title: @commit.committed_date.stamp("Aug 21, 2011 9:23pm")}
37 #{time_ago_in_words(@commit.committed_date)} ago 37 #{time_ago_in_words(@commit.committed_date)} ago
app/views/commits/_commit.html.haml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 %strong= link_to "Browse Code »", project_tree_path(@project, commit), class: "right" 4 %strong= link_to "Browse Code »", project_tree_path(@project, commit), class: "right"
5 %p 5 %p
6 = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id" 6 = link_to commit.short_id(8), project_commit_path(@project, commit), class: "commit_short_id"
7 - = commit.author_link avatar: true, size: 24 7 + = commit_author_link(commit, avatar: true, size: 24)
8 &nbsp; 8 &nbsp;
9 = link_to_gfm truncate(commit.title, length: 70), project_commit_path(@project, commit.id), class: "row_title" 9 = link_to_gfm truncate(commit.title, length: 70), project_commit_path(@project, commit.id), class: "row_title"
10 10
app/views/commits/show.html.haml
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 2
3 - if @path.present? 3 - if @path.present?
4 %ul.breadcrumb 4 %ul.breadcrumb
5 - = breadcrumbs 5 + = commits_breadcrumbs
6 6
7 %div{id: dom_id(@project)} 7 %div{id: dom_id(@project)}
8 #commits-list= render "commits" 8 #commits-list= render "commits"
app/views/compare/show.html.haml
@@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
16 %div.ui-box 16 %div.ui-box
17 %h5.title 17 %h5.title
18 Commits (#{@commits.count}) 18 Commits (#{@commits.count})
19 - %ul.well-list= render @commits 19 + %ul.well-list= render Commit.decorate(@commits)
20 20
21 - unless @diffs.empty? 21 - unless @diffs.empty?
22 %h4 Diff 22 %h4 Diff
app/views/events/_commit.html.haml
1 -- commit = CommitDecorator.decorate(commit)  
2 %li.commit 1 %li.commit
3 %p 2 %p
4 = link_to commit.short_id(8), project_commit_path(project, commit), class: "commit_short_id" 3 = link_to commit.short_id(8), project_commit_path(project, commit), class: "commit_short_id"
app/views/projects/_clone_panel.html.haml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 .form-horizontal= render "shared/clone_panel" 4 .form-horizontal= render "shared/clone_panel"
5 .span4.pull-right 5 .span4.pull-right
6 .pull-right 6 .pull-right
7 - - unless @project.empty_repo? 7 + - if @project.empty_repo?
8 - if can? current_user, :download_code, @project 8 - if can? current_user, :download_code, @project
9 = link_to archive_project_repository_path(@project), class: "btn-small btn grouped" do 9 = link_to archive_project_repository_path(@project), class: "btn-small btn grouped" do
10 %i.icon-download-alt 10 %i.icon-download-alt
app/views/repositories/_branch.html.haml
1 -- commit = Commit.new(branch.commit)  
2 -- commit = CommitDecorator.decorate(commit) 1 +- commit = Commit.new(Gitlab::Git::Commit.new(branch.commit))
3 %tr 2 %tr
4 %td 3 %td
5 = link_to project_commits_path(@project, branch.name) do 4 = link_to project_commits_path(@project, branch.name) do
app/views/repositories/_feed.html.haml
1 - commit = update 1 - commit = update
2 -- commit = CommitDecorator.new(commit)  
3 %tr 2 %tr
4 %td 3 %td
5 = link_to project_commits_path(@project, commit.head.name) do 4 = link_to project_commits_path(@project, commit.head.name) do
app/views/repositories/tags.html.haml
@@ -7,8 +7,7 @@ @@ -7,8 +7,7 @@
7 %th Last commit 7 %th Last commit
8 %th 8 %th
9 - @tags.each do |tag| 9 - @tags.each do |tag|
10 - - commit = Commit.new(tag.commit)  
11 - - commit = CommitDecorator.decorate(commit) 10 + - commit = Commit.new(Gitlab::Git::Commit.new(tag.commit))
12 %tr 11 %tr
13 %td 12 %td
14 %strong 13 %strong
app/views/tree/_tree.html.haml
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 %i.icon-angle-right 3 %i.icon-angle-right
4 = link_to project_tree_path(@project, @ref) do 4 = link_to project_tree_path(@project, @ref) do
5 = @project.path 5 = @project.path
6 - - tree.breadcrumbs(6) do |title, path| 6 + - tree_breadcrumbs(tree, 6) do |title, path|
7 \/ 7 \/
8 %li 8 %li
9 - if path 9 - if path
@@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
27 %tr.tree-item 27 %tr.tree-item
28 %td.tree-item-file-name 28 %td.tree-item-file-name
29 = image_tag "file_empty.png", size: '16x16' 29 = image_tag "file_empty.png", size: '16x16'
30 - = link_to "..", project_tree_path(@project, tree.up_dir_path) 30 + = link_to "..", project_tree_path(@project, up_dir_path(tree))
31 %td 31 %td
32 %td 32 %td
33 %td 33 %td
app/views/tree/_tree_commit_column.html.haml
1 -%span.tree_author= commit.author_link avatar: true 1 +%span.tree_author= commit_author_link(commit, avatar: true)
2 = link_to_gfm truncate(commit.title, length: 80), project_commit_path(@project, commit.id), class: "tree-commit-link" 2 = link_to_gfm truncate(commit.title, length: 80), project_commit_path(@project, commit.id), class: "tree-commit-link"
app/views/wikis/history.html.haml
@@ -14,12 +14,13 @@ @@ -14,12 +14,13 @@
14 %th Format 14 %th Format
15 %tbody 15 %tbody
16 - @wiki.versions.each do |version| 16 - @wiki.versions.each do |version|
17 - - commit = CommitDecorator.new(version) 17 + - commit = version
18 %tr 18 %tr
19 %td 19 %td
20 = link_to project_wiki_path(@project, @wiki, version_id: commit.id) do 20 = link_to project_wiki_path(@project, @wiki, version_id: commit.id) do
21 = commit.short_id 21 = commit.short_id
22 - %td= commit.author_link avatar: true, size: 24 22 + %td
  23 + = commit_author_link(commit, avatar: true, size: 24)
23 %td 24 %td
24 = commit.title 25 = commit.title
25 %td 26 %td
app/views/wikis/pages.html.haml
@@ -21,5 +21,5 @@ @@ -21,5 +21,5 @@
21 = wiki_page.created_at.to_s(:short) do 21 = wiki_page.created_at.to_s(:short) do
22 (#{time_ago_in_words(wiki_page.created_at)} 22 (#{time_ago_in_words(wiki_page.created_at)}
23 ago) 23 ago)
24 - - commit = CommitDecorator.decorate(wiki_page.version)  
25 - %td= commit.author_link avatar: true, size: 24 24 + %td
  25 + = commit_author_link(wiki_page.version, avatar: true, size: 24)
app/views/wikis/show.html.haml
@@ -13,5 +13,4 @@ @@ -13,5 +13,4 @@
13 = preserve do 13 = preserve do
14 = render_wiki_content(@wiki) 14 = render_wiki_content(@wiki)
15 15
16 -- commit = CommitDecorator.new(@wiki.version)  
17 -%p.time Last edited by #{commit.author_link(avatar: true, size: 16)} #{time_ago_in_words @wiki.created_at} ago 16 +%p.time Last edited by #{commit_author_link(@wiki.version, avatar: true, size: 16)} #{time_ago_in_words @wiki.created_at} ago
features/steps/project/project_browse_commits.rb
@@ -15,7 +15,7 @@ class ProjectBrowseCommits &lt; Spinach::FeatureSteps @@ -15,7 +15,7 @@ class ProjectBrowseCommits &lt; Spinach::FeatureSteps
15 end 15 end
16 16
17 Then 'I see commits atom feed' do 17 Then 'I see commits atom feed' do
18 - commit = CommitDecorator.decorate(@project.repository.commit) 18 + commit = @project.repository.commit
19 page.response_headers['Content-Type'].should have_content("application/atom+xml") 19 page.response_headers['Content-Type'].should have_content("application/atom+xml")
20 page.body.should have_selector("title", :text => "Recent commits to #{@project.name}") 20 page.body.should have_selector("title", :text => "Recent commits to #{@project.name}")
21 page.body.should have_selector("author email", :text => commit.author_email) 21 page.body.should have_selector("author email", :text => commit.author_email)
features/steps/shared/project.rb
@@ -3,14 +3,14 @@ module SharedProject @@ -3,14 +3,14 @@ module SharedProject
3 3
4 # Create a project without caring about what it's called 4 # Create a project without caring about what it's called
5 And "I own a project" do 5 And "I own a project" do
6 - @project = create(:project) 6 + @project = create(:project_with_code)
7 @project.team << [@user, :master] 7 @project.team << [@user, :master]
8 end 8 end
9 9
10 # Create a specific project called "Shop" 10 # Create a specific project called "Shop"
11 And 'I own project "Shop"' do 11 And 'I own project "Shop"' do
12 @project = Project.find_by_name "Shop" 12 @project = Project.find_by_name "Shop"
13 - @project ||= create(:project, name: "Shop") 13 + @project ||= create(:project_with_code, name: "Shop")
14 @project.team << [@user, :master] 14 @project.team << [@user, :master]
15 end 15 end
16 16
features/steps/userteams/userteams.rb
@@ -132,7 +132,7 @@ class Userteams &lt; Spinach::FeatureSteps @@ -132,7 +132,7 @@ class Userteams &lt; Spinach::FeatureSteps
132 team = UserTeam.last 132 team = UserTeam.last
133 team.projects.each do |project| 133 team.projects.each do |project|
134 team.members.each do |member| 134 team.members.each do |member|
135 - 3.times { project.merge_requests << create(:merge_request, assignee: member) } 135 + 3.times { create(:merge_request, assignee: member, project: project) }
136 end 136 end
137 end 137 end
138 end 138 end
@@ -157,7 +157,7 @@ class Userteams &lt; Spinach::FeatureSteps @@ -157,7 +157,7 @@ class Userteams &lt; Spinach::FeatureSteps
157 team = UserTeam.last 157 team = UserTeam.last
158 team.projects.each do |project| 158 team.projects.each do |project|
159 team.members.each do |member| 159 team.members.each do |member|
160 - 3.times { project.merge_requests << create(:merge_request, assignee: member) } 160 + 3.times { create(:merge_request, assignee: member, project: project) }
161 end 161 end
162 end 162 end
163 end 163 end
features/support/env.rb
@@ -14,7 +14,7 @@ require &#39;spinach/capybara&#39; @@ -14,7 +14,7 @@ require &#39;spinach/capybara&#39;
14 require 'sidekiq/testing/inline' 14 require 'sidekiq/testing/inline'
15 15
16 16
17 -%w(stubbed_repository valid_commit select2_helper).each do |f| 17 +%w(valid_commit select2_helper test_env).each do |f|
18 require Rails.root.join('spec', 'support', f) 18 require Rails.root.join('spec', 'support', f)
19 end 19 end
20 20
@@ -35,13 +35,8 @@ Capybara.default_wait_time = 10 @@ -35,13 +35,8 @@ Capybara.default_wait_time = 10
35 DatabaseCleaner.strategy = :truncation 35 DatabaseCleaner.strategy = :truncation
36 36
37 Spinach.hooks.before_scenario do 37 Spinach.hooks.before_scenario do
38 - # Use tmp dir for FS manipulations  
39 - Gitlab.config.gitlab_shell.stub(repos_path: Rails.root.join('tmp', 'test-git-base-path'))  
40 - Gitlab::Shell.any_instance.stub(:add_repository) do |path|  
41 - create_temp_repo("#{Rails.root}/tmp/test-git-base-path/#{path}.git")  
42 - end  
43 - FileUtils.rm_rf Gitlab.config.gitlab_shell.repos_path  
44 - FileUtils.mkdir_p Gitlab.config.gitlab_shell.repos_path 38 + TestEnv.init
  39 +
45 DatabaseCleaner.start 40 DatabaseCleaner.start
46 end 41 end
47 42
@@ -54,9 +49,3 @@ Spinach.hooks.before_run do @@ -54,9 +49,3 @@ Spinach.hooks.before_run do
54 49
55 include FactoryGirl::Syntax::Methods 50 include FactoryGirl::Syntax::Methods
56 end 51 end
57 -  
58 -def create_temp_repo(path)  
59 - FileUtils.mkdir_p path  
60 - command = "git init --quiet --bare #{path};"  
61 - system(command)  
62 -end  
lib/api/projects.rb
@@ -372,7 +372,7 @@ module Gitlab @@ -372,7 +372,7 @@ module Gitlab
372 ref = params[:ref_name] || user_project.try(:default_branch) || 'master' 372 ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
373 373
374 commits = user_project.repository.commits(ref, nil, per_page, page * per_page) 374 commits = user_project.repository.commits(ref, nil, per_page, page * per_page)
375 - present CommitDecorator.decorate(commits), with: Entities::RepoCommit 375 + present commits, with: Entities::RepoCommit
376 end 376 end
377 377
378 # Get a project snippets 378 # Get a project snippets
lib/extracts_path.rb
@@ -85,8 +85,8 @@ module ExtractsPath @@ -85,8 +85,8 @@ module ExtractsPath
85 # - @id - A string representing the joined ref and path 85 # - @id - A string representing the joined ref and path
86 # - @ref - A string representing the ref (e.g., the branch, tag, or commit SHA) 86 # - @ref - A string representing the ref (e.g., the branch, tag, or commit SHA)
87 # - @path - A string representing the filesystem path 87 # - @path - A string representing the filesystem path
88 - # - @commit - A CommitDecorator representing the commit from the given ref  
89 - # - @tree - A TreeDecorator representing the tree at the given ref/path 88 + # - @commit - A Commit representing the commit from the given ref
  89 + # - @tree - A Tree representing the tree at the given ref/path
90 # 90 #
91 # If the :id parameter appears to be requesting a specific response format, 91 # If the :id parameter appears to be requesting a specific response format,
92 # that will be handled as well. 92 # that will be handled as well.
@@ -100,11 +100,9 @@ module ExtractsPath @@ -100,11 +100,9 @@ module ExtractsPath
100 100
101 # It is used "@project.repository.commits(@ref, @path, 1, 0)", 101 # It is used "@project.repository.commits(@ref, @path, 1, 0)",
102 # because "@project.repository.commit(@ref)" returns wrong commit when @ref is tag name. 102 # because "@project.repository.commit(@ref)" returns wrong commit when @ref is tag name.
103 - commits = @project.repository.commits(@ref, @path, 1, 0)  
104 - @commit = CommitDecorator.decorate(commits.first) 103 + @commit = @project.repository.commits(@ref, @path, 1, 0).first
105 104
106 @tree = Tree.new(@commit.tree, @ref, @path) 105 @tree = Tree.new(@commit.tree, @ref, @path)
107 - @tree = TreeDecorator.new(@tree)  
108 106
109 raise InvalidPathError if @tree.invalid? 107 raise InvalidPathError if @tree.invalid?
110 rescue RuntimeError, NoMethodError, InvalidPathError 108 rescue RuntimeError, NoMethodError, InvalidPathError
lib/gitlab/git/blame.rb 0 → 100644
@@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
  1 +module Gitlab
  2 + module Git
  3 + class Blame
  4 +
  5 + attr_accessor :repository, :sha, :path
  6 +
  7 + def initialize(repository, sha, path)
  8 + @repository, @sha, @path = repository, sha, path
  9 +
  10 + end
  11 +
  12 + def each
  13 + raw_blame = Grit::Blob.blame(repository.repo, sha, path)
  14 +
  15 + raw_blame.each do |commit, lines|
  16 + commit = Gitlab::Git::Commit.new(commit)
  17 + yield(commit, lines)
  18 + end
  19 + end
  20 + end
  21 + end
  22 +end
lib/gitlab/git/commit.rb 0 → 100644
@@ -0,0 +1,153 @@ @@ -0,0 +1,153 @@
  1 +# Gitlab::Git::Commit is a wrapper around native Grit::Commit object
  2 +# We dont want to use grit objects inside app/
  3 +# It helps us easily migrate to rugged in future
  4 +module Gitlab
  5 + module Git
  6 + class Commit
  7 + attr_accessor :raw_commit, :head, :refs
  8 +
  9 + delegate :message, :authored_date, :committed_date, :parents, :sha,
  10 + :date, :committer, :author, :diffs, :tree, :id, :stats, :to_patch,
  11 + to: :raw_commit
  12 +
  13 + class << self
  14 + def find_or_first(repo, commit_id = nil, root_ref)
  15 + commit = if commit_id
  16 + repo.commit(commit_id)
  17 + else
  18 + repo.commits(root_ref).first
  19 + end
  20 +
  21 + Commit.new(commit) if commit
  22 + end
  23 +
  24 + def fresh_commits(repo, n = 10)
  25 + commits = repo.heads.map do |h|
  26 + repo.commits(h.name, n).map { |c| Commit.new(c, h) }
  27 + end.flatten.uniq { |c| c.id }
  28 +
  29 + commits.sort! do |x, y|
  30 + y.committed_date <=> x.committed_date
  31 + end
  32 +
  33 + commits[0...n]
  34 + end
  35 +
  36 + def commits_with_refs(repo, n = 20)
  37 + commits = repo.branches.map { |ref| Commit.new(ref.commit, ref) }
  38 +
  39 + commits.sort! do |x, y|
  40 + y.committed_date <=> x.committed_date
  41 + end
  42 +
  43 + commits[0..n]
  44 + end
  45 +
  46 + def commits_since(repo, date)
  47 + commits = repo.heads.map do |h|
  48 + repo.log(h.name, nil, since: date).each { |c| Commit.new(c, h) }
  49 + end.flatten.uniq { |c| c.id }
  50 +
  51 + commits.sort! do |x, y|
  52 + y.committed_date <=> x.committed_date
  53 + end
  54 +
  55 + commits
  56 + end
  57 +
  58 + def commits(repo, ref, path = nil, limit = nil, offset = nil)
  59 + if path
  60 + repo.log(ref, path, max_count: limit, skip: offset)
  61 + elsif limit && offset
  62 + repo.commits(ref, limit, offset)
  63 + else
  64 + repo.commits(ref)
  65 + end.map{ |c| Commit.new(c) }
  66 + end
  67 +
  68 + def commits_between(repo, from, to)
  69 + repo.commits_between(from, to).map { |c| Commit.new(c) }
  70 + end
  71 + end
  72 +
  73 + def initialize(raw_commit, head = nil)
  74 + raise "Nil as raw commit passed" unless raw_commit
  75 +
  76 + @raw_commit = raw_commit
  77 + @head = head
  78 + end
  79 +
  80 + def short_id(length = 10)
  81 + id.to_s[0..length]
  82 + end
  83 +
  84 + def safe_message
  85 + @safe_message ||= message
  86 + end
  87 +
  88 + def created_at
  89 + committed_date
  90 + end
  91 +
  92 + def author_email
  93 + author.email
  94 + end
  95 +
  96 + def author_name
  97 + author.name
  98 + end
  99 +
  100 + # Was this commit committed by a different person than the original author?
  101 + def different_committer?
  102 + author_name != committer_name || author_email != committer_email
  103 + end
  104 +
  105 + def committer_name
  106 + committer.name
  107 + end
  108 +
  109 + def committer_email
  110 + committer.email
  111 + end
  112 +
  113 + def prev_commit
  114 + @prev_commit ||= if parents.present?
  115 + Commit.new(parents.first)
  116 + else
  117 + nil
  118 + end
  119 + end
  120 +
  121 + def prev_commit_id
  122 + prev_commit.try :id
  123 + end
  124 +
  125 + # Shows the diff between the commit's parent and the commit.
  126 + #
  127 + # Cuts out the header and stats from #to_patch and returns only the diff.
  128 + def to_diff
  129 + # see Grit::Commit#show
  130 + patch = to_patch
  131 +
  132 + # discard lines before the diff
  133 + lines = patch.split("\n")
  134 + while !lines.first.start_with?("diff --git") do
  135 + lines.shift
  136 + end
  137 + lines.pop if lines.last =~ /^[\d.]+$/ # Git version
  138 + lines.pop if lines.last == "-- " # end of diff
  139 + lines.join("\n")
  140 + end
  141 +
  142 + def has_zero_stats?
  143 + stats.total.zero?
  144 + rescue
  145 + true
  146 + end
  147 +
  148 + def no_commit_message
  149 + "--no commit message"
  150 + end
  151 + end
  152 + end
  153 +end
lib/gitlab/git/compare.rb 0 → 100644
@@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
  1 +module Gitlab
  2 + module Git
  3 + class Compare
  4 + attr_accessor :commits, :commit, :diffs, :same
  5 +
  6 + def initialize(repository, from, to)
  7 + @commits, @diffs = [], []
  8 + @commit = nil
  9 + @same = false
  10 +
  11 + return unless from && to
  12 +
  13 + first = repository.commit(to.try(:strip))
  14 + last = repository.commit(from.try(:strip))
  15 +
  16 + return unless first && last
  17 +
  18 + if first.id == last.id
  19 + @same = true
  20 + return
  21 + end
  22 +
  23 + @commit = Commit.new(first)
  24 +
  25 + @commits = repository.commits_between(last.id, first.id)
  26 + @commits = @commits.map { |c| Commit.new(c) }
  27 +
  28 + @diffs = if @commits.size > 100
  29 + []
  30 + else
  31 + repository.repo.diff(last.id, first.id) rescue []
  32 + end
  33 + end
  34 + end
  35 + end
  36 +end
  37 +
lib/gitlab/git/repository.rb 0 → 100644
@@ -0,0 +1,185 @@ @@ -0,0 +1,185 @@
  1 +# Gitlab::Git::Gitlab::Git::Commit is a wrapper around native Grit::Repository object
  2 +# We dont want to use grit objects inside app/
  3 +# It helps us easily migrate to rugged in future
  4 +module Gitlab
  5 + module Git
  6 + class Repository
  7 + include Gitlab::Popen
  8 +
  9 + class NoRepository < StandardError; end
  10 +
  11 + # Repository directory name with namespace direcotry
  12 + # Examples:
  13 + # gitlab/gitolite
  14 + # diaspora
  15 + #
  16 + attr_accessor :path_with_namespace
  17 +
  18 + # Grit repo object
  19 + attr_accessor :repo
  20 +
  21 + # Default branch in the repository
  22 + attr_accessor :root_ref
  23 +
  24 + def initialize(path_with_namespace, root_ref = 'master')
  25 + @root_ref = root_ref || "master"
  26 + @path_with_namespace = path_with_namespace
  27 +
  28 + # Init grit repo object
  29 + repo
  30 + end
  31 +
  32 + def raw
  33 + repo
  34 + end
  35 +
  36 + def path_to_repo
  37 + @path_to_repo ||= File.join(repos_path, "#{path_with_namespace}.git")
  38 + end
  39 +
  40 + def repos_path
  41 + Gitlab.config.gitlab_shell.repos_path
  42 + end
  43 +
  44 + def repo
  45 + @repo ||= Grit::Repo.new(path_to_repo)
  46 + rescue Grit::NoSuchPathError
  47 + raise NoRepository.new('no repository for such path')
  48 + end
  49 +
  50 + def commit(commit_id = nil)
  51 + Gitlab::Git::Commit.find_or_first(repo, commit_id, root_ref)
  52 + end
  53 +
  54 + def fresh_commits(n = 10)
  55 + Gitlab::Git::Commit.fresh_commits(repo, n)
  56 + end
  57 +
  58 + def commits_with_refs(n = 20)
  59 + Gitlab::Git::Commit.commits_with_refs(repo, n)
  60 + end
  61 +
  62 + def commits_since(date)
  63 + Gitlab::Git::Commit.commits_since(repo, date)
  64 + end
  65 +
  66 + def commits(ref, path = nil, limit = nil, offset = nil)
  67 + Gitlab::Git::Commit.commits(repo, ref, path, limit, offset)
  68 + end
  69 +
  70 + def last_commit_for(ref, path = nil)
  71 + commits(ref, path, 1).first
  72 + end
  73 +
  74 + def commits_between(from, to)
  75 + Gitlab::Git::Commit.commits_between(repo, from, to)
  76 + end
  77 +
  78 + # Returns an Array of branch names
  79 + # sorted by name ASC
  80 + def branch_names
  81 + branches.map(&:name)
  82 + end
  83 +
  84 + # Returns an Array of Branches
  85 + def branches
  86 + repo.branches.sort_by(&:name)
  87 + end
  88 +
  89 + # Returns an Array of tag names
  90 + def tag_names
  91 + repo.tags.collect(&:name).sort.reverse
  92 + end
  93 +
  94 + # Returns an Array of Tags
  95 + def tags
  96 + repo.tags.sort_by(&:name).reverse
  97 + end
  98 +
  99 + # Returns an Array of branch and tag names
  100 + def ref_names
  101 + [branch_names + tag_names].flatten
  102 + end
  103 +
  104 + def heads
  105 + @heads ||= repo.heads
  106 + end
  107 +
  108 + def tree(fcommit, path = nil)
  109 + fcommit = commit if fcommit == :head
  110 + tree = fcommit.tree
  111 + path ? (tree / path) : tree
  112 + end
  113 +
  114 + def has_commits?
  115 + !!commit
  116 + rescue Grit::NoSuchPathError
  117 + false
  118 + end
  119 +
  120 + def empty?
  121 + !has_commits?
  122 + end
  123 +
  124 + # Discovers the default branch based on the repository's available branches
  125 + #
  126 + # - If no branches are present, returns nil
  127 + # - If one branch is present, returns its name
  128 + # - If two or more branches are present, returns the one that has a name
  129 + # matching root_ref (default_branch or 'master' if default_branch is nil)
  130 + def discover_default_branch
  131 + if branch_names.length == 0
  132 + nil
  133 + elsif branch_names.length == 1
  134 + branch_names.first
  135 + else
  136 + branch_names.select { |v| v == root_ref }.first
  137 + end
  138 + end
  139 +
  140 + # Archive Project to .tar.gz
  141 + #
  142 + # Already packed repo archives stored at
  143 + # app_root/tmp/repositories/project_name/project_name-commit-id.tag.gz
  144 + #
  145 + def archive_repo(ref)
  146 + ref = ref || self.root_ref
  147 + commit = self.commit(ref)
  148 + return nil unless commit
  149 +
  150 + # Build file path
  151 + file_name = self.path_with_namespace.gsub("/","_") + "-" + commit.id.to_s + ".tar.gz"
  152 + storage_path = Rails.root.join("tmp", "repositories")
  153 + file_path = File.join(storage_path, self.path_with_namespace, file_name)
  154 +
  155 + # Put files into a directory before archiving
  156 + prefix = File.basename(self.path_with_namespace) + "/"
  157 +
  158 + # Create file if not exists
  159 + unless File.exists?(file_path)
  160 + FileUtils.mkdir_p File.dirname(file_path)
  161 + file = self.repo.archive_to_file(ref, prefix, file_path)
  162 + end
  163 +
  164 + file_path
  165 + end
  166 +
  167 + # Return repo size in megabytes
  168 + # Cached in redis
  169 + def size
  170 + Rails.cache.fetch(cache_key(:size)) do
  171 + size = popen('du -s', path_to_repo).first.strip.to_i
  172 + (size.to_f / 1024).round(2)
  173 + end
  174 + end
  175 +
  176 + def expire_cache
  177 + Rails.cache.delete(cache_key(:size))
  178 + end
  179 +
  180 + def cache_key(type)
  181 + "#{type}:#{path_with_namespace}"
  182 + end
  183 + end
  184 + end
  185 +end
lib/gitlab/markdown.rb
@@ -187,7 +187,7 @@ module Gitlab @@ -187,7 +187,7 @@ module Gitlab
187 187
188 def reference_commit(identifier) 188 def reference_commit(identifier)
189 if @project.valid_repo? && commit = @project.repository.commit(identifier) 189 if @project.valid_repo? && commit = @project.repository.commit(identifier)
190 - link_to(identifier, project_commit_url(@project, commit), html_options.merge(title: CommitDecorator.new(commit).link_title, class: "gfm gfm-commit #{html_options[:class]}")) 190 + link_to(identifier, project_commit_url(@project, commit), html_options.merge(title: commit.link_title, class: "gfm gfm-commit #{html_options[:class]}"))
191 end 191 end
192 end 192 end
193 end 193 end
lib/tasks/cache.rake 0 → 100644
@@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
  1 +namespace :cache do
  2 + desc "GITLAB | Clear redis cache"
  3 + task :clear => :environment do
  4 + Rails.cache.clear
  5 + end
  6 +end
spec/controllers/commit_controller_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
2 2
3 describe CommitController do 3 describe CommitController do
4 - let(:project) { create(:project) } 4 + let(:project) { create(:project_with_code) }
5 let(:user) { create(:user) } 5 let(:user) { create(:user) }
6 let(:commit) { project.repository.last_commit_for("master") } 6 let(:commit) { project.repository.last_commit_for("master") }
7 7
spec/controllers/commits_controller_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
2 2
3 describe CommitsController do 3 describe CommitsController do
4 - let(:project) { create(:project) } 4 + let(:project) { create(:project_with_code) }
5 let(:user) { create(:user) } 5 let(:user) { create(:user) }
6 6
7 before do 7 before do
spec/controllers/merge_requests_controller_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
2 2
3 describe MergeRequestsController do 3 describe MergeRequestsController do
4 - let(:project) { create(:project) } 4 + let(:project) { create(:project_with_code) }
5 let(:user) { create(:user) } 5 let(:user) { create(:user) }
6 let(:merge_request) { create(:merge_request_with_diffs, project: project, target_branch: "bcf03b5d~3", source_branch: "bcf03b5d") } 6 let(:merge_request) { create(:merge_request_with_diffs, project: project, target_branch: "bcf03b5d~3", source_branch: "bcf03b5d") }
7 7
spec/controllers/tree_controller_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
2 2
3 describe TreeController do 3 describe TreeController do
4 - let(:project) { create(:project) } 4 + let(:project) { create(:project_with_code) }
5 let(:user) { create(:user) } 5 let(:user) { create(:user) }
6 6
7 before do 7 before do
spec/factories.rb
@@ -34,6 +34,10 @@ FactoryGirl.define do @@ -34,6 +34,10 @@ FactoryGirl.define do
34 issues_tracker_id { "project_name_in_redmine" } 34 issues_tracker_id { "project_name_in_redmine" }
35 end 35 end
36 36
  37 + factory :project_with_code, parent: :project do
  38 + path { 'gitlabhq' }
  39 + end
  40 +
37 factory :group do 41 factory :group do
38 sequence(:name) { |n| "group#{n}" } 42 sequence(:name) { |n| "group#{n}" }
39 path { name.downcase.gsub(/\s/, '_') } 43 path { name.downcase.gsub(/\s/, '_') }
@@ -73,7 +77,7 @@ FactoryGirl.define do @@ -73,7 +77,7 @@ FactoryGirl.define do
73 factory :merge_request do 77 factory :merge_request do
74 title 78 title
75 author 79 author
76 - project 80 + project factory: :project_with_code
77 source_branch "master" 81 source_branch "master"
78 target_branch "stable" 82 target_branch "stable"
79 83
@@ -82,9 +86,9 @@ FactoryGirl.define do @@ -82,9 +86,9 @@ FactoryGirl.define do
82 target_branch "master" # pretend bcf03b5d~3 86 target_branch "master" # pretend bcf03b5d~3
83 source_branch "stable" # pretend bcf03b5d 87 source_branch "stable" # pretend bcf03b5d
84 st_commits do 88 st_commits do
85 - [Commit.new(project.repo.commit('bcf03b5d')),  
86 - Commit.new(project.repo.commit('bcf03b5d~1')),  
87 - Commit.new(project.repo.commit('bcf03b5d~2'))] 89 + [Commit.new(project.repository.commit('bcf03b5d')),
  90 + Commit.new(project.repository.commit('bcf03b5d~1')),
  91 + Commit.new(project.repository.commit('bcf03b5d~2'))]
88 end 92 end
89 st_diffs do 93 st_diffs do
90 project.repo.diff("bcf03b5d~3", "bcf03b5d") 94 project.repo.diff("bcf03b5d~3", "bcf03b5d")
@@ -116,6 +120,7 @@ FactoryGirl.define do @@ -116,6 +120,7 @@ FactoryGirl.define do
116 factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff] 120 factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff]
117 121
118 trait :on_commit do 122 trait :on_commit do
  123 + project factory: :project_with_code
119 commit_id "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" 124 commit_id "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a"
120 noteable_type "Commit" 125 noteable_type "Commit"
121 end 126 end
@@ -125,6 +130,7 @@ FactoryGirl.define do @@ -125,6 +130,7 @@ FactoryGirl.define do
125 end 130 end
126 131
127 trait :on_merge_request do 132 trait :on_merge_request do
  133 + project factory: :project_with_code
128 noteable_id 1 134 noteable_id 1
129 noteable_type "MergeRequest" 135 noteable_type "MergeRequest"
130 end 136 end
spec/features/gitlab_flavored_markdown_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
2 2
3 describe "Gitlab Flavored Markdown" do 3 describe "Gitlab Flavored Markdown" do
4 - let(:project) { create(:project) } 4 + let(:project) { create(:project_with_code) }
5 let(:issue) { create(:issue, project: project) } 5 let(:issue) { create(:issue, project: project) }
6 let(:merge_request) { create(:merge_request, project: project) } 6 let(:merge_request) { create(:merge_request, project: project) }
7 let(:fred) do 7 let(:fred) do
spec/features/notes_on_merge_requests_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
2 2
3 describe "On a merge request", js: true do 3 describe "On a merge request", js: true do
4 - let!(:project) { create(:project) } 4 + let!(:project) { create(:project_with_code) }
5 let!(:merge_request) { create(:merge_request, project: project) } 5 let!(:merge_request) { create(:merge_request, project: project) }
6 6
7 before do 7 before do
@@ -83,7 +83,7 @@ end @@ -83,7 +83,7 @@ end
83 83
84 84
85 describe "On a merge request diff", js: true, focus: true do 85 describe "On a merge request diff", js: true, focus: true do
86 - let!(:project) { create(:project) } 86 + let!(:project) { create(:project_with_code) }
87 let!(:merge_request) { create(:merge_request_with_diffs, project: project) } 87 let!(:merge_request) { create(:merge_request_with_diffs, project: project) }
88 88
89 before do 89 before do
spec/features/profile_spec.rb
@@ -12,8 +12,9 @@ describe &quot;Profile account page&quot; do @@ -12,8 +12,9 @@ describe &quot;Profile account page&quot; do
12 Gitlab.config.gitlab.stub(:signup_enabled).and_return(true) 12 Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
13 visit account_profile_path 13 visit account_profile_path
14 end 14 end
  15 +
15 it { page.should have_content("Remove account") } 16 it { page.should have_content("Remove account") }
16 - 17 +
17 it "should delete the account", js: true do 18 it "should delete the account", js: true do
18 expect { click_link "Delete account" }.to change {User.count}.by(-1) 19 expect { click_link "Delete account" }.to change {User.count}.by(-1)
19 current_path.should == new_user_session_path 20 current_path.should == new_user_session_path
@@ -45,4 +46,4 @@ describe &quot;Profile account page&quot; do @@ -45,4 +46,4 @@ describe &quot;Profile account page&quot; do
45 current_path.should == account_profile_path 46 current_path.should == account_profile_path
46 end 47 end
47 end 48 end
48 -end  
49 \ No newline at end of file 49 \ No newline at end of file
  50 +end
spec/features/security/project_access_spec.rb
@@ -14,7 +14,7 @@ describe &quot;Application access&quot; do @@ -14,7 +14,7 @@ describe &quot;Application access&quot; do
14 end 14 end
15 15
16 describe "Project" do 16 describe "Project" do
17 - let(:project) { create(:project) } 17 + let(:project) { create(:project_with_code) }
18 18
19 let(:master) { create(:user) } 19 let(:master) { create(:user) }
20 let(:guest) { create(:user) } 20 let(:guest) { create(:user) }
spec/helpers/gitlab_markdown_helper_spec.rb
@@ -4,10 +4,10 @@ describe GitlabMarkdownHelper do @@ -4,10 +4,10 @@ describe GitlabMarkdownHelper do
4 include ApplicationHelper 4 include ApplicationHelper
5 include IssuesHelper 5 include IssuesHelper
6 6
7 - let!(:project) { create(:project) } 7 + let!(:project) { create(:project_with_code) }
8 8
9 let(:user) { create(:user, username: 'gfm') } 9 let(:user) { create(:user, username: 'gfm') }
10 - let(:commit) { CommitDecorator.decorate(project.repository.commit) } 10 + let(:commit) { project.repository.commit }
11 let(:issue) { create(:issue, project: project) } 11 let(:issue) { create(:issue, project: project) }
12 let(:merge_request) { create(:merge_request, project: project) } 12 let(:merge_request) { create(:merge_request, project: project) }
13 let(:snippet) { create(:snippet, project: project) } 13 let(:snippet) { create(:snippet, project: project) }
spec/lib/git/commit_spec.rb 0 → 100644
@@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
  1 +require "spec_helper"
  2 +
  3 +describe Gitlab::Git::Commit do
  4 + let(:commit) { create(:project_with_code).repository.commit }
  5 +
  6 + describe "Commit info" do
  7 + before do
  8 + @committer = double(
  9 + email: 'mike@smith.com',
  10 + name: 'Mike Smith'
  11 + )
  12 +
  13 + @author = double(
  14 + email: 'john@smith.com',
  15 + name: 'John Smith'
  16 + )
  17 +
  18 + @raw_commit = double(
  19 + id: "bcf03b5de6abcf03b5de6c",
  20 + author: @author,
  21 + committer: @committer,
  22 + committed_date: Date.yesterday,
  23 + message: 'Refactoring specs'
  24 + )
  25 +
  26 + @commit = Gitlab::Git::Commit.new(@raw_commit)
  27 + end
  28 +
  29 + it { @commit.short_id.should == "bcf03b5de6a" }
  30 + it { @commit.safe_message.should == @raw_commit.message }
  31 + it { @commit.created_at.should == @raw_commit.committed_date }
  32 + it { @commit.author_email.should == @author.email }
  33 + it { @commit.author_name.should == @author.name }
  34 + it { @commit.committer_name.should == @committer.name }
  35 + it { @commit.committer_email.should == @committer.email }
  36 + it { @commit.different_committer?.should be_true }
  37 + end
  38 +
  39 + describe "Class methods" do
  40 + subject { Gitlab::Git::Commit }
  41 +
  42 + it { should respond_to(:find_or_first) }
  43 + it { should respond_to(:fresh_commits) }
  44 + it { should respond_to(:commits_with_refs) }
  45 + it { should respond_to(:commits_since) }
  46 + it { should respond_to(:commits_between) }
  47 + it { should respond_to(:commits) }
  48 + end
  49 +end
spec/lib/git/repository_spec.rb 0 → 100644
@@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
  1 +require "spec_helper"
  2 +
  3 +describe Gitlab::Git::Repository do
  4 + let(:repository) { Gitlab::Git::Repository.new('gitlabhq', 'master') }
  5 +
  6 + describe "Respond to" do
  7 + subject { repository }
  8 +
  9 + it { should respond_to(:repo) }
  10 + it { should respond_to(:tree) }
  11 + it { should respond_to(:root_ref) }
  12 + it { should respond_to(:tags) }
  13 + it { should respond_to(:commit) }
  14 + it { should respond_to(:commits) }
  15 + it { should respond_to(:commits_between) }
  16 + it { should respond_to(:commits_with_refs) }
  17 + it { should respond_to(:commits_since) }
  18 + it { should respond_to(:commits_between) }
  19 + end
  20 +
  21 +
  22 + describe "#discover_default_branch" do
  23 + let(:master) { 'master' }
  24 + let(:stable) { 'stable' }
  25 +
  26 + it "returns 'master' when master exists" do
  27 + repository.should_receive(:branch_names).at_least(:once).and_return([stable, master])
  28 + repository.discover_default_branch.should == 'master'
  29 + end
  30 +
  31 + it "returns non-master when master exists but default branch is set to something else" do
  32 + repository.root_ref = 'stable'
  33 + repository.should_receive(:branch_names).at_least(:once).and_return([stable, master])
  34 + repository.discover_default_branch.should == 'stable'
  35 + end
  36 +
  37 + it "returns a non-master branch when only one exists" do
  38 + repository.should_receive(:branch_names).at_least(:once).and_return([stable])
  39 + repository.discover_default_branch.should == 'stable'
  40 + end
  41 +
  42 + it "returns nil when no branch exists" do
  43 + repository.should_receive(:branch_names).at_least(:once).and_return([])
  44 + repository.discover_default_branch.should be_nil
  45 + end
  46 + end
  47 +
  48 + describe :commit do
  49 + it "should return first head commit if without params" do
  50 + repository.commit.id.should == repository.repo.commits.first.id
  51 + end
  52 +
  53 + it "should return valid commit" do
  54 + repository.commit(ValidCommit::ID).should be_valid_commit
  55 + end
  56 +
  57 + it "should return nil" do
  58 + repository.commit("+123_4532530XYZ").should be_nil
  59 + end
  60 + end
  61 +
  62 + describe :tree do
  63 + before do
  64 + @commit = repository.commit(ValidCommit::ID)
  65 + end
  66 +
  67 + it "should raise error w/o arguments" do
  68 + lambda { repository.tree }.should raise_error
  69 + end
  70 +
  71 + it "should return root tree for commit" do
  72 + tree = repository.tree(@commit)
  73 + tree.contents.size.should == ValidCommit::FILES_COUNT
  74 + tree.contents.map(&:name).should == ValidCommit::FILES
  75 + end
  76 +
  77 + it "should return root tree for commit with correct path" do
  78 + tree = repository.tree(@commit, ValidCommit::C_FILE_PATH)
  79 + tree.contents.map(&:name).should == ValidCommit::C_FILES
  80 + end
  81 +
  82 + it "should return root tree for commit with incorrect path" do
  83 + repository.tree(@commit, "invalid_path").should be_nil
  84 + end
  85 + end
  86 +
  87 + describe "fresh commits" do
  88 + it { repository.fresh_commits(3).count.should == 3 }
  89 + it { repository.fresh_commits.first.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" }
  90 + it { repository.fresh_commits.last.id.should == "f403da73f5e62794a0447aca879360494b08f678" }
  91 + end
  92 +
  93 + describe "commits_between" do
  94 + subject do
  95 + commits = repository.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff",
  96 + "8470d70da67355c9c009e4401746b1d5410af2e3")
  97 + commits.map { |c| c.id }
  98 + end
  99 +
  100 + it { should have(3).elements }
  101 + it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") }
  102 + it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }
  103 + end
  104 +end
spec/mailers/notify_spec.rb
@@ -5,7 +5,7 @@ describe Notify do @@ -5,7 +5,7 @@ describe Notify do
5 include EmailSpec::Matchers 5 include EmailSpec::Matchers
6 6
7 let(:recipient) { create(:user, email: 'recipient@example.com') } 7 let(:recipient) { create(:user, email: 'recipient@example.com') }
8 - let(:project) { create(:project) } 8 + let(:project) { create(:project_with_code) }
9 9
10 shared_examples 'a multiple recipients email' do 10 shared_examples 'a multiple recipients email' do
11 it 'is sent to the given recipient' do 11 it 'is sent to the given recipient' do
@@ -277,14 +277,7 @@ describe Notify do @@ -277,14 +277,7 @@ describe Notify do
277 end 277 end
278 278
279 describe 'on a commit' do 279 describe 'on a commit' do
280 - let(:commit) do  
281 - mock(:commit).tap do |commit|  
282 - commit.stub(:id).and_return('fauxsha1')  
283 - commit.stub(:project).and_return(project)  
284 - commit.stub(:short_id).and_return('fauxsha1')  
285 - commit.stub(:safe_message).and_return('some message')  
286 - end  
287 - end 280 + let(:commit) { project.repository.commit }
288 281
289 before(:each) { note.stub(:noteable).and_return(commit) } 282 before(:each) { note.stub(:noteable).and_return(commit) }
290 283
@@ -297,7 +290,7 @@ describe Notify do @@ -297,7 +290,7 @@ describe Notify do
297 end 290 end
298 291
299 it 'contains a link to the commit' do 292 it 'contains a link to the commit' do
300 - should have_body_text /fauxsha1/ 293 + should have_body_text commit.short_id
301 end 294 end
302 end 295 end
303 296
spec/models/commit_spec.rb
1 require 'spec_helper' 1 require 'spec_helper'
2 2
3 describe Commit do 3 describe Commit do
4 - let(:commit) { create(:project).repository.commit } 4 + let(:commit) { create(:project_with_code).repository.commit }
5 5
6 - describe CommitDecorator do  
7 - let(:decorator) { CommitDecorator.new(commit) }  
8 6
9 - describe '#title' do  
10 - it "returns no_commit_message when safe_message is blank" do  
11 - decorator.stub(:safe_message).and_return('')  
12 - decorator.title.should == "--no commit message"  
13 - end  
14 -  
15 - it "truncates a message without a newline at 70 characters" do  
16 - message = commit.safe_message * 10  
17 -  
18 - decorator.stub(:safe_message).and_return(message)  
19 - decorator.title.should == "#{message[0..69]}&hellip;"  
20 - end  
21 -  
22 - it "truncates a message with a newline before 80 characters at the newline" do  
23 - message = commit.safe_message.split(" ").first  
24 -  
25 - decorator.stub(:safe_message).and_return(message + "\n" + message)  
26 - decorator.title.should == message  
27 - end  
28 -  
29 - it "truncates a message with a newline after 80 characters at 70 characters" do  
30 - message = (commit.safe_message * 10) + "\n"  
31 -  
32 - decorator.stub(:safe_message).and_return(message)  
33 - decorator.title.should == "#{message[0..69]}&hellip;"  
34 - end 7 + describe '#title' do
  8 + it "returns no_commit_message when safe_message is blank" do
  9 + commit.stub(:safe_message).and_return('')
  10 + commit.title.should == "--no commit message"
35 end 11 end
36 - end  
37 12
38 - describe "Commit info" do  
39 - before do  
40 - @committer = double(  
41 - email: 'mike@smith.com',  
42 - name: 'Mike Smith'  
43 - ) 13 + it "truncates a message without a newline at 70 characters" do
  14 + message = commit.safe_message * 10
44 15
45 - @author = double(  
46 - email: 'john@smith.com',  
47 - name: 'John Smith'  
48 - ) 16 + commit.stub(:safe_message).and_return(message)
  17 + commit.title.should == "#{message[0..69]}&hellip;"
  18 + end
49 19
50 - @raw_commit = double(  
51 - id: "bcf03b5de6abcf03b5de6c",  
52 - author: @author,  
53 - committer: @committer,  
54 - committed_date: Date.yesterday,  
55 - message: 'Refactoring specs'  
56 - ) 20 + it "truncates a message with a newline before 80 characters at the newline" do
  21 + message = commit.safe_message.split(" ").first
57 22
58 - @commit = Commit.new(@raw_commit) 23 + commit.stub(:safe_message).and_return(message + "\n" + message)
  24 + commit.title.should == message
59 end 25 end
60 26
61 - it { @commit.short_id.should == "bcf03b5de6a" }  
62 - it { @commit.safe_message.should == @raw_commit.message }  
63 - it { @commit.created_at.should == @raw_commit.committed_date }  
64 - it { @commit.author_email.should == @author.email }  
65 - it { @commit.author_name.should == @author.name }  
66 - it { @commit.committer_name.should == @committer.name }  
67 - it { @commit.committer_email.should == @committer.email }  
68 - it { @commit.different_committer?.should be_true }  
69 - end 27 + it "truncates a message with a newline after 80 characters at 70 characters" do
  28 + message = (commit.safe_message * 10) + "\n"
70 29
71 - describe "Class methods" do  
72 - subject { Commit }  
73 -  
74 - it { should respond_to(:find_or_first) }  
75 - it { should respond_to(:fresh_commits) }  
76 - it { should respond_to(:commits_with_refs) }  
77 - it { should respond_to(:commits_since) }  
78 - it { should respond_to(:commits_between) }  
79 - it { should respond_to(:commits) }  
80 - it { should respond_to(:compare) } 30 + commit.stub(:safe_message).and_return(message)
  31 + commit.title.should == "#{message[0..69]}&hellip;"
  32 + end
81 end 33 end
82 34
83 describe "delegation" do 35 describe "delegation" do
spec/models/gollum_wiki_spec.rb
@@ -81,7 +81,7 @@ describe GollumWiki do @@ -81,7 +81,7 @@ describe GollumWiki do
81 end 81 end
82 82
83 it "raises CouldNotCreateWikiError if it can't create the wiki repository" do 83 it "raises CouldNotCreateWikiError if it can't create the wiki repository" do
84 - Gitlab::Shell.any_instance.stub(:add_repository).and_return(false) 84 + GollumWiki.any_instance.stub(:init_repo).and_return(false)
85 expect { GollumWiki.new(project, user).wiki }.to raise_exception(GollumWiki::CouldNotCreateWikiError) 85 expect { GollumWiki.new(project, user).wiki }.to raise_exception(GollumWiki::CouldNotCreateWikiError)
86 end 86 end
87 end 87 end
spec/models/project_spec.rb
@@ -119,7 +119,7 @@ describe Project do @@ -119,7 +119,7 @@ describe Project do
119 end 119 end
120 120
121 describe :update_merge_requests do 121 describe :update_merge_requests do
122 - let(:project) { create(:project) } 122 + let(:project) { create(:project_with_code) }
123 123
124 before do 124 before do
125 @merge_request = create(:merge_request, project: project) 125 @merge_request = create(:merge_request, project: project)
@@ -189,10 +189,6 @@ describe Project do @@ -189,10 +189,6 @@ describe Project do
189 it "should return valid repo" do 189 it "should return valid repo" do
190 project.repository.should be_kind_of(Repository) 190 project.repository.should be_kind_of(Repository)
191 end 191 end
192 -  
193 - it "should return nil" do  
194 - Project.new(path: "empty").repository.should be_nil  
195 - end  
196 end 192 end
197 193
198 describe :issue_exists? do 194 describe :issue_exists? do
@@ -249,7 +245,7 @@ describe Project do @@ -249,7 +245,7 @@ describe Project do
249 end 245 end
250 246
251 describe :open_branches do 247 describe :open_branches do
252 - let(:project) { create(:project) } 248 + let(:project) { create(:project_with_code) }
253 249
254 before do 250 before do
255 project.protected_branches.create(name: 'master') 251 project.protected_branches.create(name: 'master')
spec/models/repository_spec.rb
@@ -1,105 +0,0 @@ @@ -1,105 +0,0 @@
1 -require "spec_helper"  
2 -  
3 -describe Repository do  
4 - let(:project) { create(:project) }  
5 - let(:repository) { project.repository }  
6 -  
7 - describe "Respond to" do  
8 - subject { repository }  
9 -  
10 - it { should respond_to(:repo) }  
11 - it { should respond_to(:tree) }  
12 - it { should respond_to(:root_ref) }  
13 - it { should respond_to(:tags) }  
14 - it { should respond_to(:commit) }  
15 - it { should respond_to(:commits) }  
16 - it { should respond_to(:commits_between) }  
17 - it { should respond_to(:commits_with_refs) }  
18 - it { should respond_to(:commits_since) }  
19 - it { should respond_to(:commits_between) }  
20 - end  
21 -  
22 -  
23 - describe "#discover_default_branch" do  
24 - let(:master) { 'master' }  
25 - let(:stable) { 'stable' }  
26 -  
27 - it "returns 'master' when master exists" do  
28 - repository.should_receive(:branch_names).at_least(:once).and_return([stable, master])  
29 - repository.discover_default_branch.should == 'master'  
30 - end  
31 -  
32 - it "returns non-master when master exists but default branch is set to something else" do  
33 - repository.root_ref = 'stable'  
34 - repository.should_receive(:branch_names).at_least(:once).and_return([stable, master])  
35 - repository.discover_default_branch.should == 'stable'  
36 - end  
37 -  
38 - it "returns a non-master branch when only one exists" do  
39 - repository.should_receive(:branch_names).at_least(:once).and_return([stable])  
40 - repository.discover_default_branch.should == 'stable'  
41 - end  
42 -  
43 - it "returns nil when no branch exists" do  
44 - repository.should_receive(:branch_names).at_least(:once).and_return([])  
45 - repository.discover_default_branch.should be_nil  
46 - end  
47 - end  
48 -  
49 - describe :commit do  
50 - it "should return first head commit if without params" do  
51 - repository.commit.id.should == repository.repo.commits.first.id  
52 - end  
53 -  
54 - it "should return valid commit" do  
55 - repository.commit(ValidCommit::ID).should be_valid_commit  
56 - end  
57 -  
58 - it "should return nil" do  
59 - repository.commit("+123_4532530XYZ").should be_nil  
60 - end  
61 - end  
62 -  
63 - describe :tree do  
64 - before do  
65 - @commit = repository.commit(ValidCommit::ID)  
66 - end  
67 -  
68 - it "should raise error w/o arguments" do  
69 - lambda { repository.tree }.should raise_error  
70 - end  
71 -  
72 - it "should return root tree for commit" do  
73 - tree = repository.tree(@commit)  
74 - tree.contents.size.should == ValidCommit::FILES_COUNT  
75 - tree.contents.map(&:name).should == ValidCommit::FILES  
76 - end  
77 -  
78 - it "should return root tree for commit with correct path" do  
79 - tree = repository.tree(@commit, ValidCommit::C_FILE_PATH)  
80 - tree.contents.map(&:name).should == ValidCommit::C_FILES  
81 - end  
82 -  
83 - it "should return root tree for commit with incorrect path" do  
84 - repository.tree(@commit, "invalid_path").should be_nil  
85 - end  
86 - end  
87 -  
88 - describe "fresh commits" do  
89 - it { repository.fresh_commits(3).count.should == 3 }  
90 - it { repository.fresh_commits.first.id.should == "bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a" }  
91 - it { repository.fresh_commits.last.id.should == "f403da73f5e62794a0447aca879360494b08f678" }  
92 - end  
93 -  
94 - describe "commits_between" do  
95 - subject do  
96 - commits = repository.commits_between("3a4b4fb4cde7809f033822a171b9feae19d41fff",  
97 - "8470d70da67355c9c009e4401746b1d5410af2e3")  
98 - commits.map { |c| c.id }  
99 - end  
100 -  
101 - it { should have(3).elements }  
102 - it { should include("f0f14c8eaba69ebddd766498a9d0b0e79becd633") }  
103 - it { should_not include("bcf03b5de6c33f3869ef70d68cf06e679d1d7f9a") }  
104 - end  
105 -end  
spec/requests/api/merge_requests_spec.rb
@@ -4,7 +4,7 @@ describe Gitlab::API do @@ -4,7 +4,7 @@ describe Gitlab::API do
4 include ApiHelpers 4 include ApiHelpers
5 5
6 let(:user) { create(:user ) } 6 let(:user) { create(:user ) }
7 - let!(:project) { create(:project, namespace: user.namespace ) } 7 + let!(:project) { create(:project_with_code, creator_id: user.id) }
8 let!(:merge_request) { create(:merge_request, author: user, assignee: user, project: project, title: "Test") } 8 let!(:merge_request) { create(:merge_request, author: user, assignee: user, project: project, title: "Test") }
9 before { project.team << [user, :reporters] } 9 before { project.team << [user, :reporters] }
10 10
spec/requests/api/projects_spec.rb
@@ -7,7 +7,7 @@ describe Gitlab::API do @@ -7,7 +7,7 @@ describe Gitlab::API do
7 let(:user2) { create(:user) } 7 let(:user2) { create(:user) }
8 let(:user3) { create(:user) } 8 let(:user3) { create(:user) }
9 let(:admin) { create(:admin) } 9 let(:admin) { create(:admin) }
10 - let!(:project) { create(:project, namespace: user.namespace ) } 10 + let!(:project) { create(:project_with_code, creator_id: user.id) }
11 let!(:hook) { create(:project_hook, project: project, url: "http://example.com") } 11 let!(:hook) { create(:project_hook, project: project, url: "http://example.com") }
12 let!(:snippet) { create(:snippet, author: user, project: project, title: 'example') } 12 let!(:snippet) { create(:snippet, author: user, project: project, title: 'example') }
13 let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) } 13 let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
spec/services/git_push_service_spec.rb
@@ -2,7 +2,7 @@ require &#39;spec_helper&#39; @@ -2,7 +2,7 @@ require &#39;spec_helper&#39;
2 2
3 describe GitPushService do 3 describe GitPushService do
4 let (:user) { create :user } 4 let (:user) { create :user }
5 - let (:project) { create :project } 5 + let (:project) { create :project_with_code }
6 let (:service) { GitPushService.new } 6 let (:service) { GitPushService.new }
7 7
8 before do 8 before do
spec/spec_helper.rb
@@ -47,11 +47,7 @@ Spork.prefork do @@ -47,11 +47,7 @@ Spork.prefork do
47 config.use_transactional_fixtures = false 47 config.use_transactional_fixtures = false
48 48
49 config.before do 49 config.before do
50 - # Use tmp dir for FS manipulations  
51 - temp_repos_path = Rails.root.join('tmp', 'test-git-base-path')  
52 - Gitlab.config.gitlab_shell.stub(repos_path: temp_repos_path)  
53 - FileUtils.rm_rf temp_repos_path  
54 - FileUtils.mkdir_p temp_repos_path 50 + TestEnv.init
55 end 51 end
56 end 52 end
57 end 53 end
spec/support/stubbed_repository.rb
@@ -1,75 +0,0 @@ @@ -1,75 +0,0 @@
1 -require "repository"  
2 -require "project"  
3 -require "merge_request"  
4 -require "shell"  
5 -  
6 -# Stubs out all Git repository access done by models so that specs can run  
7 -# against fake repositories without Grit complaining that they don't exist.  
8 -class Project  
9 - def repository  
10 - if path == "empty" || !path  
11 - nil  
12 - else  
13 - GitLabTestRepo.new(path_with_namespace)  
14 - end  
15 - end  
16 -  
17 - def satellite  
18 - FakeSatellite.new  
19 - end  
20 -  
21 - class FakeSatellite  
22 - def exists?  
23 - true  
24 - end  
25 -  
26 - def destroy  
27 - true  
28 - end  
29 -  
30 - def create  
31 - true  
32 - end  
33 - end  
34 -end  
35 -  
36 -class MergeRequest  
37 - def check_if_can_be_merged  
38 - true  
39 - end  
40 -end  
41 -  
42 -class GitLabTestRepo < Repository  
43 - def repo  
44 - @repo ||= Grit::Repo.new(Rails.root.join('tmp', 'repositories', 'gitlabhq'))  
45 - end  
46 -  
47 - # patch repo size (in mb)  
48 - def size  
49 - 12.45  
50 - end  
51 -end  
52 -  
53 -module Gitlab  
54 - class Shell  
55 - def add_repository name  
56 - true  
57 - end  
58 -  
59 - def mv_repository name, new_name  
60 - true  
61 - end  
62 -  
63 - def remove_repository name  
64 - true  
65 - end  
66 -  
67 - def add_key id, key  
68 - true  
69 - end  
70 -  
71 - def remove_key id, key  
72 - true  
73 - end  
74 - end  
75 -end  
spec/support/test_env.rb 0 → 100644
@@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
  1 +module TestEnv
  2 + extend self
  3 +
  4 + # Test environment
  5 + #
  6 + # all repositories and namespaces stored at
  7 + # RAILS_APP/tmp/test-git-base-path
  8 + #
  9 + # Next shell methods are stubbed and return true
  10 + # - mv_repository
  11 + # - remove_repository
  12 + # - add_key
  13 + # - remove_key
  14 + #
  15 + def init
  16 + # Use tmp dir for FS manipulations
  17 + repos_path = Rails.root.join('tmp', 'test-git-base-path')
  18 + Gitlab.config.gitlab_shell.stub(repos_path: repos_path)
  19 +
  20 + GollumWiki.any_instance.stub(:init_repo) do |path|
  21 + create_temp_repo(File.join(repos_path, "#{path}.git"))
  22 + end
  23 +
  24 + Gitlab::Shell.any_instance.stub(
  25 + add_repository: true,
  26 + mv_repository: true,
  27 + remove_repository: true,
  28 + add_key: true,
  29 + remove_key: true
  30 + )
  31 +
  32 + Gitlab::Satellite::Satellite.any_instance.stub(
  33 + exists?: true,
  34 + destroy: true,
  35 + create: true
  36 + )
  37 +
  38 + MergeRequest.any_instance.stub(
  39 + check_if_can_be_merged: true
  40 + )
  41 +
  42 + Repository.any_instance.stub(
  43 + size: 12.45
  44 + )
  45 +
  46 + # Remove tmp/test-git-base-path
  47 + FileUtils.rm_rf Gitlab.config.gitlab_shell.repos_path
  48 +
  49 + # Recreate tmp/test-git-base-path
  50 + FileUtils.mkdir_p Gitlab.config.gitlab_shell.repos_path
  51 +
  52 + # Symlink tmp/repositories/gitlabhq to tmp/test-git-base-path/gitlabhq
  53 + seed_repo = Rails.root.join('tmp', 'repositories', 'gitlabhq')
  54 + target_repo = File.join(repos_path, 'gitlabhq.git')
  55 + system("ln -s #{seed_repo} #{target_repo}")
  56 + end
  57 +
  58 + def create_temp_repo(path)
  59 + FileUtils.mkdir_p path
  60 + command = "git init --quiet --bare #{path};"
  61 + system(command)
  62 + end
  63 +end
spec/workers/post_receive_spec.rb
@@ -9,7 +9,7 @@ describe PostReceive do @@ -9,7 +9,7 @@ describe PostReceive do
9 end 9 end
10 10
11 context "web hook" do 11 context "web hook" do
12 - let(:project) { create(:project) } 12 + let(:project) { create(:project_with_code) }
13 let(:key) { create(:key, user: project.owner) } 13 let(:key) { create(:key, user: project.owner) }
14 let(:key_id) { key.shell_id } 14 let(:key_id) { key.shell_id }
15 15