diff --git a/config/routes.rb b/config/routes.rb
index 6f0318c029744b4be5a68e0b8d11d35f4f89e9be..a345b007b2393d79c4fae91fa120f1b23639ff4d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -27,10 +27,14 @@ Rails.application.routes.draw do
                 authorizations: 'oauth/authorizations'
   end
 
-  scope path: '/-/jira/login/oauth', controller: 'oauth/jira/authorizations', as: :oauth_jira do
+  # This prefixless path is required because Jira gets confused if we set it up with a path
+  # More information: https://gitlab.com/gitlab-org/gitlab-ee/issues/6752
+  scope path: '/login/oauth', controller: 'oauth/jira/authorizations', as: :oauth_jira do
     get :authorize, action: :new
     get :callback
     post :access_token
+    # This helps minimize merge conflicts with CE for this scope block
+    match ':action', via: [:get, :post], to: proc { [404, {}, ['']] }
   end
 
   namespace :oauth do
diff --git a/db/post_migrate/20180816193530_rename_login_root_namespaces.rb b/db/post_migrate/20180816193530_rename_login_root_namespaces.rb
new file mode 100644
index 0000000000000000000000000000000000000000..60cec24eed64335ea689af04ec354914c4148026
--- /dev/null
+++ b/db/post_migrate/20180816193530_rename_login_root_namespaces.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+class RenameLoginRootNamespaces < ActiveRecord::Migration
+  include Gitlab::Database::MigrationHelpers
+  include Gitlab::Database::RenameReservedPathsMigration::V1
+
+  DOWNTIME = false
+
+  # We're taking over the /login namespace as part of a fix for the Jira integration
+  def up
+    rename_root_paths 'login'
+  end
+
+  def down
+    revert_renames
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index a74882e19e2dc935efde66148824874380166207..49e44b97d394c02aea2d5517425e8091bafc36f2 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 20180809195358) do
+ActiveRecord::Schema.define(version: 20180816193530) do
 
   # These are extensions that must be enabled in order to support this database
   enable_extension "plpgsql"
diff --git a/doc/integration/img/jira_dev_panel_gl_setup_1.png b/doc/integration/img/jira_dev_panel_gl_setup_1.png
index 1bee7a291a7be2165e4efa5ef100f94c29a66a7e..a8eb37f4b54149449163c25134fa634ce963265d 100644
Binary files a/doc/integration/img/jira_dev_panel_gl_setup_1.png and b/doc/integration/img/jira_dev_panel_gl_setup_1.png differ
diff --git a/doc/integration/img/jira_dev_panel_jira_setup_2.png b/doc/integration/img/jira_dev_panel_jira_setup_2.png
index 5737785f97200887f4e95f40e2ef74df2b1466f7..535627005ddee8135defadae345a5be5a193b450 100644
Binary files a/doc/integration/img/jira_dev_panel_jira_setup_2.png and b/doc/integration/img/jira_dev_panel_jira_setup_2.png differ
diff --git a/doc/integration/jira_development_panel.md b/doc/integration/jira_development_panel.md
index a9f03aea0443b62109be7ff5719d1d9b6ce28a5c..add1e237fe13432cb98ef8bdb297a11d0f487078 100644
--- a/doc/integration/jira_development_panel.md
+++ b/doc/integration/jira_development_panel.md
@@ -31,9 +31,9 @@ account, in order to maximize the integrated GitLab projects used by your team.
 
     Enter a useful name for the `Name` field.
 
-    For the `Redirect URI` field, enter `https://<your-gitlab-instance-domain>/-/jira/login/oauth/callback`,
+    For the `Redirect URI` field, enter `https://<your-gitlab-instance-domain>/login/oauth/callback`,
     replacing `<your-gitlab-instance-domain>` appropriately. So for example, if you are using GitLab.com,
-    this would be `https://gitlab.com/-/jira/login/oauth/callback`.
+    this would be `https://gitlab.com/login/oauth/callback`.
 
     ![GitLab Application setup](img/jira_dev_panel_gl_setup_1.png)
     - Check `api` in the Scopes section.
@@ -58,9 +58,9 @@ from the left navigation menu. Click `Link GitHub account` to start creating a n
 
     ![Creation of Jira DVCS integration](img/jira_dev_panel_jira_setup_2.png)
 
