diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index 6725964f5..5ec001b6d 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -1041,6 +1041,7 @@ line_unicode = `This line has hidden unicode characters`
 escape_control_characters = Escape
 unescape_control_characters = Unescape
 file_copy_permalink = Copy Permalink
+view_git_blame = View Git Blame
 video_not_supported_in_browser = Your browser does not support the HTML5 'video' tag.
 audio_not_supported_in_browser = Your browser does not support the HTML5 'audio' tag.
 stored_lfs = Stored with Git LFS
@@ -3088,7 +3089,7 @@ settings.link = Link this package to a repository
 settings.link.description = If you link a package with a repository, the package is listed in the repository's package list.
 settings.link.select = Select Repository
 settings.link.button = Update Repository Link
-settings.link.success = Repository link was successfully updated. 
+settings.link.success = Repository link was successfully updated.
 settings.link.error = Failed to update repository link.
 settings.delete = Delete package
 settings.delete.description = Deleting a package is permanent and cannot be undone.
diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl
index 9e1d83b83..c5efd3d2d 100644
--- a/templates/repo/view_file.tmpl
+++ b/templates/repo/view_file.tmpl
@@ -128,6 +128,9 @@
 									<a class="item ref-in-new-issue" href="{{.RepoLink}}/issues/new?body={{.Repository.HTMLURL}}{{printf "/src/commit/" }}{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}" rel="nofollow noindex">{{.i18n.Tr "repo.issues.context.reference_issue"}}</a>
 								</div>
 							{{end}}
+							<div class="ui link list">
+								<a class="item view_git_blame" href="{{.Repository.HTMLURL}}/blame/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}">{{.i18n.Tr "repo.view_git_blame"}}</a>
+							</div>
 							<div class="ui link list">
 								<a data-clipboard-text="{{.Repository.HTMLURL}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}" class="item copy-line-permalink">{{.i18n.Tr "repo.file_copy_permalink"}}</a>
 							</div>
diff --git a/web_src/js/features/repo-code.js b/web_src/js/features/repo-code.js
index a4b6e433a..d7b4baac8 100644
--- a/web_src/js/features/repo-code.js
+++ b/web_src/js/features/repo-code.js
@@ -15,10 +15,7 @@ function selectRange($list, $select, $from) {
   // add hashchange to permalink
   const $issue = $('a.ref-in-new-issue');
   const $copyPermalink = $('a.copy-line-permalink');
-
-  if ($copyPermalink.length === 0) {
-    return;
-  }
+  const $viewGitBlame = $('a.view_git_blame');
 
   const updateIssueHref = function (anchor) {
     if ($issue.length === 0) {
@@ -29,7 +26,22 @@ function selectRange($list, $select, $from) {
     $issue.attr('href', href);
   };
 
+  const updateViewGitBlameFragment = function (anchor) {
+    if ($viewGitBlame.length === 0) {
+      return;
+    }
+    let href = $viewGitBlame.attr('href');
+    href = `${href.replace(/#L\d+$|#L\d+-L\d+$/, '')}`;
+    if (anchor.length !== 0) {
+      href = `${href}#${anchor}`;
+    }
+    $viewGitBlame.attr('href', href);
+  };
+
   const updateCopyPermalinkHref = function(anchor) {
+    if ($copyPermalink.length === 0) {
+      return;
+    }
     let link = $copyPermalink.attr('data-clipboard-text');
     link = `${link.replace(/#L\d+$|#L\d+-L\d+$/, '')}#${anchor}`;
     $copyPermalink.attr('data-clipboard-text', link);
@@ -53,6 +65,7 @@ function selectRange($list, $select, $from) {
       changeHash(`#L${a}-L${b}`);
 
       updateIssueHref(`L${a}-L${b}`);
+      updateViewGitBlameFragment(`L${a}-L${b}`);
       updateCopyPermalinkHref(`L${a}-L${b}`);
       return;
     }
@@ -61,6 +74,7 @@ function selectRange($list, $select, $from) {
   changeHash(`#${$select.attr('rel')}`);
 
   updateIssueHref($select.attr('rel'));
+  updateViewGitBlameFragment($select.attr('rel'));
   updateCopyPermalinkHref($select.attr('rel'));
 }