BigW Consortium Gitlab
Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
gitlab-ce
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Forest Godfrey
gitlab-ce
Commits
faa9bd40
Commit
faa9bd40
authored
Oct 09, 2017
by
Alejandro Rodríguez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Create a Gitlab::Git submodule for conlict-related files
Rename classes to (hopefully) clearer names while we're doing that.
parent
3fcab51e
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
268 additions
and
257 deletions
+268
-257
conflicts_controller.rb
...ntrollers/projects/merge_requests/conflicts_controller.rb
+1
-1
list_service.rb
app/services/merge_requests/conflicts/list_service.rb
+1
-1
commits.rb
lib/api/commits.rb
+1
-1
commits.rb
lib/api/v3/commits.rb
+1
-1
comment.rb
lib/github/representation/comment.rb
+1
-1
importer.rb
lib/gitlab/bitbucket_import/importer.rb
+1
-1
file.rb
lib/gitlab/conflict/file.rb
+5
-2
file_collection.rb
lib/gitlab/conflict/file_collection.rb
+4
-4
file.rb
lib/gitlab/diff/file.rb
+1
-1
file.rb
lib/gitlab/git/conflict/file.rb
+65
-63
line_code.rb
lib/gitlab/git/conflict/line_code.rb
+5
-3
parser.rb
lib/gitlab/git/conflict/parser.rb
+76
-74
resolver.rb
lib/gitlab/git/conflict/resolver.rb
+67
-65
comment_formatter.rb
lib/gitlab/github_import/comment_formatter.rb
+1
-1
conflicts_controller_spec.rb
...lers/projects/merge_requests/conflicts_controller_spec.rb
+4
-4
file_spec.rb
spec/lib/gitlab/conflict/file_spec.rb
+4
-4
position_spec.rb
spec/lib/gitlab/diff/position_spec.rb
+10
-10
parser_spec.rb
spec/lib/gitlab/git/conflict/parser_spec.rb
+13
-13
diff_note_spec.rb
spec/models/diff_note_spec.rb
+1
-1
resolve_service_spec.rb
...services/merge_requests/conflicts/resolve_service_spec.rb
+6
-6
No files found.
app/controllers/projects/merge_requests/conflicts_controller.rb
View file @
faa9bd40
...
...
@@ -53,7 +53,7 @@ class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::Ap
flash
[
:notice
]
=
'All merge conflicts were resolved. The merge request can now be merged.'
render
json:
{
redirect_to:
project_merge_request_url
(
@project
,
@merge_request
,
resolved_conflicts:
true
)
}
rescue
Gitlab
::
Git
::
Merge
::
ResolutionError
=>
e
rescue
Gitlab
::
Git
::
Conflict
::
Resolver
::
ResolutionError
=>
e
render
status: :bad_request
,
json:
{
message:
e
.
message
}
end
end
...
...
app/services/merge_requests/conflicts/list_service.rb
View file @
faa9bd40
...
...
@@ -23,7 +23,7 @@ module MergeRequests
# when there are no conflict files.
conflicts
.
files
.
each
(
&
:lines
)
@conflicts_can_be_resolved_in_ui
=
conflicts
.
files
.
length
>
0
rescue
Rugged
::
OdbError
,
Gitlab
::
Git
::
Conflict
Parser
::
UnresolvableError
,
Gitlab
::
Git
::
Merge
::
ConflictSideMissing
rescue
Rugged
::
OdbError
,
Gitlab
::
Git
::
Conflict
::
Parser
::
UnresolvableError
,
Gitlab
::
Git
::
Conflict
::
Resolver
::
ConflictSideMissing
@conflicts_can_be_resolved_in_ui
=
false
end
end
...
...
lib/api/commits.rb
View file @
faa9bd40
...
...
@@ -186,7 +186,7 @@ module API
lines
.
each
do
|
line
|
next
unless
line
.
new_pos
==
params
[
:line
]
&&
line
.
type
==
params
[
:line_type
]
break
opts
[
:line_code
]
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
diff
.
new_path
,
line
.
new_pos
,
line
.
old_pos
)
break
opts
[
:line_code
]
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
diff
.
new_path
,
line
.
new_pos
,
line
.
old_pos
)
end
break
if
opts
[
:line_code
]
...
...
lib/api/v3/commits.rb
View file @
faa9bd40
...
...
@@ -173,7 +173,7 @@ module API
lines
.
each
do
|
line
|
next
unless
line
.
new_pos
==
params
[
:line
]
&&
line
.
type
==
params
[
:line_type
]
break
opts
[
:line_code
]
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
diff
.
new_path
,
line
.
new_pos
,
line
.
old_pos
)
break
opts
[
:line_code
]
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
diff
.
new_path
,
line
.
new_pos
,
line
.
old_pos
)
end
break
if
opts
[
:line_code
]
...
...
lib/github/representation/comment.rb
View file @
faa9bd40
...
...
@@ -23,7 +23,7 @@ module Github
private
def
generate_line_code
(
line
)
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
file_path
,
line
.
new_pos
,
line
.
old_pos
)
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
file_path
,
line
.
new_pos
,
line
.
old_pos
)
end
def
on_diff?
...
...
lib/gitlab/bitbucket_import/importer.rb
View file @
faa9bd40
...
...
@@ -241,7 +241,7 @@ module Gitlab
end
def
generate_line_code
(
pr_comment
)
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
pr_comment
.
file_path
,
pr_comment
.
new_pos
,
pr_comment
.
old_pos
)
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
pr_comment
.
file_path
,
pr_comment
.
new_pos
,
pr_comment
.
old_pos
)
end
def
pull_request_comment_attributes
(
comment
)
...
...
lib/gitlab/conflict/file.rb
View file @
faa9bd40
...
...
@@ -6,7 +6,10 @@ module Gitlab
CONTEXT_LINES
=
3
attr_reader
:merge_request
,
:raw
attr_reader
:merge_request
# 'raw' holds the Gitlab::Git::Conflict::File that this instance wraps
attr_reader
:raw
delegate
:type
,
:content
,
:their_path
,
:our_path
,
:our_mode
,
:our_blob
,
:repository
,
to: :raw
...
...
@@ -107,7 +110,7 @@ module Gitlab
end
def
line_code
(
line
)
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
our_path
,
line
.
new_pos
,
line
.
old_pos
)
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
our_path
,
line
.
new_pos
,
line
.
old_pos
)
end
def
create_match_line
(
line
)
...
...
lib/gitlab/conflict/file_collection.rb
View file @
faa9bd40
module
Gitlab
module
Conflict
class
FileCollection
attr_reader
:merge_request
,
:
merge
attr_reader
:merge_request
,
:
resolver
def
initialize
(
merge_request
)
source_repo
=
merge_request
.
source_project
.
repository
.
raw
our_commit
=
merge_request
.
source_branch_head
.
raw
their_commit
=
merge_request
.
target_branch_head
.
raw
target_repo
=
merge_request
.
target_project
.
repository
.
raw
@
merge
=
Gitlab
::
Git
::
Merge
.
new
(
source_repo
,
our_commit
,
target_repo
,
their_commit
)
@
resolver
=
Gitlab
::
Git
::
Conflict
::
Resolver
.
new
(
source_repo
,
our_commit
,
target_repo
,
their_commit
)
@merge_request
=
merge_request
end
...
...
@@ -18,11 +18,11 @@ module Gitlab
target_branch:
merge_request
.
target_branch
,
commit_message:
commit_message
||
default_commit_message
}
merge
.
resolve_conflicts
(
user
,
files
,
args
)
resolver
.
resolve_conflicts
(
user
,
files
,
args
)
end
def
files
@files
||=
merge
.
conflicts
.
map
do
|
conflict_file
|
@files
||=
resolver
.
conflicts
.
map
do
|
conflict_file
|
Gitlab
::
Conflict
::
File
.
new
(
conflict_file
,
merge_request:
merge_request
)
end
end
...
...
lib/gitlab/diff/file.rb
View file @
faa9bd40
...
...
@@ -49,7 +49,7 @@ module Gitlab
def
line_code
(
line
)
return
if
line
.
meta?
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
file_path
,
line
.
new_pos
,
line
.
old_pos
)
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
file_path
,
line
.
new_pos
,
line
.
old_pos
)
end
def
line_for_line_code
(
code
)
...
...
lib/gitlab/git/conflict
_
file.rb
→
lib/gitlab/git/conflict
/
file.rb
View file @
faa9bd40
module
Gitlab
module
Git
class
ConflictFile
attr_reader
:content
,
:their_path
,
:our_path
,
:our_mode
,
:repository
module
Conflict
class
File
attr_reader
:content
,
:their_path
,
:our_path
,
:our_mode
,
:repository
def
initialize
(
repository
,
commit_oid
,
conflict
,
content
)
@repository
=
repository
@commit_oid
=
commit_oid
@their_path
=
conflict
[
:theirs
][
:path
]
@our_path
=
conflict
[
:ours
][
:path
]
@our_mode
=
conflict
[
:ours
][
:mode
]
@content
=
content
end
def
initialize
(
repository
,
commit_oid
,
conflict
,
content
)
@repository
=
repository
@commit_oid
=
commit_oid
@their_path
=
conflict
[
:theirs
][
:path
]
@our_path
=
conflict
[
:ours
][
:path
]
@our_mode
=
conflict
[
:ours
][
:mode
]
@content
=
content
end
def
lines
return
@lines
if
defined?
(
@lines
)
def
lines
return
@lines
if
defined?
(
@lines
)
begin
@type
=
'text'
@lines
=
Gitlab
::
Git
::
ConflictParser
.
parse
(
content
,
our_path:
our_path
,
their_path:
their_path
)
rescue
Gitlab
::
Git
::
ConflictParser
::
ParserError
@type
=
'text-editor'
@lines
=
nil
begin
@type
=
'text'
@lines
=
Gitlab
::
Git
::
Conflict
::
Parser
.
parse
(
content
,
our_path:
our_path
,
their_path:
their_path
)
rescue
Gitlab
::
Git
::
Conflict
::
Parser
::
ParserError
@type
=
'text-editor'
@lines
=
nil
end
end
end
def
type
lines
unless
@type
def
type
lines
unless
@type
@type
.
inquiry
end
def
our_blob
# REFACTOR NOTE: the source of `commit_oid` used to be
# `merge_request.diff_refs.head_sha`. Instead of passing this value
# around the new lib structure, I decided to use `@commit_oid` which is
# equivalent to `merge_request.source_branch_head.raw.rugged_commit.oid`.
# That is what `merge_request.diff_refs.head_sha` is equivalent to when
# `merge_request` is not persisted (see `MergeRequest#diff_head_commit`).
# I think using the same oid is more consistent anyways, but if Conflicts
# start breaking, the change described above is a good place to look at.
@our_blob
||=
repository
.
blob_at
(
@commit_oid
,
our_path
)
end
@type
.
inquiry
end
def
line_code
(
line
)
Gitlab
::
Git
::
DiffLineCode
.
generate
(
our_path
,
line
[
:line_new
],
line
[
:line_old
])
end
def
our_blob
# REFACTOR NOTE: the source of `commit_oid` used to be
# `merge_request.diff_refs.head_sha`. Instead of passing this value
# around the new lib structure, I decided to use `@commit_oid` which is
# equivalent to `merge_request.source_branch_head.raw.rugged_commit.oid`.
# That is what `merge_request.diff_refs.head_sha` is equivalent to when
# `merge_request` is not persisted (see `MergeRequest#diff_head_commit`).
# I think using the same oid is more consistent anyways, but if Conflicts
# start breaking, the change described above is a good place to look at.
@our_blob
||=
repository
.
blob_at
(
@commit_oid
,
our_path
)
end
def
resolve_lines
(
resolution
)
section_id
=
nil
def
line_code
(
line
)
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
our_path
,
line
[
:line_new
],
line
[
:line_old
])
end
lines
.
map
do
|
line
|
unless
line
[
:type
]
section_id
=
nil
next
line
end
def
resolve_lines
(
resolution
)
section_id
=
nil
section_id
||=
line_code
(
line
)
lines
.
map
do
|
line
|
unless
line
[
:type
]
section_id
=
nil
next
line
end
case
resolution
[
section_id
]
when
'head'
next
unless
line
[
:type
]
==
'new'
when
'origin'
next
unless
line
[
:type
]
==
'old'
else
raise
Gitlab
::
Git
::
Merge
::
ResolutionError
,
"Missing resolution for section ID:
#{
section_id
}
"
end
section_id
||=
line_code
(
line
)
line
end
.
compact
end
case
resolution
[
section_id
]
when
'head'
next
unless
line
[
:type
]
==
'new'
when
'origin'
next
unless
line
[
:type
]
==
'old'
else
raise
Gitlab
::
Git
::
Conflict
::
Resolver
::
ResolutionError
,
"Missing resolution for section ID:
#{
section_id
}
"
end
def
resolve_content
(
resolution
)
if
resolution
==
content
raise
Gitlab
::
Git
::
Merge
::
ResolutionError
,
"Resolved content has no changes for file
#{
our_path
}
"
line
end
.
compact
end
resolution
def
resolve_content
(
resolution
)
if
resolution
==
content
raise
Gitlab
::
Git
::
Conflict
::
Resolver
::
ResolutionError
,
"Resolved content has no changes for file
#{
our_path
}
"
end
resolution
end
end
end
end
...
...
lib/gitlab/git/
diff_
line_code.rb
→
lib/gitlab/git/
conflict/
line_code.rb
View file @
faa9bd40
module
Gitlab
module
Git
class
DiffLineCode
def
self
.
generate
(
file_path
,
new_line_position
,
old_line_position
)
"
#{
Digest
::
SHA1
.
hexdigest
(
file_path
)
}
_
#{
old_line_position
}
_
#{
new_line_position
}
"
module
Conflict
class
LineCode
def
self
.
generate
(
file_path
,
new_line_position
,
old_line_position
)
"
#{
Digest
::
SHA1
.
hexdigest
(
file_path
)
}
_
#{
old_line_position
}
_
#{
new_line_position
}
"
end
end
end
end
...
...
lib/gitlab/git/conflict
_
parser.rb
→
lib/gitlab/git/conflict
/
parser.rb
View file @
faa9bd40
module
Gitlab
module
Git
class
ConflictParser
UnresolvableError
=
Class
.
new
(
StandardError
)
UnmergeableFile
=
Class
.
new
(
UnresolvableError
)
UnsupportedEncoding
=
Class
.
new
(
UnresolvableError
)
# Recoverable errors - the conflict can be resolved in an editor, but not with
# sections.
ParserError
=
Class
.
new
(
StandardError
)
UnexpectedDelimiter
=
Class
.
new
(
ParserError
)
MissingEndDelimiter
=
Class
.
new
(
ParserError
)
class
<<
self
def
parse
(
text
,
our_path
:,
their_path
:,
parent_file:
nil
)
validate_text!
(
text
)
line_obj_index
=
0
line_old
=
1
line_new
=
1
type
=
nil
lines
=
[]
conflict_start
=
"<<<<<<<
#{
our_path
}
"
conflict_middle
=
'======='
conflict_end
=
">>>>>>>
#{
their_path
}
"
text
.
each_line
.
map
do
|
line
|
full_line
=
line
.
delete
(
"
\n
"
)
if
full_line
==
conflict_start
validate_delimiter!
(
type
.
nil?
)
type
=
'new'
elsif
full_line
==
conflict_middle
validate_delimiter!
(
type
==
'new'
)
type
=
'old'
elsif
full_line
==
conflict_end
validate_delimiter!
(
type
==
'old'
)
type
=
nil
elsif
line
[
0
]
==
'\\'
type
=
'nonewline'
lines
<<
{
full_line:
full_line
,
type:
type
,
line_obj_index:
line_obj_index
,
line_old:
line_old
,
line_new:
line_new
}
else
lines
<<
{
full_line:
full_line
,
type:
type
,
line_obj_index:
line_obj_index
,
line_old:
line_old
,
line_new:
line_new
}
line_old
+=
1
if
type
!=
'new'
line_new
+=
1
if
type
!=
'old'
line_obj_index
+=
1
module
Conflict
class
Parser
UnresolvableError
=
Class
.
new
(
StandardError
)
UnmergeableFile
=
Class
.
new
(
UnresolvableError
)
UnsupportedEncoding
=
Class
.
new
(
UnresolvableError
)
# Recoverable errors - the conflict can be resolved in an editor, but not with
# sections.
ParserError
=
Class
.
new
(
StandardError
)
UnexpectedDelimiter
=
Class
.
new
(
ParserError
)
MissingEndDelimiter
=
Class
.
new
(
ParserError
)
class
<<
self
def
parse
(
text
,
our_path
:,
their_path
:,
parent_file:
nil
)
validate_text!
(
text
)
line_obj_index
=
0
line_old
=
1
line_new
=
1
type
=
nil
lines
=
[]
conflict_start
=
"<<<<<<<
#{
our_path
}
"
conflict_middle
=
'======='
conflict_end
=
">>>>>>>
#{
their_path
}
"
text
.
each_line
.
map
do
|
line
|
full_line
=
line
.
delete
(
"
\n
"
)
if
full_line
==
conflict_start
validate_delimiter!
(
type
.
nil?
)
type
=
'new'
elsif
full_line
==
conflict_middle
validate_delimiter!
(
type
==
'new'
)
type
=
'old'
elsif
full_line
==
conflict_end
validate_delimiter!
(
type
==
'old'
)
type
=
nil
elsif
line
[
0
]
==
'\\'
type
=
'nonewline'
lines
<<
{
full_line:
full_line
,
type:
type
,
line_obj_index:
line_obj_index
,
line_old:
line_old
,
line_new:
line_new
}
else
lines
<<
{
full_line:
full_line
,
type:
type
,
line_obj_index:
line_obj_index
,
line_old:
line_old
,
line_new:
line_new
}
line_old
+=
1
if
type
!=
'new'
line_new
+=
1
if
type
!=
'old'
line_obj_index
+=
1
end
end
end
raise
MissingEndDelimiter
unless
type
.
nil?
raise
MissingEndDelimiter
unless
type
.
nil?
lines
end
lines
end
private
private
def
validate_text!
(
text
)
raise
UnmergeableFile
if
text
.
blank?
# Typically a binary file
raise
UnmergeableFile
if
text
.
length
>
200
.
kilobytes
def
validate_text!
(
text
)
raise
UnmergeableFile
if
text
.
blank?
# Typically a binary file
raise
UnmergeableFile
if
text
.
length
>
200
.
kilobytes
text
.
force_encoding
(
'UTF-8'
)
text
.
force_encoding
(
'UTF-8'
)
raise
UnsupportedEncoding
unless
text
.
valid_encoding?
end
raise
UnsupportedEncoding
unless
text
.
valid_encoding?
end
def
validate_delimiter!
(
condition
)
raise
UnexpectedDelimiter
unless
condition
def
validate_delimiter!
(
condition
)
raise
UnexpectedDelimiter
unless
condition
end
end
end
end
...
...
lib/gitlab/git/
merge
.rb
→
lib/gitlab/git/
conflict/resolver
.rb
View file @
faa9bd40
module
Gitlab
module
Git
class
Merge
ConflictSideMissing
=
Class
.
new
(
StandardError
)
ResolutionError
=
Class
.
new
(
StandardError
)
def
initialize
(
repository
,
our_commit
,
target_repository
,
their_commit
)
@repository
=
repository
@our_commit
=
our_commit
.
rugged_commit
@target_repository
=
target_repository
@their_commit
=
their_commit
.
rugged_commit
end
module
Conflict
class
Resolver
ConflictSideMissing
=
Class
.
new
(
StandardError
)
ResolutionError
=
Class
.
new
(
StandardError
)
def
initialize
(
repository
,
our_commit
,
target_repository
,
their_commit
)
@repository
=
repository
@our_commit
=
our_commit
.
rugged_commit
@target_repository
=
target_repository
@their_commit
=
their_commit
.
rugged_commit
end
def
conflicts
@conflicts
||=
begin
target_index
=
@target_repository
.
rugged
.
merge_commits
(
@our_commit
,
@their_commit
)
# We don't need to do `with_repo_branch_commit` here, because the target
# project always fetches source refs when creating merge request diffs.
target_index
.
conflicts
.
map
do
|
conflict
|
raise
ConflictSideMissing
unless
conflict
[
:theirs
]
&&
conflict
[
:ours
]
Gitlab
::
Git
::
ConflictFile
.
new
(
@target_repository
,
@our_commit
.
oid
,
conflict
,
target_index
.
merge_file
(
conflict
[
:ours
][
:path
])[
:data
]
)
def
conflicts
@conflicts
||=
begin
target_index
=
@target_repository
.
rugged
.
merge_commits
(
@our_commit
,
@their_commit
)
# We don't need to do `with_repo_branch_commit` here, because the target
# project always fetches source refs when creating merge request diffs.
target_index
.
conflicts
.
map
do
|
conflict
|
raise
ConflictSideMissing
unless
conflict
[
:theirs
]
&&
conflict
[
:ours
]
Gitlab
::
Git
::
Conflict
::
File
.
new
(
@target_repository
,
@our_commit
.
oid
,
conflict
,
target_index
.
merge_file
(
conflict
[
:ours
][
:path
])[
:data
]
)
end
end
end
end
def
resolve_conflicts
(
user
,
files
,
source_branch
:,
target_branch
:,
commit_message
:)
@repository
.
with_repo_branch_commit
(
@target_repository
,
target_branch
)
do
files
.
each
do
|
file_params
|
conflict_file
=
conflict_for_path
(
file_params
[
:old_path
],
file_params
[
:new_path
])
def
resolve_conflicts
(
user
,
files
,
source_branch
:,
target_branch
:,
commit_message
:)
@repository
.
with_repo_branch_commit
(
@target_repository
,
target_branch
)
do
files
.
each
do
|
file_params
|
conflict_file
=
conflict_for_path
(
file_params
[
:old_path
],
file_params
[
:new_path
])
write_resolved_file_to_index
(
conflict_file
,
file_params
)
end
write_resolved_file_to_index
(
conflict_file
,
file_params
)
end
unless
index
.
conflicts
.
empty?
missing_files
=
index
.
conflicts
.
map
{
|
file
|
file
[
:ours
][
:path
]
}
unless
index
.
conflicts
.
empty?
missing_files
=
index
.
conflicts
.
map
{
|
file
|
file
[
:ours
][
:path
]
}
raise
ResolutionError
,
"Missing resolutions for the following files:
#{
missing_files
.
join
(
', '
)
}
"
end
raise
ResolutionError
,
"Missing resolutions for the following files:
#{
missing_files
.
join
(
', '
)
}
"
end
commit_params
=
{
message:
commit_message
,
parents:
[
@our_commit
,
@their_commit
].
map
(
&
:oid
)
}
commit_params
=
{
message:
commit_message
,
parents:
[
@our_commit
,
@their_commit
].
map
(
&
:oid
)
}
@repository
.
commit_index
(
user
,
source_branch
,
index
,
commit_params
)
@repository
.
commit_index
(
user
,
source_branch
,
index
,
commit_params
)
end
end
end
def
conflict_for_path
(
old_path
,
new_path
)
conflicts
.
find
do
|
conflict
|
conflict
.
their_path
==
old_path
&&
conflict
.
our_path
==
new_path
def
conflict_for_path
(
old_path
,
new_path
)
conflicts
.
find
do
|
conflict
|
conflict
.
their_path
==
old_path
&&
conflict
.
our_path
==
new_path
end
end
end
private
private
# We can only write when getting the merge index from the source
# project, because we will write to that project. We don't use this all
# the time because this fetches a ref into the source project, which
# isn't needed for reading.
def
index
@index
||=
@repository
.
rugged
.
merge_commits
(
@our_commit
,
@their_commit
)
end
# We can only write when getting the merge index from the source
# project, because we will write to that project. We don't use this all
# the time because this fetches a ref into the source project, which
# isn't needed for reading.
def
index
@index
||=
@repository
.
rugged
.
merge_commits
(
@our_commit
,
@their_commit
)
end
def
write_resolved_file_to_index
(
file
,
params
)
if
params
[
:sections
]
resolved_lines
=
file
.
resolve_lines
(
params
[
:sections
])
new_file
=
resolved_lines
.
map
{
|
line
|
line
[
:full_line
]
}.
join
(
"
\n
"
)
def
write_resolved_file_to_index
(
file
,
params
)
if
params
[
:sections
]
resolved_lines
=
file
.
resolve_lines
(
params
[
:sections
])
new_file
=
resolved_lines
.
map
{
|
line
|
line
[
:full_line
]
}.
join
(
"
\n
"
)
new_file
<<
"
\n
"
if
file
.
our_blob
.
data
.
ends_with?
(
"
\n
"
)
elsif
params
[
:content
]
new_file
=
file
.
resolve_content
(
params
[
:content
])
end
new_file
<<
"
\n
"
if
file
.
our_blob
.
data
.
ends_with?
(
"
\n
"
)
elsif
params
[
:content
]
new_file
=
file
.
resolve_content
(
params
[
:content
])
end
our_path
=
file
.
our_path
our_path
=
file
.
our_path
index
.
add
(
path:
our_path
,
oid:
@repository
.
rugged
.
write
(
new_file
,
:blob
),
mode:
file
.
our_mode
)
index
.
conflict_remove
(
our_path
)
index
.
add
(
path:
our_path
,
oid:
@repository
.
rugged
.
write
(
new_file
,
:blob
),
mode:
file
.
our_mode
)
index
.
conflict_remove
(
our_path
)
end
end
end
end
...
...
lib/gitlab/github_import/comment_formatter.rb
View file @
faa9bd40
...
...
@@ -38,7 +38,7 @@ module Gitlab
end
def
generate_line_code
(
line
)
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
file_path
,
line
.
new_pos
,
line
.
old_pos
)
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
file_path
,
line
.
new_pos
,
line
.
old_pos
)
end
def
on_diff?
...
...
spec/controllers/projects/merge_requests/conflicts_controller_spec.rb
View file @
faa9bd40
...
...
@@ -17,8 +17,8 @@ describe Projects::MergeRequests::ConflictsController do
describe
'GET show'
do
context
'when the conflicts cannot be resolved in the UI'
do
before
do
allow
(
Gitlab
::
Git
::
ConflictParser
).
to
receive
(
:parse
)
.
and_raise
(
Gitlab
::
Git
::
ConflictParser
::
UnmergeableFile
)
allow
(
Gitlab
::
Git
::
Conflict
::
Parser
).
to
receive
(
:parse
)
.
and_raise
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnmergeableFile
)
get
:show
,
namespace_id:
merge_request_with_conflicts
.
project
.
namespace
.
to_param
,
...
...
@@ -109,8 +109,8 @@ describe Projects::MergeRequests::ConflictsController do
context
'when the conflicts cannot be resolved in the UI'
do
before
do
allow
(
Gitlab
::
Git
::
ConflictParser
).
to
receive
(
:parse
)
.
and_raise
(
Gitlab
::
Git
::
ConflictParser
::
UnmergeableFile
)
allow
(
Gitlab
::
Git
::
Conflict
::
Parser
).
to
receive
(
:parse
)
.
and_raise
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnmergeableFile
)
conflict_for_path
(
'files/ruby/regex.rb'
)
end
...
...
spec/lib/gitlab/conflict/file_spec.rb
View file @
faa9bd40
...
...
@@ -10,7 +10,7 @@ describe Gitlab::Conflict::File do
let
(
:index
)
{
rugged
.
merge_commits
(
our_commit
,
their_commit
)
}
let
(
:rugged_conflict
)
{
index
.
conflicts
.
last
}
let
(
:raw_conflict_content
)
{
index
.
merge_file
(
'files/ruby/regex.rb'
)[
:data
]
}
let
(
:raw_conflict_file
)
{
Gitlab
::
Git
::
ConflictFile
.
new
(
repository
,
our_commit
.
oid
,
rugged_conflict
,
raw_conflict_content
)
}
let
(
:raw_conflict_file
)
{
Gitlab
::
Git
::
Conflict
::
File
.
new
(
repository
,
our_commit
.
oid
,
rugged_conflict
,
raw_conflict_content
)
}
let
(
:conflict_file
)
{
described_class
.
new
(
raw_conflict_file
,
merge_request:
merge_request
)
}
describe
'#resolve_lines'
do
...
...
@@ -54,13 +54,13 @@ describe Gitlab::Conflict::File do
invalid_hash
=
section_keys
.
map
{
|
key
|
[
key
,
'invalid'
]
}.
to_h
expect
{
conflict_file
.
resolve_lines
({})
}
.
to
raise_error
(
Gitlab
::
Git
::
Merge
::
ResolutionError
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Resolver
::
ResolutionError
)
expect
{
conflict_file
.
resolve_lines
(
empty_hash
)
}
.
to
raise_error
(
Gitlab
::
Git
::
Merge
::
ResolutionError
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Resolver
::
ResolutionError
)
expect
{
conflict_file
.
resolve_lines
(
invalid_hash
)
}
.
to
raise_error
(
Gitlab
::
Git
::
Merge
::
ResolutionError
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Resolver
::
ResolutionError
)
end
end
...
...
spec/lib/gitlab/diff/position_spec.rb
View file @
faa9bd40
...
...
@@ -40,7 +40,7 @@ describe Gitlab::Diff::Position do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
0
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
0
)
expect
(
subject
.
line_code
(
project
.
repository
)).
to
eq
(
line_code
)
end
...
...
@@ -108,7 +108,7 @@ describe Gitlab::Diff::Position do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
15
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
15
)
expect
(
subject
.
line_code
(
project
.
repository
)).
to
eq
(
line_code
)
end
...
...
@@ -149,7 +149,7 @@ describe Gitlab::Diff::Position do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
subject
.
old_line
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
subject
.
old_line
)
expect
(
subject
.
line_code
(
project
.
repository
)).
to
eq
(
line_code
)
end
...
...
@@ -189,7 +189,7 @@ describe Gitlab::Diff::Position do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
subject
.
file_path
,
13
,
subject
.
old_line
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
subject
.
file_path
,
13
,
subject
.
old_line
)
expect
(
subject
.
line_code
(
project
.
repository
)).
to
eq
(
line_code
)
end
...
...
@@ -233,7 +233,7 @@ describe Gitlab::Diff::Position do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
5
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
5
)
expect
(
subject
.
line_code
(
project
.
repository
)).
to
eq
(
line_code
)
end
...
...
@@ -274,7 +274,7 @@ describe Gitlab::Diff::Position do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
subject
.
old_line
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
subject
.
old_line
)
expect
(
subject
.
line_code
(
project
.
repository
)).
to
eq
(
line_code
)
end
...
...
@@ -314,7 +314,7 @@ describe Gitlab::Diff::Position do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
subject
.
file_path
,
4
,
subject
.
old_line
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
subject
.
file_path
,
4
,
subject
.
old_line
)
expect
(
subject
.
line_code
(
project
.
repository
)).
to
eq
(
line_code
)
end
...
...
@@ -357,7 +357,7 @@ describe Gitlab::Diff::Position do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
subject
.
file_path
,
0
,
subject
.
old_line
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
subject
.
file_path
,
0
,
subject
.
old_line
)
expect
(
subject
.
line_code
(
project
.
repository
)).
to
eq
(
line_code
)
end
...
...
@@ -399,7 +399,7 @@ describe Gitlab::Diff::Position do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
0
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
subject
.
file_path
,
subject
.
new_line
,
0
)
expect
(
subject
.
line_code
(
project
.
repository
)).
to
eq
(
line_code
)
end
...
...
@@ -447,7 +447,7 @@ describe Gitlab::Diff::Position do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
subject
.
file_path
,
0
,
subject
.
old_line
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
subject
.
file_path
,
0
,
subject
.
old_line
)
expect
(
subject
.
line_code
(
project
.
repository
)).
to
eq
(
line_code
)
end
...
...
spec/lib/gitlab/git/conflict
_
parser_spec.rb
→
spec/lib/gitlab/git/conflict
/
parser_spec.rb
View file @
faa9bd40
require
'spec_helper'
describe
Gitlab
::
Git
::
ConflictParser
do
describe
Gitlab
::
Git
::
Conflict
::
Parser
do
describe
'.parse'
do
def
parse_text
(
text
)
described_class
.
parse
(
text
,
our_path:
'README.md'
,
their_path:
'README.md'
)
...
...
@@ -125,12 +125,12 @@ CONFLICT
context
'when there is a non-start delimiter first'
do
it
'raises UnexpectedDelimiter when there is a middle delimiter first'
do
expect
{
parse_text
(
'======='
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
UnexpectedDelimiter
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnexpectedDelimiter
)
end
it
'raises UnexpectedDelimiter when there is an end delimiter first'
do
expect
{
parse_text
(
'>>>>>>> README.md'
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
UnexpectedDelimiter
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnexpectedDelimiter
)
end
it
'does not raise when there is an end delimiter for a different path first'
do
...
...
@@ -145,12 +145,12 @@ CONFLICT
it
'raises UnexpectedDelimiter when it is followed by an end delimiter'
do
expect
{
parse_text
(
start_text
+
'>>>>>>> README.md'
+
end_text
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
UnexpectedDelimiter
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnexpectedDelimiter
)
end
it
'raises UnexpectedDelimiter when it is followed by another start delimiter'
do
expect
{
parse_text
(
start_text
+
start_text
+
end_text
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
UnexpectedDelimiter
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnexpectedDelimiter
)
end
it
'does not raise when it is followed by a start delimiter for a different path'
do
...
...
@@ -165,12 +165,12 @@ CONFLICT
it
'raises UnexpectedDelimiter when it is followed by another middle delimiter'
do
expect
{
parse_text
(
start_text
+
'======='
+
end_text
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
UnexpectedDelimiter
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnexpectedDelimiter
)
end
it
'raises UnexpectedDelimiter when it is followed by a start delimiter'
do
expect
{
parse_text
(
start_text
+
start_text
+
end_text
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
UnexpectedDelimiter
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnexpectedDelimiter
)
end
it
'does not raise when it is followed by a start delimiter for another path'
do
...
...
@@ -183,25 +183,25 @@ CONFLICT
start_text
=
"<<<<<<< README.md
\n
=======
\n
"
expect
{
parse_text
(
start_text
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
MissingEndDelimiter
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
MissingEndDelimiter
)
expect
{
parse_text
(
start_text
+
'>>>>>>> some-other-path.md'
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
MissingEndDelimiter
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
MissingEndDelimiter
)
end
end
context
'other file types'
do
it
'raises UnmergeableFile when lines is blank, indicating a binary file'
do
expect
{
parse_text
(
''
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
UnmergeableFile
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnmergeableFile
)
expect
{
parse_text
(
nil
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
UnmergeableFile
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnmergeableFile
)
end
it
'raises UnmergeableFile when the file is over 200 KB'
do
expect
{
parse_text
(
'a'
*
204801
)
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
UnmergeableFile
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnmergeableFile
)
end
# All text from Rugged has an encoding of ASCII_8BIT, so force that in
...
...
@@ -216,7 +216,7 @@ CONFLICT
context
'when the file contains non-UTF-8 characters'
do
it
'raises UnsupportedEncoding'
do
expect
{
parse_text
(
"a
\xC4\xFC
"
.
force_encoding
(
Encoding
::
ASCII_8BIT
))
}
.
to
raise_error
(
Gitlab
::
Git
::
ConflictParser
::
UnsupportedEncoding
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Parser
::
UnsupportedEncoding
)
end
end
end
...
...
spec/models/diff_note_spec.rb
View file @
faa9bd40
...
...
@@ -105,7 +105,7 @@ describe DiffNote do
describe
"#line_code"
do
it
"returns the correct line code"
do
line_code
=
Gitlab
::
Git
::
Diff
LineCode
.
generate
(
position
.
file_path
,
position
.
formatter
.
new_line
,
15
)
line_code
=
Gitlab
::
Git
::
Conflict
::
LineCode
.
generate
(
position
.
file_path
,
position
.
formatter
.
new_line
,
15
)
expect
(
subject
.
line_code
).
to
eq
(
line_code
)
end
...
...
spec/services/merge_requests/conflicts/resolve_service_spec.rb
View file @
faa9bd40
...
...
@@ -204,16 +204,16 @@ describe MergeRequests::Conflicts::ResolveService do
it
'raises a ResolutionError error'
do
expect
{
service
.
execute
(
user
,
invalid_params
)
}
.
to
raise_error
(
Gitlab
::
Git
::
Merge
::
ResolutionError
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Resolver
::
ResolutionError
)
end
end
context
'when the content of a file is unchanged'
do
let
(
:
merge
)
do
MergeRequests
::
Conflicts
::
ListService
.
new
(
merge_request
).
conflicts
.
merge
let
(
:
resolver
)
do
MergeRequests
::
Conflicts
::
ListService
.
new
(
merge_request
).
conflicts
.
resolver
end
let
(
:regex_conflict
)
do
merge
.
conflict_for_path
(
'files/ruby/regex.rb'
,
'files/ruby/regex.rb'
)
resolver
.
conflict_for_path
(
'files/ruby/regex.rb'
,
'files/ruby/regex.rb'
)
end
let
(
:invalid_params
)
do
...
...
@@ -235,7 +235,7 @@ describe MergeRequests::Conflicts::ResolveService do
it
'raises a ResolutionError error'
do
expect
{
service
.
execute
(
user
,
invalid_params
)
}
.
to
raise_error
(
Gitlab
::
Git
::
Merge
::
ResolutionError
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Resolver
::
ResolutionError
)
end
end
...
...
@@ -255,7 +255,7 @@ describe MergeRequests::Conflicts::ResolveService do
it
'raises a ResolutionError error'
do
expect
{
service
.
execute
(
user
,
invalid_params
)
}
.
to
raise_error
(
Gitlab
::
Git
::
Merge
::
ResolutionError
)
.
to
raise_error
(
Gitlab
::
Git
::
Conflict
::
Resolver
::
ResolutionError
)
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