From d97beec1d4cc773dd8fb8a5245efb040235f86b1 Mon Sep 17 00:00:00 2001 From: Go MAEDA Date: Sun, 30 Apr 2023 04:00:57 +0000 Subject: [PATCH] Add "View annotation prior to this change" button in the annotate view of Git (#35432). Patch by Takenori TAKAKI. git-svn-id: https://svn.redmine.org/redmine/trunk@22217 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- app/controllers/repositories_controller.rb | 4 ++++ app/views/repositories/annotate.html.erb | 8 ++++++++ config/locales/en.yml | 1 + lib/redmine/scm/adapters/abstract_adapter.rb | 6 ++++-- lib/redmine/scm/adapters/git_adapter.rb | 6 +++++- public/stylesheets/scm.css | 7 +++++++ test/functional/repositories_git_controller_test.rb | 5 +++++ test/unit/lib/redmine/scm/adapters/git_adapter_test.rb | 4 ++++ 8 files changed, 38 insertions(+), 3 deletions(-) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index c143ed233..9ef62edd1 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -208,6 +208,10 @@ class RepositoriesController < ApplicationController elsif @annotate.lines.sum(&:size) > Setting.file_max_size_displayed.to_i.kilobyte @annotate = nil @error_message = l(:error_scm_annotate_big_text_file) + else + # the SCM adapter supports "View annotation prior to this change" links + # and the entry has previous annotations + @has_previous = @annotate.previous_annotations.any? end @changeset = @repository.find_changeset_by_name(@rev) end diff --git a/app/views/repositories/annotate.html.erb b/app/views/repositories/annotate.html.erb index de30e7c00..db91ef913 100644 --- a/app/views/repositories/annotate.html.erb +++ b/app/views/repositories/annotate.html.erb @@ -16,6 +16,7 @@ <% line_num = 1; previous_revision = nil %> <% syntax_highlight_lines(@path, Redmine::CodesetUtil.to_utf8_by_setting(@annotate.content)).each do |line| %> <% revision = @annotate.revisions[line_num - 1] %> + <% previous_annot = @annotate.previous_annotations[line_num - 1] %> @@ -31,6 +32,13 @@ <%= author.split('<').first %> <% end %> + <% if @has_previous %> + + <% if previous_annot && revision && revision != previous_revision %> + <%= link_to '', {:action => 'annotate', :id => @project, :repository_id => @repository.identifier_param, :path => to_path_param(previous_annot.split[1] || @path), :rev => previous_annot.split[0] }, :title => l(:label_view_previous_annotation), :class => 'icon icon-history' %> + <% end %> + + <% end %> <% if line == "\n" or line == "\r\n" %>
<% else %> diff --git a/config/locales/en.yml b/config/locales/en.yml index a6bf316d4..637fe8a12 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -838,6 +838,7 @@ en: label_latest_revision_plural: Latest revisions label_view_revisions: View revisions label_view_all_revisions: View all revisions + label_view_previous_annotation: View annotation prior to this change label_x_revisions: "%{count} revisions" label_max_size: Maximum size label_roadmap: Roadmap diff --git a/lib/redmine/scm/adapters/abstract_adapter.rb b/lib/redmine/scm/adapters/abstract_adapter.rb index 88a62fd6d..8e74086c5 100644 --- a/lib/redmine/scm/adapters/abstract_adapter.rb +++ b/lib/redmine/scm/adapters/abstract_adapter.rb @@ -423,16 +423,18 @@ module Redmine end class Annotate - attr_reader :lines, :revisions + attr_reader :lines, :revisions, :previous_annotations def initialize @lines = [] @revisions = [] + @previous_annotations = [] end - def add_line(line, revision) + def add_line(line, revision, previous=nil) @lines << line @revisions << revision + @previous_annotations << previous end def content diff --git a/lib/redmine/scm/adapters/git_adapter.rb b/lib/redmine/scm/adapters/git_adapter.rb index 0c916c283..f4c3902e2 100644 --- a/lib/redmine/scm/adapters/git_adapter.rb +++ b/lib/redmine/scm/adapters/git_adapter.rb @@ -376,11 +376,14 @@ module Redmine identifier = '' # git shows commit author on the first occurrence only authors_by_commit = {} + prev_blames_by_commit = {} content.split("\n").each do |line| if line =~ /^([0-9a-f]{39,40})\s.*/ identifier = $1 elsif line =~ /^author (.+)/ authors_by_commit[identifier] = $1.strip + elsif line =~ /^previous (.+)/ + prev_blames_by_commit[identifier] = $1.strip elsif line =~ /^\t(.*)/ blame.add_line( $1, @@ -389,7 +392,8 @@ module Redmine :revision => identifier, :scmid => identifier, :author => authors_by_commit[identifier] - ) + ), + prev_blames_by_commit[identifier] ) identifier = '' author = '' diff --git a/public/stylesheets/scm.css b/public/stylesheets/scm.css index 2d39482d8..4711a2e5a 100644 --- a/public/stylesheets/scm.css +++ b/public/stylesheets/scm.css @@ -116,6 +116,13 @@ table.annotate td.author { background: inherit; } +table.annotate td.previous { + padding: 0; + text-align: center; + width: 1%; + background: inherit; +} + table.annotate td.line-code { background-color: #fafafa; border-left: 6px solid #d7d7d7; diff --git a/test/functional/repositories_git_controller_test.rb b/test/functional/repositories_git_controller_test.rb index 01f745de6..5367c3cf2 100644 --- a/test/functional/repositories_git_controller_test.rb +++ b/test/functional/repositories_git_controller_test.rb @@ -589,9 +589,14 @@ class RepositoriesGitControllerTest < Redmine::RepositoryControllerTest # Line 23, changeset 2f9c0091 assert_select 'tr' do + prev_blame, path = '4a79347ea4b7184938d9bbea0fd421a6079f71bb', 'sources/watchers_controller.rb' assert_select 'th.line-num a[data-txt=?]', '23' assert_select 'td.revision', :text => /2f9c0091/ assert_select 'td.author', :text => 'jsmith' + assert_select 'td.previous' do + assert_select 'a.icon-history[href=?]', + "/projects/subproject1/repository/#{@repository.id}/revisions/#{prev_blame}/annotate/#{path}" + end assert_select 'td', :text => /remove_watcher/ end end diff --git a/test/unit/lib/redmine/scm/adapters/git_adapter_test.rb b/test/unit/lib/redmine/scm/adapters/git_adapter_test.rb index b81261c41..68bc37def 100644 --- a/test/unit/lib/redmine/scm/adapters/git_adapter_test.rb +++ b/test/unit/lib/redmine/scm/adapters/git_adapter_test.rb @@ -437,6 +437,10 @@ class GitAdapterTest < ActiveSupport::TestCase assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", annotate.revisions[4].identifier assert_equal "jsmith", annotate.revisions[4].author + assert_equal "4a79347ea4b7184938d9bbea0fd421a6079f71bb", + annotate.previous_annotations[22].split[0] + assert_equal "sources/watchers_controller.rb", + annotate.previous_annotations[22].split[1] end def test_annotate_latin_1_identifier -- 2.39.5