diff --git a/CHANGELOG b/CHANGELOG index aa14f49bc8e8307a6c95307a3f925b975c07eca2..27eef858d787ac6af4e8ccb0aa427d92ab24b788 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,7 @@ v 10.3.0 (unreleased) - Remove Repository#format_patch - Remove Repository#add_tag + - Rename a repository file v 10.2.3 - Handle nil blob data diff --git a/Gemfile b/Gemfile index 038a3e8df8c476479335eecc4d2dcc3053b07a25..394be07f7df19a7dc1878bb149d3970e1ff61b3b 100644 --- a/Gemfile +++ b/Gemfile @@ -4,6 +4,7 @@ gemspec group :development do gem 'rubocop' + gem 'rubocop-rspec', '~> 1.5.0' gem 'coveralls', require: false gem 'rspec', '~> 3.0' gem 'rspec-mocks' diff --git a/lib/gitlab_git/blob.rb b/lib/gitlab_git/blob.rb index 94c0307c5835984a212b88b9d8b89c2667a7f422..52d1138e4ed2a1964a1326a046db3947aba52a21 100644 --- a/lib/gitlab_git/blob.rb +++ b/lib/gitlab_git/blob.rb @@ -150,6 +150,12 @@ module Gitlab if action == :remove index.remove(filename) else + if action == :rename + old_path_name = PathHelper.normalize_path(file[:previous_path]) + old_filename = old_path_name.to_s + index.remove(old_filename) + end + mode = 0o100644 file_entry = index.get(filename) @@ -207,6 +213,35 @@ module Gitlab def remove(repository, options) commit(repository, options, :remove) end + + + # Rename file from repository and return commit sha + # + # options should contain next structure: + # file: { + # previous_path: 'documents/old_story.txt' + # path: 'documents/story.txt' + # content: 'Lorem ipsum...', + # update: true + # }, + # author: { + # email: 'user@example.com', + # name: 'Test User', + # time: Time.now + # }, + # committer: { + # email: 'user@example.com', + # name: 'Test User', + # time: Time.now + # }, + # commit: { + # message: 'Rename FILENAME', + # branch: 'master' + # } + # + def rename(repository, options) + commit(repository, options, :rename) + end end def initialize(options) diff --git a/spec/blob_spec.rb b/spec/blob_spec.rb index 6998ea37baf6c88c124d883f09c81775ef274cfd..0af42c9f0386b25c77acbf66523a729d1e0665fb 100644 --- a/spec/blob_spec.rb +++ b/spec/blob_spec.rb @@ -270,6 +270,57 @@ describe Gitlab::Git::Blob do end end + describe :rename do + let(:repository) { Gitlab::Git::Repository.new(TEST_NORMAL_REPO_PATH) } + + let(:commit_options) do + options = { + file: { + path: 'NEWREADME.md', + previous_path: 'README.md', + content: 'Lorem ipsum...', + update: true + }, + author: { + email: 'user@example.com', + name: 'Test User', + time: Time.now + }, + committer: { + email: 'user@example.com', + name: 'Test User', + time: Time.now + }, + commit: { + message: 'Rename readme', + branch: 'master' + } + } + end + + let!(:ref) { commit_options[:commit][:branch] } + let!(:prev_commit_count) { repository.commit_count(ref) } + let(:commit_sha) { Gitlab::Git::Blob.rename(repository, commit_options) } + let(:commit_count) { repository.commit_count(ref) } + let(:commit) { repository.lookup(commit_sha) } + let(:blob) { Gitlab::Git::Blob.find(repository, commit_sha, "NEWREADME.md") } + let(:removed_blob) { Gitlab::Git::Blob.find(repository, commit_sha, "README.md") } + + it 'should rename the file with commit' do + # Commit message valid + expect(commit.message).to eq('Rename readme') + + # Only one commit was made + expect(commit_count).to eq(prev_commit_count + 1) + + # Previous file was removed + expect(removed_blob).to be_nil + + # File was renamed + expect(blob).not_to be_nil + end + end + describe :remove do let(:repository) { Gitlab::Git::Repository.new(TEST_REPO_PATH) } @@ -295,17 +346,16 @@ describe Gitlab::Git::Blob do } end - let!(:commit_sha) { Gitlab::Git::Blob.remove(repository, commit_options) } - let!(:commit) { repository.lookup(commit_sha) } + let(:commit_sha) { Gitlab::Git::Blob.remove(repository, commit_options) } + let(:commit) { repository.lookup(commit_sha) } + let(:blob) { Gitlab::Git::Blob.find(repository, commit_sha, "README.md") } it 'should remove file with commit' do # Commit message valid expect(commit.message).to eq('Remove readme') # File was removed - expect(commit.tree.to_a.any? do |tree| - tree[:name] == 'README.md' - end).to be_falsey + expect(blob).to be_nil end end