-    For the `Host URL` field, enter `https://<your-gitlab-instance-domain>/-/jira`,
+    For the `Host URL` field, enter `https://<your-gitlab-instance-domain>/`,
     replacing `<your-gitlab-instance-domain>` appropriately. So for example, if you are using GitLab.com,
-    this would be `https://gitlab.com/-/jira`.
+    this would be `https://gitlab.com/`.
 
     For the `Client ID` field, use the `Application ID` value from the previous section.
 
diff --git a/ee/changelogs/unreleased/6752-jira-branches.yml b/ee/changelogs/unreleased/6752-jira-branches.yml
new file mode 100644
index 0000000000000000000000000000000000000000..52ed58cc1711344a47556c944dce15dbb7addc3f
--- /dev/null
+++ b/ee/changelogs/unreleased/6752-jira-branches.yml
@@ -0,0 +1,5 @@
+---
+title: Fix Jira integration duplicating branches and MRs
+merge_request: 6876
+author:
+type: fixed
diff --git a/ee/lib/api/v3/github.rb b/ee/lib/api/v3/github.rb
index 6f37d4c74f26e320102f6977fd4fa692f8f41c2a..181b04370a121bae4709ceafdc3cd391bc126f2c 100644
--- a/ee/lib/api/v3/github.rb
+++ b/ee/lib/api/v3/github.rb
@@ -98,30 +98,42 @@ module API
       # Jira handles the filtering, presenting just MRs mentioning the Jira
       # issue ID on the MR title / description.
       resource :repos do
+        # Keeping for backwards compatibility with old Jira integration instructions
+        # so that users that do not change it will not suddenly have a broken integration
         get '/-/jira/pulls' do
           present find_merge_requests, with: ::API::Github::Entities::PullRequest
         end
 
+        params do
+          use :project_full_path
+        end
+        get ':namespace/:project/pulls', requirements: PROJECT_ENDPOINT_REQUIREMENTS do
+          user_project = find_project_with_access(params)
+
+          merge_requests = MergeRequestsFinder.new(current_user, authorized_only: true, project_id: user_project.id).execute
+
+          present paginate(merge_requests), with: ::API::Github::Entities::PullRequest
+        end
+
         # In Github, each Merge Request is automatically also an issue.
         # Therefore we return its comments here.
         # It'll present _just_ the comments counting with a link to GitLab on
         # Jira dev panel, not the actual note content.
-        #
-        get '/-/jira/issues/:id/comments' do
+        get ':namespace/:project/issues/:id/comments' do
           merge_request = find_merge_request_with_access(params[:id])
 
           present find_notes(merge_request), with: ::API::Github::Entities::NoteableComment
         end
 
-        # This refers to "review" comments but Jira dev panel doesn't seem to
+        # This refer to "review" comments but Jira dev panel doesn't seem to
         # present it accordingly.
-        get '/-/jira/pulls/:id/comments' do
+        get ':namespace/:project/pulls/:id/comments' do
           present []
         end
 
         # Commits are not presented within "Pull Requests" modal on Jira dev
         # panel.
-        get '/-/jira/pulls/:id/commits' do
+        get ':namespace/:project/pulls/:id/commits' do
           present []
         end
 
@@ -129,7 +141,7 @@ module API
         # after fetching branches.
         # We need to respond with a 200 request to avoid breaking the
         # integration flow (fetching merge requests).
-        get '/-/jira/events' do
+        get ':namespace/:project/events' do
           present []
         end
 
diff --git a/ee/spec/controllers/oauth/jira/authorizations_controller_spec.rb b/ee/spec/controllers/oauth/jira/authorizations_controller_spec.rb
index 0e2b3b07f270d3701592e18c5af34c6113d6700b..c05e0cb78241eb4ad92ce315ea7a0e85aa9d50bd 100644
--- a/ee/spec/controllers/oauth/jira/authorizations_controller_spec.rb
+++ b/ee/spec/controllers/oauth/jira/authorizations_controller_spec.rb
@@ -35,7 +35,7 @@ describe Oauth::Jira::AuthorizationsController do
                                'client_id' => 'client-123',
                                'client_secret' => 'secret-123',
                                'grant_type' => 'authorization_code',
