Commit 377916ed authored by Shinya Maeda's avatar Shinya Maeda

Merge branch 'master' into refactor-clusters

parents eba27fe0 d4ceec9d
...@@ -413,8 +413,9 @@ export default class Notes { ...@@ -413,8 +413,9 @@ export default class Notes {
return; return;
} }
this.note_ids.push(noteEntity.id); this.note_ids.push(noteEntity.id);
form = $form || $(`.js-discussion-note-form[data-discussion-id="${noteEntity.discussion_id}"]`); form = $form || $(`.js-discussion-note-form[data-discussion-id="${noteEntity.discussion_id}"]`);
row = form.closest('tr'); row = (form.length || !noteEntity.discussion_line_code) ? form.closest('tr') : $(`#${noteEntity.discussion_line_code}`);
if (noteEntity.on_image) { if (noteEntity.on_image) {
row = form; row = form;
......
...@@ -109,6 +109,8 @@ module NotesActions ...@@ -109,6 +109,8 @@ module NotesActions
diff_discussion_html: diff_discussion_html(discussion), diff_discussion_html: diff_discussion_html(discussion),
discussion_html: discussion_html(discussion) discussion_html: discussion_html(discussion)
) )
attrs[:discussion_line_code] = discussion.line_code if discussion.diff_discussion?
end end
end end
else else
......
module RepositoryMirroring
IMPORT_HEAD_REFS = '+refs/heads/*:refs/heads/*'.freeze
IMPORT_TAG_REFS = '+refs/tags/*:refs/tags/*'.freeze
def set_remote_as_mirror(name)
# This is used to define repository as equivalent as "git clone --mirror"
raw_repository.rugged.config["remote.#{name}.fetch"] = 'refs/*:refs/*'
raw_repository.rugged.config["remote.#{name}.mirror"] = true
raw_repository.rugged.config["remote.#{name}.prune"] = true
end
def set_import_remote_as_mirror(remote_name)
# Add first fetch with Rugged so it does not create its own.
raw_repository.rugged.config["remote.#{remote_name}.fetch"] = IMPORT_HEAD_REFS
add_remote_fetch_config(remote_name, IMPORT_TAG_REFS)
raw_repository.rugged.config["remote.#{remote_name}.mirror"] = true
raw_repository.rugged.config["remote.#{remote_name}.prune"] = true
end
def add_remote_fetch_config(remote_name, refspec)
run_git(%W[config --add remote.#{remote_name}.fetch #{refspec}])
end
def fetch_mirror(remote, url)
add_remote(remote, url)
set_remote_as_mirror(remote)
fetch_remote(remote, forced: true)
remove_remote(remote)
end
end
...@@ -30,7 +30,6 @@ class Environment < ActiveRecord::Base ...@@ -30,7 +30,6 @@ class Environment < ActiveRecord::Base
message: Gitlab::Regex.environment_slug_regex_message } message: Gitlab::Regex.environment_slug_regex_message }
validates :external_url, validates :external_url,
uniqueness: { scope: :project_id },
length: { maximum: 255 }, length: { maximum: 255 },
allow_nil: true, allow_nil: true,
addressable_url: true addressable_url: true
......
...@@ -1686,6 +1686,10 @@ class Project < ActiveRecord::Base ...@@ -1686,6 +1686,10 @@ class Project < ActiveRecord::Base
Gitlab::GlRepository.gl_repository(self, is_wiki) Gitlab::GlRepository.gl_repository(self, is_wiki)
end end
def reference_counter(wiki: false)
Gitlab::ReferenceCounter.new(gl_repository(is_wiki: wiki))
end
private private
def storage def storage
...@@ -1704,11 +1708,11 @@ class Project < ActiveRecord::Base ...@@ -1704,11 +1708,11 @@ class Project < ActiveRecord::Base
end end
def repo_reference_count def repo_reference_count
Gitlab::ReferenceCounter.new(gl_repository(is_wiki: false)).value reference_counter.value
end end
def wiki_reference_count def wiki_reference_count
Gitlab::ReferenceCounter.new(gl_repository(is_wiki: true)).value reference_counter(wiki: true).value
end end
def check_repository_absence! def check_repository_absence!
......
...@@ -135,7 +135,7 @@ class ProjectWiki ...@@ -135,7 +135,7 @@ class ProjectWiki
end end
def repository def repository
@repository ||= Repository.new(full_path, @project, disk_path: disk_path) @repository ||= Repository.new(full_path, @project, disk_path: disk_path, is_wiki: true)
end end
def default_branch def default_branch
......
...@@ -15,9 +15,8 @@ class Repository ...@@ -15,9 +15,8 @@ class Repository
].freeze ].freeze
include Gitlab::ShellAdapter include Gitlab::ShellAdapter
include RepositoryMirroring
attr_accessor :full_path, :disk_path, :project attr_accessor :full_path, :disk_path, :project, :is_wiki
delegate :ref_name_for_sha, to: :raw_repository delegate :ref_name_for_sha, to: :raw_repository
...@@ -72,11 +71,12 @@ class Repository ...@@ -72,11 +71,12 @@ class Repository
end end
end end
def initialize(full_path, project, disk_path: nil) def initialize(full_path, project, disk_path: nil, is_wiki: false)
@full_path = full_path @full_path = full_path
@disk_path = disk_path || full_path @disk_path = disk_path || full_path
@project = project @project = project
@commit_cache = {} @commit_cache = {}
@is_wiki = is_wiki
end end
def ==(other) def ==(other)
...@@ -965,21 +965,8 @@ class Repository ...@@ -965,21 +965,8 @@ class Repository
run_git(args).first.lines.map(&:strip) run_git(args).first.lines.map(&:strip)
end end
def add_remote(name, url) def fetch_remote(remote, forced: false, ssh_auth: nil, no_tags: false)
raw_repository.remote_add(name, url) gitlab_shell.fetch_remote(raw_repository, remote, ssh_auth: ssh_auth, forced: forced, no_tags: no_tags)
rescue Rugged::ConfigError
raw_repository.remote_update(name, url: url)
end
def remove_remote(name)
raw_repository.remote_delete(name)
true
rescue Rugged::ConfigError
false
end
def fetch_remote(remote, forced: false, no_tags: false)
gitlab_shell.fetch_remote(raw_repository, remote, forced: forced, no_tags: no_tags)
end end
def fetch_source_branch(source_repository, source_branch, local_ref) def fetch_source_branch(source_repository, source_branch, local_ref)
...@@ -1141,7 +1128,7 @@ class Repository ...@@ -1141,7 +1128,7 @@ class Repository
end end
def initialize_raw_repository def initialize_raw_repository
Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git', Gitlab::GlRepository.gl_repository(project, false)) Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git', Gitlab::GlRepository.gl_repository(project, is_wiki))
end end
def find_commits_by_message_by_shelling_out(query, ref, path, limit, offset) def find_commits_by_message_by_shelling_out(query, ref, path, limit, offset)
......
...@@ -44,7 +44,7 @@ module Projects ...@@ -44,7 +44,7 @@ module Projects
else else
clone_repository clone_repository
end end
rescue Gitlab::Shell::Error => e rescue Gitlab::Shell::Error, Gitlab::Git::RepositoryMirroring::RemoteError => e
# Expire cache to prevent scenarios such as: # Expire cache to prevent scenarios such as:
# 1. First import failed, but the repo was imported successfully, so +exists?+ returns true # 1. First import failed, but the repo was imported successfully, so +exists?+ returns true
# 2. Retried import, repo is broken or not imported but +exists?+ still returns true # 2. Retried import, repo is broken or not imported but +exists?+ still returns true
......
---
title: Add new diff discussions on MR diffs tab in "realtime"
merge_request: 14981
author:
type: fixed
...@@ -60,7 +60,9 @@ module Github ...@@ -60,7 +60,9 @@ module Github
project.repository.set_import_remote_as_mirror('github') project.repository.set_import_remote_as_mirror('github')
project.repository.add_remote_fetch_config('github', '+refs/pull/*/head:refs/merge-requests/*/head') project.repository.add_remote_fetch_config('github', '+refs/pull/*/head:refs/merge-requests/*/head')
fetch_remote(forced: true) fetch_remote(forced: true)
rescue Gitlab::Git::Repository::NoRepository, Gitlab::Shell::Error => e rescue Gitlab::Git::Repository::NoRepository,
Gitlab::Git::RepositoryMirroring::RemoteError,
Gitlab::Shell::Error => e
error(:project, repo_url, e.message) error(:project, repo_url, e.message)
raise Github::RepositoryFetchError raise Github::RepositoryFetchError
end end
......
...@@ -6,6 +6,7 @@ require "rubygems/package" ...@@ -6,6 +6,7 @@ require "rubygems/package"
module Gitlab module Gitlab
module Git module Git
class Repository class Repository
include Gitlab::Git::RepositoryMirroring
include Gitlab::Git::Popen include Gitlab::Git::Popen
ALLOWED_OBJECT_DIRECTORIES_VARIABLES = %w[ ALLOWED_OBJECT_DIRECTORIES_VARIABLES = %w[
...@@ -898,16 +899,25 @@ module Gitlab ...@@ -898,16 +899,25 @@ module Gitlab
end end
end end
# Delete the specified remote from this repository. def add_remote(remote_name, url)
def remote_delete(remote_name) rugged.remotes.create(remote_name, url)
rugged.remotes.delete(remote_name) rescue Rugged::ConfigError
nil remote_update(remote_name, url: url)
end end
# Add a new remote to this repository. def remove_remote(remote_name)
def remote_add(remote_name, url) # When a remote is deleted all its remote refs are deleted too, but in
rugged.remotes.create(remote_name, url) # the case of mirrors we map its refs (that would usualy go under
nil # [remote_name]/) to the top level namespace. We clean the mapping so
# those don't get deleted.
if rugged.config["remote.#{remote_name}.mirror"]
rugged.config.delete("remote.#{remote_name}.fetch")
end
rugged.remotes.delete(remote_name)
true
rescue Rugged::ConfigError
false
end end
# Update the specified remote using the values in the +options+ hash # Update the specified remote using the values in the +options+ hash
......
module Gitlab
module Git
module RepositoryMirroring
IMPORT_HEAD_REFS = '+refs/heads/*:refs/heads/*'.freeze
IMPORT_TAG_REFS = '+refs/tags/*:refs/tags/*'.freeze
MIRROR_REMOTE = 'mirror'.freeze
RemoteError = Class.new(StandardError)
def set_remote_as_mirror(remote_name)
# This is used to define repository as equivalent as "git clone --mirror"
rugged.config["remote.#{remote_name}.fetch"] = 'refs/*:refs/*'
rugged.config["remote.#{remote_name}.mirror"] = true
rugged.config["remote.#{remote_name}.prune"] = true
end
def set_import_remote_as_mirror(remote_name)
# Add first fetch with Rugged so it does not create its own.
rugged.config["remote.#{remote_name}.fetch"] = IMPORT_HEAD_REFS
add_remote_fetch_config(remote_name, IMPORT_TAG_REFS)
rugged.config["remote.#{remote_name}.mirror"] = true
rugged.config["remote.#{remote_name}.prune"] = true
end
def add_remote_fetch_config(remote_name, refspec)
run_git(%W[config --add remote.#{remote_name}.fetch #{refspec}])
end
def fetch_mirror(url)
add_remote(MIRROR_REMOTE, url)
set_remote_as_mirror(MIRROR_REMOTE)
fetch(MIRROR_REMOTE)
remove_remote(MIRROR_REMOTE)
end
def remote_tags(remote)
# Each line has this format: "dc872e9fa6963f8f03da6c8f6f264d0845d6b092\trefs/tags/v1.10.0\n"
# We want to convert it to: [{ 'v1.10.0' => 'dc872e9fa6963f8f03da6c8f6f264d0845d6b092' }, ...]
list_remote_tags(remote).map do |line|
target, path = line.strip.split("\t")
# When the remote repo does not have tags.
if target.nil? || path.nil?
Rails.logger.info "Empty or invalid list of tags for remote: #{remote}. Output: #{output}"
return []
end
name = path.split('/', 3).last
# We're only interested in tag references
# See: http://stackoverflow.com/questions/15472107/when-listing-git-ls-remote-why-theres-after-the-tag-name
next if name =~ /\^\{\}\Z/
target_commit = Gitlab::Git::Commit.find(self, target)
Gitlab::Git::Tag.new(self, name, target, target_commit)
end.compact
end
def remote_branches(remote_name)
branches = []
rugged.references.each("refs/remotes/#{remote_name}/*").map do |ref|
name = ref.name.sub(/\Arefs\/remotes\/#{remote_name}\//, '')
begin
target_commit = Gitlab::Git::Commit.find(self, ref.target)
branches << Gitlab::Git::Branch.new(self, name, ref.target, target_commit)
rescue Rugged::ReferenceError
# Omit invalid branch
end
end
branches
end
private
def list_remote_tags(remote)
tag_list, exit_code, error = nil
cmd = %W(#{Gitlab.config.git.bin_path} --git-dir=#{full_path} ls-remote --tags #{remote})
Open3.popen3(*cmd) do |stdin, stdout, stderr, wait_thr|
tag_list = stdout.read
error = stderr.read
exit_code = wait_thr.value.exitstatus
end
raise RemoteError, error unless exit_code.zero?
tag_list.split('\n')
end
end
end
end
...@@ -10,6 +10,8 @@ module Gitlab ...@@ -10,6 +10,8 @@ module Gitlab
end end
PageBlob = Struct.new(:name) PageBlob = Struct.new(:name)
attr_reader :repository
def self.default_ref def self.default_ref
'master' 'master'
end end
......
...@@ -59,6 +59,7 @@ describe Projects::NotesController do ...@@ -59,6 +59,7 @@ describe Projects::NotesController do
expect(note_json[:id]).to eq(note.id) expect(note_json[:id]).to eq(note.id)
expect(note_json[:discussion_html]).not_to be_nil expect(note_json[:discussion_html]).not_to be_nil
expect(note_json[:diff_discussion_html]).to be_nil expect(note_json[:diff_discussion_html]).to be_nil
expect(note_json[:discussion_line_code]).to be_nil
end end
end end
...@@ -74,6 +75,7 @@ describe Projects::NotesController do ...@@ -74,6 +75,7 @@ describe Projects::NotesController do
expect(note_json[:id]).to eq(note.id) expect(note_json[:id]).to eq(note.id)
expect(note_json[:discussion_html]).not_to be_nil expect(note_json[:discussion_html]).not_to be_nil
expect(note_json[:diff_discussion_html]).not_to be_nil expect(note_json[:diff_discussion_html]).not_to be_nil
expect(note_json[:discussion_line_code]).not_to be_nil
end end
end end
...@@ -92,6 +94,7 @@ describe Projects::NotesController do ...@@ -92,6 +94,7 @@ describe Projects::NotesController do
expect(note_json[:id]).to eq(note.id) expect(note_json[:id]).to eq(note.id)
expect(note_json[:discussion_html]).not_to be_nil expect(note_json[:discussion_html]).not_to be_nil
expect(note_json[:diff_discussion_html]).to be_nil expect(note_json[:diff_discussion_html]).to be_nil
expect(note_json[:discussion_line_code]).to be_nil
end end
end end
...@@ -104,6 +107,7 @@ describe Projects::NotesController do ...@@ -104,6 +107,7 @@ describe Projects::NotesController do
expect(note_json[:id]).to eq(note.id) expect(note_json[:id]).to eq(note.id)
expect(note_json[:discussion_html]).to be_nil expect(note_json[:discussion_html]).to be_nil
expect(note_json[:diff_discussion_html]).to be_nil expect(note_json[:diff_discussion_html]).to be_nil
expect(note_json[:discussion_line_code]).to be_nil
end end
context 'when user cannot read commit' do context 'when user cannot read commit' do
...@@ -133,6 +137,7 @@ describe Projects::NotesController do ...@@ -133,6 +137,7 @@ describe Projects::NotesController do
expect(note_json[:html]).not_to be_nil expect(note_json[:html]).not_to be_nil
expect(note_json[:discussion_html]).to be_nil expect(note_json[:discussion_html]).to be_nil
expect(note_json[:diff_discussion_html]).to be_nil expect(note_json[:diff_discussion_html]).to be_nil
expect(note_json[:discussion_line_code]).to be_nil
end end
end end
......
...@@ -343,6 +343,7 @@ import '~/notes'; ...@@ -343,6 +343,7 @@ import '~/notes';
diff_discussion_html: false, diff_discussion_html: false,
}; };
$form = jasmine.createSpyObj('$form', ['closest', 'find']); $form = jasmine.createSpyObj('$form', ['closest', 'find']);
$form.length = 1;
row = jasmine.createSpyObj('row', ['prevAll', 'first', 'find']); row = jasmine.createSpyObj('row', ['prevAll', 'first', 'find']);
notes = jasmine.createSpyObj('notes', [ notes = jasmine.createSpyObj('notes', [
...@@ -371,13 +372,29 @@ import '~/notes'; ...@@ -371,13 +372,29 @@ import '~/notes';
$form.closest.and.returnValues(row, $form); $form.closest.and.returnValues(row, $form);
$form.find.and.returnValues(discussionContainer); $form.find.and.returnValues(discussionContainer);
body.attr.and.returnValue(''); body.attr.and.returnValue('');
Notes.prototype.renderDiscussionNote.call(notes, note, $form);
}); });
it('should call Notes.animateAppendNote', () => { it('should call Notes.animateAppendNote', () => {
Notes.prototype.renderDiscussionNote.call(notes, note, $form);
expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.discussion_html, $('.main-notes-list')); expect(Notes.animateAppendNote).toHaveBeenCalledWith(note.discussion_html, $('.main-notes-list'));
}); });
it('should append to row selected with line_code', () => {
$form.length = 0;
note.discussion_line_code = 'line_code';
note.diff_discussion_html = '<tr></tr>';
const line = document.createElement('div');
line.id = note.discussion_line_code;
document.body.appendChild(line);
$form.closest.and.returnValues($form);
Notes.prototype.renderDiscussionNote.call(notes, note, $form);
expect(line.nextSibling.outerHTML).toEqual(note.diff_discussion_html);
});
}); });
describe('Discussion sub note', () => { describe('Discussion sub note', () => {
......
...@@ -77,12 +77,24 @@ describe Gitlab::Ci::CronParser do ...@@ -77,12 +77,24 @@ describe Gitlab::Ci::CronParser do
it_behaves_like "returns time in the future" it_behaves_like "returns time in the future"
context 'when PST (Pacific Standard Time)' do
it 'converts time in server time zone' do it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 1, 1)) do
expect(subject.hour).to eq(hour_in_utc) expect(subject.hour).to eq(hour_in_utc)
end end
end end
end end
context 'when PDT (Pacific Daylight Time)' do
it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 6, 1)) do
expect(subject.hour).to eq(hour_in_utc)
end
end
end
end
end
context 'when cron_timezone is ActiveSupport::TimeZone format' do context 'when cron_timezone is ActiveSupport::TimeZone format' do
before do before do
allow(Time).to receive(:zone) allow(Time).to receive(:zone)
...@@ -100,10 +112,22 @@ describe Gitlab::Ci::CronParser do ...@@ -100,10 +112,22 @@ describe Gitlab::Ci::CronParser do
it_behaves_like "returns time in the future" it_behaves_like "returns time in the future"
context 'when CET (Central European Time)' do
it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 1, 1)) do
expect(subject.hour).to eq(hour_in_utc)
end
end
end
context 'when CEST (Central European Summer Time)' do
it 'converts time in server time zone' do it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 6, 1)) do
expect(subject.hour).to eq(hour_in_utc) expect(subject.hour).to eq(hour_in_utc)
end end
end end
end
end
context 'when cron_timezone is Eastern Time (US & Canada)' do context 'when cron_timezone is Eastern Time (US & Canada)' do
let(:cron) { '* 0 * * *' } let(:cron) { '* 0 * * *' }
...@@ -111,12 +135,24 @@ describe Gitlab::Ci::CronParser do ...@@ -111,12 +135,24 @@ describe Gitlab::Ci::CronParser do
it_behaves_like "returns time in the future" it_behaves_like "returns time in the future"
context 'when EST (Eastern Standard Time)' do
it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 1, 1)) do
expect(subject.hour).to eq(hour_in_utc)
end
end
end
context 'when EDT (Eastern Daylight Time)' do
it 'converts time in server time zone' do it 'converts time in server time zone' do
Timecop.freeze(Time.utc(2017, 6, 1)) do
expect(subject.hour).to eq(hour_in_utc) expect(subject.hour).to eq(hour_in_utc)
end end
end end
end end
end end
end
end
context 'when cron and cron_timezone are invalid' do context 'when cron and cron_timezone are invalid' do
let(:cron) { 'invalid_cron' } let(:cron) { 'invalid_cron' }
......
...@@ -559,10 +559,10 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -559,10 +559,10 @@ describe Gitlab::Git::Repository, seed_helper: true do
end end
end end
describe "#remote_delete" do describe "#remove_remote" do
before(:all) do before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
@repo.remote_delete("expendable") @repo.remove_remote("expendable")
end end
it "should remove the remote" do it "should remove the remote" do
...@@ -575,14 +575,16 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -575,14 +575,16 @@ describe Gitlab::Git::Repository, seed_helper: true do
end end
end end
describe "#remote_add" do describe "#remote_update" do
before(:all) do before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
@repo.remote_add("new_remote", SeedHelper::GITLAB_GIT_TEST_REPO_URL) @repo.remote_update("expendable", url: TEST_NORMAL_REPO_PATH)
end end
it "should add the remote" do it "should add the remote" do
expect(@repo.rugged.remotes.each_name.to_a).to include("new_remote") expect(@repo.rugged.remotes["expendable"].url).to(
eq(TEST_NORMAL_REPO_PATH)
)
end end
after(:all) do after(:all) do
...@@ -591,21 +593,58 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -591,21 +593,58 @@ describe Gitlab::Git::Repository, seed_helper: true do
end end
end end
describe "#remote_update" do describe '#fetch_mirror' do
before(:all) do let(:new_repository) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') Gitlab::Git::Repository.new('default', 'my_project.git', '')
@repo.remote_update("expendable", url: TEST_NORMAL_REPO_PATH)
end end
it "should add the remote" do subject { new_repository.fetch_mirror(repository.path) }
expect(@repo.rugged.remotes["expendable"].url).to(
eq(TEST_NORMAL_REPO_PATH) before do
) Gitlab::Shell.new.add_repository('default', 'my_project')
end end
after(:all) do after do
FileUtils.rm_rf(TEST_MUTABLE_REPO_PATH) Gitlab::Shell.new.remove_repository(TestEnv.repos_path, 'my_project')
ensure_seeds end
it 'fetches a url as a mirror remote' do
subject
expect(refs(new_repository.path)).to eq(refs(repository.path))
end
context 'with keep-around refs' do
let(:sha) { SeedRepo::Commit::ID }
let(:keep_around_ref) { "refs/keep-around/#{sha}" }
let(:tmp_ref) { "refs/tmp/#{SecureRandom.hex}" }
before do
repository.rugged.references.create(keep_around_ref, sha, force: true)
repository.rugged.references.create(tmp_ref, sha, force: true)
end
it 'includes the temporary and keep-around refs' do
subject
expect(refs(new_repository.path)).to include(keep_around_ref)
expect(refs(new_repository.path)).to include(tmp_ref)
end
end
end
describe '#remote_tags' do
let(:target_commit_id) { SeedRepo::Commit::ID }
subject { repository.remote_tags('upstream') }
it 'gets the remote tags' do
expect(repository).to receive(:list_remote_tags).with('upstream')
.and_return(["#{target_commit_id}\trefs/tags/v0.0.1\n"])
expect(subject.first).to be_an_instance_of(Gitlab::Git::Tag)
expect(subject.first.name).to eq('v0.0.1')
expect(subject.first.dereferenced_target.id).to eq(target_commit_id)
end end
end end
...@@ -1685,6 +1724,21 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -1685,6 +1724,21 @@ describe Gitlab::Git::Repository, seed_helper: true do
end end
end end
describe '#fetch' do
let(:git_path) { Gitlab.config.git.bin_path }
let(:remote_name) { 'my_remote' }
subject { repository.fetch(remote_name) }
it 'fetches the remote and returns true if the command was successful' do
expect(repository).to receive(:popen)
.with(%W(#{git_path} fetch #{remote_name}), repository.path)
.and_return(['', 0])
expect(subject).to be(true)
end
end
def create_remote_branch(repository, remote_name, branch_name, source_branch_name) def create_remote_branch(repository, remote_name, branch_name, source_branch_name)
source_branch = repository.branches.find { |branch| branch.name == source_branch_name } source_branch = repository.branches.find { |branch| branch.name == source_branch_name }
rugged = repository.rugged rugged = repository.rugged
...@@ -1760,4 +1814,10 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -1760,4 +1814,10 @@ describe Gitlab::Git::Repository, seed_helper: true do
sha = Rugged::Commit.create(repo, options) sha = Rugged::Commit.create(repo, options)
repo.lookup(sha) repo.lookup(sha)
end end
def refs(dir)
IO.popen(%W[git -C #{dir} for-each-ref], &:read).split("\n").map do |line|
line.split("\t").last
end
end
end end
...@@ -18,7 +18,6 @@ describe Environment do ...@@ -18,7 +18,6 @@ describe Environment do
it { is_expected.to validate_length_of(:slug).is_at_most(24) } it { is_expected.to validate_length_of(:slug).is_at_most(24) }
it { is_expected.to validate_length_of(:external_url).is_at_most(255) } it { is_expected.to validate_length_of(:external_url).is_at_most(255) }
it { is_expected.to validate_uniqueness_of(:external_url).scoped_to(:project_id) }
describe '.order_by_last_deployed_at' do describe '.order_by_last_deployed_at' do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
......
...@@ -2298,4 +2298,24 @@ describe Repository do ...@@ -2298,4 +2298,24 @@ describe Repository do
project.commit_by(oid: '1' * 40) project.commit_by(oid: '1' * 40)
end end
end end
describe '#raw_repository' do
subject { repository.raw_repository }
it 'returns a Gitlab::Git::Repository representation of the repository' do
expect(subject).to be_a(Gitlab::Git::Repository)
expect(subject.relative_path).to eq(project.disk_path + '.git')
expect(subject.gl_repository).to eq("project-#{project.id}")
end
context 'with a wiki repository' do
let(:repository) { project.wiki.repository }
it 'creates a Gitlab::Git::Repository with the proper attributes' do
expect(subject).to be_a(Gitlab::Git::Repository)
expect(subject.relative_path).to eq(project.disk_path + '.wiki.git')
expect(subject.gl_repository).to eq("wiki-#{project.id}")
end
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment