diff --git a/Gemfile b/Gemfile
index 0504e643ed7681cc4f804bd9639a7da182ce57e3..74fb7b1a2af8500f701b6b86205912fea760867c 100644
--- a/Gemfile
+++ b/Gemfile
@@ -349,3 +349,4 @@ gem 'health_check', '~> 2.1.0'
 # System information
 gem 'vmstat', '~> 2.1.1'
 gem 'sys-filesystem', '~> 1.1.6'
+gem 'vuejs-rails'
diff --git a/Gemfile.lock b/Gemfile.lock
index 195516d1bf1a6b6a7db2a9917ab8179c7dd48ff4..e9068d1d69ef86f1cad9b00a4e5d8b73e7fa0099 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -776,6 +776,7 @@ GEM
       descendants_tracker (~> 0.0, >= 0.0.3)
       equalizer (~> 0.0, >= 0.0.9)
     vmstat (2.1.1)
+    vuejs-rails (1.0.24)
     warden (1.2.6)
       rack (>= 1.0)
     web-console (2.3.0)
@@ -980,7 +981,12 @@ DEPENDENCIES
   unicorn-worker-killer (~> 0.4.2)
   version_sorter (~> 2.0.0)
   virtus (~> 1.0.1)
+<<<<<<< HEAD
   vmstat (~> 2.1.1)
+=======
+  vmstat (~> 2.1.0)
+  vuejs-rails
+>>>>>>> Diff line comments resolve
   web-console (~> 2.0)
   webmock (~> 1.21.0)
   wikicloth (= 0.8.1)
diff --git a/app/assets/javascripts/line_comments/application.js.coffee b/app/assets/javascripts/line_comments/application.js.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..396416efb7864f252b1f3bbf67562e7f84d9f533
--- /dev/null
+++ b/app/assets/javascripts/line_comments/application.js.coffee
@@ -0,0 +1,6 @@
+#= require vue
+#= require_directory ./components
+
+$ ->
+  new Vue
+    el: '#notes'
diff --git a/app/assets/javascripts/line_comments/components/line_btn.js.coffee b/app/assets/javascripts/line_comments/components/line_btn.js.coffee
new file mode 100644
index 0000000000000000000000000000000000000000..3abcd41df1eb34a2d86e2c68c814b9223a066e65
--- /dev/null
+++ b/app/assets/javascripts/line_comments/components/line_btn.js.coffee
@@ -0,0 +1,19 @@
+LineBtn = Vue.extend
+  props:
+    noteId: Number
+    resolved: Boolean
+  computed:
+    buttonText: ->
+      if this.resolved then "Mark as un-resolved" else "Mark as resolved"
+  methods:
+    updateTooltip: ->
+      $(this.$el)
+        .tooltip('hide')
+        .tooltip('fixTitle')
+    resolve: ->
+      this.$set('resolved', !this.resolved)
+      this.$nextTick this.updateTooltip
+  compiled: ->
+    $(this.$el).tooltip()
+
+Vue.component 'line-btn', LineBtn
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index a2b5437e5031080ed00835470d1967fd7d17bf70..49331aa641a4231c72958519c46e100895f360f7 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -383,3 +383,47 @@ ul.notes {
     color: $gl-link-color;
   }
 }
+
+.line-resolve-all {
+  padding: 10px;
+  border: 1px solid $border-color;
+  border-radius: 2px;
+
+  .btn {
+  	margin-right: 10px;
+  }
+}
+
+.line-resolve-text {
+  vertical-align: middle;
+}
+
+.line-resolve-btn {
+  position: relative;
+  top: -1px;
+  width: 14px;
+  height: 14px;
+  padding: 0;
+  background-color: transparent;
+  border: 1px solid #c3c3c3;
+  border-radius: 50%;
+  outline: 0;
+  vertical-align: middle;
+
+  &:hover,
+  &.is-active {
+    color: #fff;
+    background-color: $gl-text-green;
+    border-color: $gl-text-green;
+
+    .fa {
+      color: #fff;
+    }
+  }
+
+  .fa {
+    top: 2px;
+    font-size: 8px;
+    vertical-align: top;
+  }
+}
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index 873ed9b59ee4c86237f29c0b430196cbf5b54be1..f7f7182b2a0c11828a418e3aaedbd992c1737b26 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -1,6 +1,8 @@
 - page_title           "#{@merge_request.title} (#{@merge_request.to_reference})", "Merge Requests"
 - page_description     @merge_request.description
 - page_card_attributes @merge_request.card_attributes
+- content_for :page_specific_javascripts do
+  = page_specific_javascript_tag('line_comments/application.js')
 
 - if diff_view == 'parallel'
   - fluid_layout true
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 71da8ac9d7c1e582cb4ac456c099564dd47678ff..9b1eb8545e5cc256a913a4b9c42d849d11b41a34 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -20,6 +20,10 @@
           - access = note_max_access_for_user(note)
           - if access and not note.system
             %span.note-role.hidden-xs= access
+          - unless note.system
+            %line-btn{ ":note-id" => note.id, ":resolved" => "false", "inline-template" => true }
+              %button.note-action-button.line-resolve-btn{ type: "button", "v-bind:class" => "{ 'is-active': resolved }", "v-bind:aria-label" => "buttonText", "v-on:click" => "resolve", "v-bind:title" => "buttonText" }
+                = icon("check")
           - if current_user and not note.system
             = link_to '#', title: 'Award Emoji', class: 'note-action-button note-emoji-button js-add-award js-note-emoji', data: { position: 'right' } do
               = icon('spinner spin')
diff --git a/config/application.rb b/config/application.rb
index 06ebb14a5fea258e2a6bdbfff6cb6319e2a81a69..54c82bbcf26f4a1d872dc5edd9d65970015e534d 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -85,6 +85,7 @@ module Gitlab
     config.assets.precompile << "users/users_bundle.js"
     config.assets.precompile << "network/network_bundle.js"
     config.assets.precompile << "profile/profile_bundle.js"
+    config.assets.precompile << "line_comments/application.js"
     config.assets.precompile << "lib/utils/*.js"
     config.assets.precompile << "lib/*.js"
     config.assets.precompile << "u2f.js"