-                               'redirect_uri' => 'http://test.host/-/jira/login/oauth/callback' }
+                               'redirect_uri' => 'http://test.host/login/oauth/callback' }
 
       expect(Gitlab::HTTP).to receive(:post).with(oauth_token_url, allow_local_requests: true, body: expected_auth_params) do
         { 'access_token' => 'fake-123', 'scope' => 'foo', 'token_type' => 'bar' }
diff --git a/ee/spec/requests/api/v3/github_spec.rb b/ee/spec/requests/api/v3/github_spec.rb
index 25f6c8f984bc5cf1a0a67245ff659bdb344844ec..5bc8b9c3829bb650a59a9a35039f0d66b80cb4af 100644
--- a/ee/spec/requests/api/v3/github_spec.rb
+++ b/ee/spec/requests/api/v3/github_spec.rb
@@ -3,10 +3,12 @@ require 'spec_helper'
 describe API::V3::Github do
   let(:user) { create(:user) }
   let!(:project) { create(:project, :repository, creator: user) }
+  let!(:project2) { create(:project, :repository, creator: user) }
 
   before do
     allow(Gitlab::Jira::Middleware).to receive(:jira_dvcs_connector?) { true }
     project.add_maintainer(user)
+    project2.add_maintainer(user)
   end
 
   describe 'GET /orgs/:namespace/repos' do
@@ -37,91 +39,125 @@ describe API::V3::Github do
     end
   end
 
-  describe 'GET /repos/-/jira/events' do
-    it 'returns an empty array' do
-      get v3_api('/repos/-/jira/events', user)
+  shared_examples_for 'Jira-specific mimicked GitHub endpoints' do
+    describe 'GET /repos/.../events' do
+      it 'returns an empty array' do
+        get v3_api("/repos/#{path}/events", user)
 
-      expect(response).to have_gitlab_http_status(200)
-      expect(json_response).to eq([])
-    end
-  end
-
-  describe 'GET /-/jira/pulls' do
-    let(:assignee) { create(:user) }
-    let!(:merge_request) do
-      create(:merge_request, source_project: project, target_project: project, author: user, assignee: assignee)
+        expect(response).to have_gitlab_http_status(200)
+        expect(json_response).to eq([])
+      end
     end
 
-    it 'returns an array of merge requests with github format' do
-      stub_licensed_features(jira_dev_panel_integration: true)
+    describe 'GET /.../issues/:id/comments' do
+      context 'when user has access to the merge request' do
+        let(:merge_request) do
+          create(:merge_request, source_project: project, target_project: project)
+        end
+        let!(:note) do
+          create(:note, project: project, noteable: merge_request)
+        end
 
-      get v3_api('/repos/-/jira/pulls', user)
+        it 'returns an array of notes' do
+          stub_licensed_features(jira_dev_panel_integration: true)
 
-      expect(response).to have_gitlab_http_status(200)
-      expect(json_response).to be_an(Array)
-      expect(json_response.size).to eq(1)
-      expect(response).to match_response_schema('entities/github/pull_requests', dir: 'ee')
-    end
-  end
+          get v3_api("/repos/#{path}/issues/#{merge_request.id}/comments", user)
 
-  describe 'GET /-/jira/issues/:id/comments' do
-    context 'when user has access to the merge request' do
-      let(:merge_request) do
-        create(:merge_request, source_project: project, target_project: project)
-      end
-      let!(:note) do
-        create(:note, project: project, noteable: merge_request)
+          expect(response).to have_gitlab_http_status(200)
+          expect(json_response).to be_an(Array)
+          expect(json_response.size).to eq(1)
+        end
       end
 
-      it 'returns an array of notes' do
-        stub_licensed_features(jira_dev_panel_integration: true)
+      context 'when user has no access to the merge request' do
+        let(:private_project) { create(:project, :private) }
+        let(:merge_request) do
+          create(:merge_request, source_project: private_project, target_project: private_project)
+        end
+        let!(:note) do
+          create(:note, project: private_project, noteable: merge_request)
+        end
 
-        get v3_api("/repos/-/jira/issues/#{merge_request.id}/comments", user)
+        before do
+          private_project.add_guest(user)
+        end
 
-        expect(response).to have_gitlab_http_status(200)
-        expect(json_response).to be_an(Array)
-        expect(json_response.size).to eq(1)
+        it 'returns 404' do
+          stub_licensed_features(jira_dev_panel_integration: true)
+
+          get v3_api("/repos/#{path}/issues/#{merge_request.id}/comments", user)
+
+          expect(response).to have_gitlab_http_status(404)
+        end
       end
     end
 
