diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl
index 15eff8109..8482c31cd 100644
--- a/templates/repo/diff/box.tmpl
+++ b/templates/repo/diff/box.tmpl
@@ -143,7 +143,7 @@
 													{{$.locale.Tr "repo.diff.file_suppressed_line_too_long"}}
 												{{else}}
 													{{$.locale.Tr "repo.diff.file_suppressed"}}
-													<a class="ui basic tiny button diff-show-more-button" data-href="{{$.Link}}?file-only=true&files={{$file.Name}}&files={{$file.OldName}}">{{$.locale.Tr "repo.diff.load"}}</a>
+													<a class="ui basic tiny button diff-load-button" data-href="{{$.Link}}?file-only=true&files={{$file.Name}}&files={{$file.OldName}}">{{$.locale.Tr "repo.diff.load"}}</a>
 												{{end}}
 											{{else}}
 												{{$.locale.Tr "repo.diff.bin_not_shown"}}
diff --git a/web_src/js/components/DiffFileTree.vue b/web_src/js/components/DiffFileTree.vue
index e592574ac..6d77b2024 100644
--- a/web_src/js/components/DiffFileTree.vue
+++ b/web_src/js/components/DiffFileTree.vue
@@ -8,7 +8,7 @@
       <DiffFileTreeItem v-for="item in fileTree" :key="item.name" :item="item" />
     </div>
     <div v-if="isIncomplete" id="diff-too-many-files-stats" class="pt-2">
-      <span>{{ tooManyFilesMessage }}</span><a :class="['ui', 'basic', 'tiny', 'button', isLoadingNewData === true ? 'disabled' : '']" id="diff-show-more-files-stats" @click.stop="loadMoreData">{{ showMoreMessage }}</a>
+      <span class="mr-2">{{ tooManyFilesMessage }}</span><a :class="['ui', 'basic', 'tiny', 'button', isLoadingNewData === true ? 'disabled' : '']" id="diff-show-more-files-stats" @click.stop="loadMoreData">{{ showMoreMessage }}</a>
     </div>
   </div>
 </template>
@@ -94,6 +94,9 @@ export default {
   mounted() {
     // ensure correct buttons when we are mounted to the dom
     this.adjustToggleButton(this.fileTreeIsVisible);
+    // replace the pageData.diffFileInfo.files with our watched data so we get updates
+    pageData.diffFileInfo.files = this.files;
+
     document.querySelector('.diff-toggle-file-tree-button').addEventListener('click', this.toggleVisibility);
   },
   unmounted() {
diff --git a/web_src/js/features/repo-diff.js b/web_src/js/features/repo-diff.js
index 0fb7ee22d..9b5da7de8 100644
--- a/web_src/js/features/repo-diff.js
+++ b/web_src/js/features/repo-diff.js
@@ -119,26 +119,47 @@ function onShowMoreFiles() {
 
 export function doLoadMoreFiles(link, diffEnd, callback) {
   const url = `${link}?skip-to=${diffEnd}&file-only=true`;
+  loadMoreFiles(url, callback);
+}
+
+function loadMoreFiles(url, callback) {
+  const $target = $('a#diff-show-more-files');
+  if ($target.hasClass('disabled')) {
+    callback();
+    return;
+  }
+  $target.addClass('disabled');
   $.ajax({
     type: 'GET',
     url,
   }).done((resp) => {
     if (!resp) {
+      $target.removeClass('disabled');
       callback(resp);
       return;
     }
+    $('#diff-incomplete').replaceWith($(resp).find('#diff-file-boxes').children());
     // By simply rerunning the script we add the new data to our existing
     // pagedata object. this triggers vue and the filetree and filelist will
     // render the new elements.
     $('body').append($(resp).find('script#diff-data-script'));
+    onShowMoreFiles();
     callback(resp);
   }).fail(() => {
+    $target.removeClass('disabled');
     callback();
   });
 }
 
 export function initRepoDiffShowMore() {
-  $(document).on('click', 'a.diff-show-more-button', (e) => {
+  $(document).on('click', 'a#diff-show-more-files', (e) => {
+    e.preventDefault();
+
+    const $target = $(e.target);
+    loadMoreFiles($target.data('href'), () => {});
+  });
+
+  $(document).on('click', 'a.diff-load-button', (e) => {
     e.preventDefault();
     const $target = $(e.target);
 
diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less
index 3ceb9e30c..646cf4e60 100644
--- a/web_src/less/_repository.less
+++ b/web_src/less/_repository.less
@@ -1667,6 +1667,9 @@
         background-color: var(--color-teal);
       }
     }
+    .button {
+      padding: 8px 12px;
+    }
   }
 
   .diff-box .header:not(.resolved-placeholder) {