diff --git a/CHANGELOG b/CHANGELOG
index 943e4e8c586e674709c91bb10241b25faf9f11aa..df8e9a48474a75b47c3970134ba0aa7d9a6d9cde 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
 Please view this file on the master branch, on stable branches it's out of date.
 
 v 7.14.0 (unreleased)
+  - Fix "Network" and "Graphs" pages for branches with encoded slashes (Stan Hu)
+  - Fix errors deleting and creating branches with encoded slashes (Stan Hu)
   - Fix multi-line syntax highlighting (Stan Hu)
   - Fix network graph when branch name has single quotes (Stan Hu)
   - Add "Confirm user" button in user admin page (Stan Hu)
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 117ae3aaa3d469e1260f5f6f9dd3639d4b9ab21c..3ac0a75fa709936ccdb384add23bcbb90de5125b 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -17,7 +17,9 @@ class Projects::BranchesController < Projects::ApplicationController
 
   def create
     branch_name = sanitize(strip_tags(params[:branch_name]))
+    branch_name = Addressable::URI.unescape(branch_name)
     ref = sanitize(strip_tags(params[:ref]))
+    ref = Addressable::URI.unescape(ref)
     result = CreateBranchService.new(project, current_user).
         execute(branch_name, ref)
 
@@ -32,9 +34,8 @@ class Projects::BranchesController < Projects::ApplicationController
   end
 
   def destroy
-    status = DeleteBranchService.new(project, current_user).execute(params[:id])
-    @branch_name = params[:id]
-
+    @branch_name = Addressable::URI.unescape(params[:id])
+    status = DeleteBranchService.new(project, current_user).execute(@branch_name)
     respond_to do |format|
       format.html do
         redirect_to namespace_project_branches_path(@project.namespace,
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index 3f420553d42596100fa391885e13d2db3e6ba333..322aed5e27c33e61b071ae87f6407677619673f5 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -94,7 +94,7 @@ module ExtractsPath
     @options = params.select {|key, value| allowed_options.include?(key) && !value.blank? }
     @options = HashWithIndifferentAccess.new(@options)
 
-    @id = get_id
+    @id = Addressable::URI.unescape(get_id)
     @ref, @path = extract_ref(@id)
     @repo = @project.repository
     if @options[:extended_sha1].blank?
diff --git a/spec/controllers/branches_controller_spec.rb b/spec/controllers/branches_controller_spec.rb
index bd4c946b64b8700bf82d83849adf9eefb09bcd42..8e06d4bdc77693546dc679ddee5c53df184f19af 100644
--- a/spec/controllers/branches_controller_spec.rb
+++ b/spec/controllers/branches_controller_spec.rb
@@ -54,6 +54,13 @@ describe Projects::BranchesController do
       let(:ref) { "<script>alert('ref');</script>" }
       it { is_expected.to render_template('new') }
     end
+
+    context "valid branch name with encoded slashes" do
+      let(:branch) { "feature%2Ftest" }
+      let(:ref) { "<script>alert('ref');</script>" }
+      it { is_expected.to render_template('new') }
+      it { project.repository.branch_names.include?('feature/test')}
+    end
   end
 
   describe "POST destroy" do
@@ -74,6 +81,19 @@ describe Projects::BranchesController do
       it { expect(subject).to render_template('destroy') }
     end
 
+    context "valid branch name with unencoded slashes" do
+      let(:branch) { "improve/awesome" }
+
+      it { expect(response.status).to eq(200) }
+      it { expect(subject).to render_template('destroy') }
+    end
+
+    context "valid branch name with encoded slashes" do
+      let(:branch) { "improve%2Fawesome" }
+
+      it { expect(response.status).to eq(200) }
+      it { expect(subject).to render_template('destroy') }
+    end
     context "invalid branch name, valid ref" do
       let(:branch) { "no-branch" }
 
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index 4439775f612965b09f9d52762590b4829a7df4ad..9c115bbfc6a0a86d1d86bdeeca4e5ce05b1d16a4 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -29,6 +29,16 @@ describe ExtractsPath do
       assign_ref_vars
       expect(@logs_path).to eq("/#{@project.path_with_namespace}/refs/#{ref}/logs_tree/files/ruby/popen.rb")
     end
+
+    context 'escaped sequences in ref' do
+      let(:ref) { "improve%2Fawesome" }
+
+      it "id should have no escape sequences" do
+        assign_ref_vars
+        expect(@ref).to eq('improve/awesome')
+        expect(@logs_path).to eq("/#{@project.path_with_namespace}/refs/#{ref}/logs_tree/files/ruby/popen.rb")
+      end
+    end
   end
 
   describe '#extract_ref' do