-    context 'when user has no access to the merge request' do
-      let(:private_project) { create(:project, :private) }
-      let(:merge_request) do
-        create(:merge_request, source_project: private_project, target_project: private_project)
-      end
-      let!(:note) do
-        create(:note, project: private_project, noteable: merge_request)
-      end
+    describe 'GET /.../pulls/:id/commits' do
+      it 'returns an empty array' do
+        get v3_api("/repos/#{path}/pulls/xpto/commits", user)
 
-      before do
-        private_project.add_guest(user)
+        expect(response).to have_gitlab_http_status(200)
+        expect(json_response).to eq([])
       end
+    end
 
-      it 'returns 404' do
-        stub_licensed_features(jira_dev_panel_integration: true)
-
-        get v3_api("/repos/-/jira/issues/#{merge_request.id}/comments", user)
+    describe 'GET /.../pulls/:id/comments' do
+      it 'returns an empty array' do
+        get v3_api("/repos/#{path}/pulls/xpto/comments", user)
 
-        expect(response).to have_gitlab_http_status(404)
+        expect(response).to have_gitlab_http_status(200)
+        expect(json_response).to eq([])
       end
     end
   end
 
-  describe 'GET /-/jira/pulls/:id/commits' do
-    it 'returns an empty array' do
-      get v3_api("/repos/-/jira/pulls/xpto/commits", user)
+  # Here we test that using /-/jira as namespace/project still works,
+  # since that is how old Jira setups will talk to us
+  context 'old /-/jira endpoints' do
+    it_behaves_like 'Jira-specific mimicked GitHub endpoints' do
+      let(:path) { '-/jira' }
+    end
+  end
 
-      expect(response).to have_gitlab_http_status(200)
-      expect(json_response).to eq([])
+  context 'new :namespace/:project jira endpoints' do
+    it_behaves_like 'Jira-specific mimicked GitHub endpoints' do
+      let(:path) { "#{project.namespace.path}/#{project.path}" }
     end
   end
 
-  describe 'GET /-/jira/pulls/:id/comments' do
-    it 'returns an empty array' do
-      get v3_api("/repos/-/jira/pulls/xpto/comments", user)
+  describe 'repo pulls' do
+    let(:assignee) { create(:user) }
+    let!(:merge_request) do
+      create(:merge_request, source_project: project, target_project: project, author: user, assignee: assignee)
+    end
+    let!(:merge_request_2) do
+      create(:merge_request, source_project: project2, target_project: project2, author: user, assignee: assignee)
+    end
 
-      expect(response).to have_gitlab_http_status(200)
-      expect(json_response).to eq([])
+    describe 'GET /-/jira/pulls' do
+      it 'returns an array of merge requests with github format' do
+        stub_licensed_features(jira_dev_panel_integration: true)
+
+        get v3_api('/repos/-/jira/pulls', user)
+
+        expect(response).to have_gitlab_http_status(200)
+        expect(json_response).to be_an(Array)
+        expect(json_response.size).to eq(2)
+        expect(response).to match_response_schema('entities/github/pull_requests', dir: 'ee')
+      end
+    end
+
+    describe 'GET /repos/:namespace/:project/pulls' do
+      it 'returns an array of merge requests for the proper project in github format' do
+        stub_licensed_features(jira_dev_panel_integration: true)
+
+        get v3_api("/repos/#{project.namespace.path}/#{project.path}/pulls", user)
+
+        expect(response).to have_gitlab_http_status(200)
+        expect(json_response).to be_an(Array)
+        expect(json_response.size).to eq(1)
+        expect(response).to match_response_schema('entities/github/pull_requests', dir: 'ee')
+      end
     end
   end
 
diff --git a/lib/gitlab/path_regex.rb b/lib/gitlab/path_regex.rb
index 91febaaeac9b08b55d239a64112273ba95320243..59504d5af301a088f6420d28b098bf2b640b0d46 100644
--- a/lib/gitlab/path_regex.rb
+++ b/lib/gitlab/path_regex.rb
@@ -40,6 +40,7 @@ module Gitlab
       invites
       jwt
       koding
+      login
       notification_settings
       oauth
       profile