From d09fdfd6c72e544fa3156a13cad59a791e977dce Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Wed, 25 Jan 2017 23:13:09 -0800 Subject: Fix Error 500 when repositories contain annotated tags pointing to blobs In repositories such as https://github.com/git/git.git, annotated tags can point to blobs, not necessarily to commits. `Repository` attempts to return the tags in the order of the commit date, but if a commit is not available the previous implementation would error due to a `nil` target. This change modifies the code to use the current time if a commit is not associated with the given tag. Closes #27228 --- app/models/repository.rb | 13 +++++++++++- .../sh-fix-annotated-tags-pointing-to-blob.yml | 4 ++++ spec/models/repository_spec.rb | 24 ++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 changelogs/unreleased/sh-fix-annotated-tags-pointing-to-blob.yml diff --git a/app/models/repository.rb b/app/models/repository.rb index 43dba86e5ed..d77b7692d75 100644 --- a/app/models/repository.rb +++ b/app/models/repository.rb @@ -1188,7 +1188,18 @@ class Repository end def tags_sorted_by_committed_date - tags.sort_by { |tag| tag.dereferenced_target.committed_date } + tags.sort_by do |tag| + # Annotated tags can point to any object (e.g. a blob), but generally + # tags point to a commit. If we don't have a commit, then just default + # to putting the tag at the end of the list. + target = tag.dereferenced_target + + if target + target.committed_date + else + Time.now + end + end end def keep_around_ref_name(sha) diff --git a/changelogs/unreleased/sh-fix-annotated-tags-pointing-to-blob.yml b/changelogs/unreleased/sh-fix-annotated-tags-pointing-to-blob.yml new file mode 100644 index 00000000000..ff2b38f21f2 --- /dev/null +++ b/changelogs/unreleased/sh-fix-annotated-tags-pointing-to-blob.yml @@ -0,0 +1,4 @@ +--- +title: Fix Error 500 when repositories contain annotated tags pointing to blobs +merge_request: +author: diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb index 99ca53938c8..b91fbc1a845 100644 --- a/spec/models/repository_spec.rb +++ b/spec/models/repository_spec.rb @@ -90,6 +90,30 @@ describe Repository, models: true do it { is_expected.to eq(['v1.1.0', 'v1.0.0']) } end + + context 'annotated tag pointing to a blob' do + let(:annotated_tag_name) { 'annotated-tag' } + + subject { repository.tags_sorted_by('updated_asc').map(&:name) } + + before do + options = { message: 'test tag message\n', + tagger: { name: 'John Smith', email: 'john@gmail.com' } } + repository.rugged.tags.create(annotated_tag_name, 'a48e4fc218069f68ef2e769dd8dfea3991362175', options) + + double_first = double(committed_date: Time.now - 1.second) + double_last = double(committed_date: Time.now) + + allow(tag_a).to receive(:dereferenced_target).and_return(double_last) + allow(tag_b).to receive(:dereferenced_target).and_return(double_first) + end + + it { is_expected.to eq(['v1.1.0', 'v1.0.0', annotated_tag_name]) } + + after do + repository.rugged.tags.delete(annotated_tag_name) + end + end end end -- cgit v1.2.1