Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
gitlab-ce
Commits
351f205c
Commit
351f205c
authored
Dec 05, 2017
by
Alejandro Rodríguez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Incorporate ConflictsService.ListConflictFiles Gitaly RPC
parent
f1d5e509
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
177 additions
and
23 deletions
+177
-23
app/services/merge_requests/conflicts/list_service.rb
app/services/merge_requests/conflicts/list_service.rb
+1
-1
lib/gitlab/git/conflict/resolver.rb
lib/gitlab/git/conflict/resolver.rb
+19
-5
lib/gitlab/git/repository.rb
lib/gitlab/git/repository.rb
+4
-0
lib/gitlab/gitaly_client/conflicts_service.rb
lib/gitlab/gitaly_client/conflicts_service.rb
+60
-0
lib/gitlab/gitaly_client/util.rb
lib/gitlab/gitaly_client/util.rb
+6
-0
spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb
spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb
+58
-0
spec/services/merge_requests/conflicts/list_service_spec.rb
spec/services/merge_requests/conflicts/list_service_spec.rb
+18
-8
spec/services/merge_requests/conflicts/resolve_service_spec.rb
...services/merge_requests/conflicts/resolve_service_spec.rb
+11
-9
No files found.
app/services/merge_requests/conflicts/list_service.rb
View file @
351f205c
...
@@ -23,7 +23,7 @@ module MergeRequests
...
@@ -23,7 +23,7 @@ module MergeRequests
# when there are no conflict files.
# when there are no conflict files.
conflicts
.
files
.
each
(
&
:lines
)
conflicts
.
files
.
each
(
&
:lines
)
@conflicts_can_be_resolved_in_ui
=
conflicts
.
files
.
length
>
0
@conflicts_can_be_resolved_in_ui
=
conflicts
.
files
.
length
>
0
rescue
Rugged
::
Odb
Error
,
Gitlab
::
Git
::
Conflict
::
Parser
::
UnresolvableError
,
Gitlab
::
Git
::
Conflict
::
Resolver
::
ConflictSideMissing
rescue
Gitlab
::
Git
::
Command
Error
,
Gitlab
::
Git
::
Conflict
::
Parser
::
UnresolvableError
,
Gitlab
::
Git
::
Conflict
::
Resolver
::
ConflictSideMissing
@conflicts_can_be_resolved_in_ui
=
false
@conflicts_can_be_resolved_in_ui
=
false
end
end
end
end
...
...
lib/gitlab/git/conflict/resolver.rb
View file @
351f205c
...
@@ -13,12 +13,18 @@ module Gitlab
...
@@ -13,12 +13,18 @@ module Gitlab
def
conflicts
def
conflicts
@conflicts
||=
begin
@conflicts
||=
begin
target_index
=
@target_repository
.
rugged
.
merge_commits
(
@our_commit_oid
,
@their_commit_oid
)
@target_repository
.
gitaly_migrate
(
:conflicts_list_conflict_files
)
do
|
is_enabled
|
if
is_enabled
# We don't need to do `with_repo_branch_commit` here, because the target
@target_repository
.
gitaly_conflicts_client
.
list_conflict_files
(
@our_commit_oid
,
@their_commit_oid
)
# project always fetches source refs when creating merge request diffs.
else
conflict_files
(
@target_repository
,
target_index
)
rugged_list_conflict_files
end
end
end
end
rescue
GRPC
::
FailedPrecondition
=>
e
raise
Gitlab
::
Git
::
Conflict
::
Resolver
::
ConflictSideMissing
.
new
(
e
.
message
)
rescue
Rugged
::
OdbError
,
GRPC
::
BadStatus
=>
e
raise
Gitlab
::
Git
::
CommandError
.
new
(
e
)
end
end
def
resolve_conflicts
(
source_repository
,
user
,
files
,
source_branch
:,
target_branch
:,
commit_message
:)
def
resolve_conflicts
(
source_repository
,
user
,
files
,
source_branch
:,
target_branch
:,
commit_message
:)
...
@@ -84,6 +90,14 @@ module Gitlab
...
@@ -84,6 +90,14 @@ module Gitlab
index
.
add
(
path:
our_path
,
oid:
oid
,
mode:
file
.
our_mode
)
index
.
add
(
path:
our_path
,
oid:
oid
,
mode:
file
.
our_mode
)
index
.
conflict_remove
(
our_path
)
index
.
conflict_remove
(
our_path
)
end
end
def
rugged_list_conflict_files
target_index
=
@target_repository
.
rugged
.
merge_commits
(
@our_commit_oid
,
@their_commit_oid
)
# We don't need to do `with_repo_branch_commit` here, because the target
# project always fetches source refs when creating merge request diffs.
conflict_files
(
@target_repository
,
target_index
)
end
end
end
end
end
end
end
...
...
lib/gitlab/git/repository.rb
View file @
351f205c
...
@@ -1294,6 +1294,10 @@ module Gitlab
...
@@ -1294,6 +1294,10 @@ module Gitlab
@gitaly_remote_client
||=
Gitlab
::
GitalyClient
::
RemoteService
.
new
(
self
)
@gitaly_remote_client
||=
Gitlab
::
GitalyClient
::
RemoteService
.
new
(
self
)
end
end
def
gitaly_conflicts_client
@gitaly_conflicts_client
||=
Gitlab
::
GitalyClient
::
ConflictsService
.
new
(
self
)
end
def
gitaly_migrate
(
method
,
status:
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_IN
,
&
block
)
def
gitaly_migrate
(
method
,
status:
Gitlab
::
GitalyClient
::
MigrationStatus
::
OPT_IN
,
&
block
)
Gitlab
::
GitalyClient
.
migrate
(
method
,
status:
status
,
&
block
)
Gitlab
::
GitalyClient
.
migrate
(
method
,
status:
status
,
&
block
)
rescue
GRPC
::
NotFound
=>
e
rescue
GRPC
::
NotFound
=>
e
...
...
lib/gitlab/gitaly_client/conflicts_service.rb
0 → 100644
View file @
351f205c
module
Gitlab
module
GitalyClient
class
ConflictsService
def
initialize
(
repository
)
@gitaly_repo
=
repository
.
gitaly_repository
@repository
=
repository
end
def
list_conflict_files
(
our_commit_oid
,
their_commit_oid
)
request
=
Gitaly
::
ListConflictFilesRequest
.
new
(
repository:
@gitaly_repo
,
our_commit_oid:
our_commit_oid
,
their_commit_oid:
their_commit_oid
)
response
=
GitalyClient
.
call
(
@repository
.
storage
,
:conflicts_service
,
:list_conflict_files
,
request
)
files
=
[]
header
=
nil
content
=
nil
response
.
each
do
|
msg
|
msg
.
files
.
each
do
|
gitaly_file
|
if
gitaly_file
.
header
# Add previous file to the collection, except on first iteration
files
<<
conflict_file_from_gitaly
(
header
,
content
)
if
header
header
=
gitaly_file
.
header
content
=
""
else
# Append content to curret file
content
<<
gitaly_file
.
content
end
end
end
# Add leftover file, if any
files
<<
conflict_file_from_gitaly
(
header
,
content
)
if
header
files
end
private
def
conflict_file_from_gitaly
(
header
,
content
)
Gitlab
::
Git
::
Conflict
::
File
.
new
(
Gitlab
::
GitalyClient
::
Util
.
git_repository
(
header
.
repository
),
header
.
commit_oid
,
conflict_from_gitaly_file_header
(
header
),
content
)
end
def
conflict_from_gitaly_file_header
(
header
)
{
ours:
{
path:
header
.
our_path
,
mode:
header
.
our_mode
},
theirs:
{
path:
header
.
their_path
}
}
end
end
end
end
lib/gitlab/gitaly_client/util.rb
View file @
351f205c
...
@@ -18,6 +18,12 @@ module Gitlab
...
@@ -18,6 +18,12 @@ module Gitlab
)
)
end
end
def
git_repository
(
gitaly_repository
)
Gitlab
::
Git
::
Repository
.
new
(
gitaly_repository
.
storage_name
,
gitaly_repository
.
relative_path
,
gitaly_repository
.
gl_repository
)
end
def
gitlab_tag_from_gitaly_tag
(
repository
,
gitaly_tag
)
def
gitlab_tag_from_gitaly_tag
(
repository
,
gitaly_tag
)
if
gitaly_tag
.
target_commit
.
present?
if
gitaly_tag
.
target_commit
.
present?
commit
=
Gitlab
::
Git
::
Commit
.
decorate
(
repository
,
gitaly_tag
.
target_commit
)
commit
=
Gitlab
::
Git
::
Commit
.
decorate
(
repository
,
gitaly_tag
.
target_commit
)
...
...
spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb
0 → 100644
View file @
351f205c
require
'spec_helper'
describe
Gitlab
::
GitalyClient
::
ConflictsService
do
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:target_project
)
{
create
(
:project
,
:repository
)
}
let
(
:repository
)
{
project
.
repository
}
let
(
:gitaly_repositoy
)
{
repository
.
gitaly_repository
}
let
(
:target_repository
)
{
target_project
.
repository
}
let
(
:target_gitaly_repository
)
{
target_repository
.
gitaly_repository
}
describe
'#list_conflict_files'
do
let
(
:request
)
do
Gitaly
::
ListConflictFilesRequest
.
new
(
repository:
target_gitaly_repository
,
our_commit_oid:
our_commit_oid
,
their_commit_oid:
their_commit_oid
)
end
let
(
:our_commit_oid
)
{
'f00'
}
let
(
:their_commit_oid
)
{
'f44'
}
let
(
:our_path
)
{
'our/path'
}
let
(
:their_path
)
{
'their/path'
}
let
(
:our_mode
)
{
0744
}
let
(
:header
)
do
double
(
repository:
target_gitaly_repository
,
commit_oid:
our_commit_oid
,
our_path:
our_path
,
our_mode:
0744
,
their_path:
their_path
)
end
let
(
:response
)
do
[
double
(
files:
[
double
(
header:
header
),
double
(
content:
'foo'
,
header:
nil
)]),
double
(
files:
[
double
(
content:
'bar'
,
header:
nil
)])
]
end
let
(
:file
)
{
subject
[
0
]
}
let
(
:client
)
{
described_class
.
new
(
target_repository
)
}
subject
{
client
.
list_conflict_files
(
our_commit_oid
,
their_commit_oid
)
}
it
'sends an RPC request'
do
expect_any_instance_of
(
Gitaly
::
ConflictsService
::
Stub
).
to
receive
(
:list_conflict_files
)
.
with
(
request
,
kind_of
(
Hash
)).
and_return
([])
subject
end
it
'forms a Gitlab::Git::ConflictFile collection from the response'
do
allow_any_instance_of
(
Gitaly
::
ConflictsService
::
Stub
).
to
receive
(
:list_conflict_files
)
.
with
(
request
,
kind_of
(
Hash
)).
and_return
(
response
)
expect
(
subject
.
size
).
to
be
(
1
)
expect
(
file
.
content
).
to
eq
(
'foobar'
)
expect
(
file
.
their_path
).
to
eq
(
their_path
)
expect
(
file
.
our_path
).
to
eq
(
our_path
)
expect
(
file
.
our_mode
).
to
be
(
our_mode
)
expect
(
file
.
repository
).
to
eq
(
target_repository
)
expect
(
file
.
commit_oid
).
to
eq
(
our_commit_oid
)
end
end
end
spec/services/merge_requests/conflicts/list_service_spec.rb
View file @
351f205c
...
@@ -32,14 +32,6 @@ describe MergeRequests::Conflicts::ListService do
...
@@ -32,14 +32,6 @@ describe MergeRequests::Conflicts::ListService do
expect
(
conflicts_service
(
merge_request
).
can_be_resolved_in_ui?
).
to
be_falsey
expect
(
conflicts_service
(
merge_request
).
can_be_resolved_in_ui?
).
to
be_falsey
end
end
it
'returns a falsey value when the MR has a missing ref after a force push'
do
merge_request
=
create_merge_request
(
'conflict-resolvable'
)
service
=
conflicts_service
(
merge_request
)
allow_any_instance_of
(
Rugged
::
Repository
).
to
receive
(
:merge_commits
).
and_raise
(
Rugged
::
OdbError
)
expect
(
service
.
can_be_resolved_in_ui?
).
to
be_falsey
end
it
'returns a falsey value when the MR does not support new diff notes'
do
it
'returns a falsey value when the MR does not support new diff notes'
do
merge_request
=
create_merge_request
(
'conflict-resolvable'
)
merge_request
=
create_merge_request
(
'conflict-resolvable'
)
merge_request
.
merge_request_diff
.
update_attributes
(
start_commit_sha:
nil
)
merge_request
.
merge_request_diff
.
update_attributes
(
start_commit_sha:
nil
)
...
@@ -76,5 +68,23 @@ describe MergeRequests::Conflicts::ListService do
...
@@ -76,5 +68,23 @@ describe MergeRequests::Conflicts::ListService do
expect
(
conflicts_service
(
merge_request
).
can_be_resolved_in_ui?
).
to
be_truthy
expect
(
conflicts_service
(
merge_request
).
can_be_resolved_in_ui?
).
to
be_truthy
end
end
it
'returns a falsey value when the MR has a missing ref after a force push'
do
merge_request
=
create_merge_request
(
'conflict-resolvable'
)
service
=
conflicts_service
(
merge_request
)
allow_any_instance_of
(
Gitlab
::
GitalyClient
::
ConflictsService
).
to
receive
(
:list_conflict_files
).
and_raise
(
GRPC
::
Unknown
)
expect
(
service
.
can_be_resolved_in_ui?
).
to
be_falsey
end
context
'with gitaly disabled'
,
:skip_gitaly_mock
do
it
'returns a falsey value when the MR has a missing ref after a force push'
do
merge_request
=
create_merge_request
(
'conflict-resolvable'
)
service
=
conflicts_service
(
merge_request
)
allow_any_instance_of
(
Rugged
::
Repository
).
to
receive
(
:merge_commits
).
and_raise
(
Rugged
::
OdbError
)
expect
(
service
.
can_be_resolved_in_ui?
).
to
be_falsey
end
end
end
end
end
end
spec/services/merge_requests/conflicts/resolve_service_spec.rb
View file @
351f205c
...
@@ -111,15 +111,6 @@ describe MergeRequests::Conflicts::ResolveService do
...
@@ -111,15 +111,6 @@ describe MergeRequests::Conflicts::ResolveService do
described_class
.
new
(
merge_request_from_fork
).
execute
(
user
,
params
)
described_class
.
new
(
merge_request_from_fork
).
execute
(
user
,
params
)
end
end
it
'gets conflicts from the source project'
do
# REFACTOR NOTE: We used to test that `project.repository.rugged` wasn't
# used in this case, but since the refactor, for simplification,
# we always use that repository for read only operations.
expect
(
forked_project
.
repository
.
rugged
).
to
receive
(
:merge_commits
).
and_call_original
subject
end
it
'creates a commit with the message'
do
it
'creates a commit with the message'
do
subject
subject
...
@@ -132,6 +123,17 @@ describe MergeRequests::Conflicts::ResolveService do
...
@@ -132,6 +123,17 @@ describe MergeRequests::Conflicts::ResolveService do
expect
(
merge_request_from_fork
.
source_branch_head
.
parents
.
map
(
&
:id
))
expect
(
merge_request_from_fork
.
source_branch_head
.
parents
.
map
(
&
:id
))
.
to
eq
([
'404fa3fc7c2c9b5dacff102f353bdf55b1be2813'
,
target_head
])
.
to
eq
([
'404fa3fc7c2c9b5dacff102f353bdf55b1be2813'
,
target_head
])
end
end
context
'when gitaly is disabled'
,
:skip_gitaly_mock
do
it
'gets conflicts from the source project'
do
# REFACTOR NOTE: We used to test that `project.repository.rugged` wasn't
# used in this case, but since the refactor, for simplification,
# we always use that repository for read only operations.
expect
(
forked_project
.
repository
.
rugged
).
to
receive
(
:merge_commits
).
and_call_original
subject
end
end
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment