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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gitlab-ce
Commits
e9e06ca6
Commit
e9e06ca6
authored
Jun 20, 2016
by
Douwe Maan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Gitlab::Diff::LineMapper
parent
9abcc0a9
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
201 additions
and
0 deletions
+201
-0
lib/gitlab/diff/line_mapper.rb
lib/gitlab/diff/line_mapper.rb
+64
-0
spec/lib/gitlab/diff/line_mapper_spec.rb
spec/lib/gitlab/diff/line_mapper_spec.rb
+137
-0
No files found.
lib/gitlab/diff/line_mapper.rb
0 → 100644
View file @
e9e06ca6
# When provided a diff for a specific file, maps old line numbers to new line
# numbers and back, to find out where a specific line in a file was moved by the
# changes.
module
Gitlab
module
Diff
class
LineMapper
attr_accessor
:diff_file
def
initialize
(
diff_file
)
@diff_file
=
diff_file
end
# Find new line number for old line number.
def
old_to_new
(
old_line
)
map_line_number
(
old_line
,
from: :old_line
,
to: :new_line
)
end
# Find old line number for new line number.
def
new_to_old
(
new_line
)
map_line_number
(
new_line
,
from: :new_line
,
to: :old_line
)
end
private
def
diff_lines
@diff_lines
||=
@diff_file
.
diff_lines
end
# Find old line number based on new line number.
def
map_line_number
(
from_line
,
from
:,
to
:)
# If no diff file could be found, the file wasn't changed, and the
# mapped line number is the same as the specified line number.
return
from_line
unless
diff_file
# To find the mapped line number for the specified line number,
# we need to find:
# - The diff line with that exact line number, if it is in the diff context
# - The first diff line with a higher line number, if it falls between diff contexts
# - The last known diff line, if it falls after the last diff context
diff_line
=
diff_lines
.
find
do
|
diff_line
|
diff_from_line
=
diff_line
.
send
(
from
)
diff_from_line
&&
diff_from_line
>=
from_line
end
diff_line
||=
diff_lines
.
last
# If no diff line could be found, the file wasn't changed, and the
# mapped line number is the same as the specified line number.
return
from_line
unless
diff_line
diff_from_line
=
diff_line
.
send
(
from
)
diff_to_line
=
diff_line
.
send
(
to
)
# If the line was removed, there is no mapped line number.
return
unless
diff_to_line
# Because we may not have the diff line with the exact line number
# we were looking for, we need to adjust the mapped line number.
distance
=
diff_from_line
-
from_line
diff_to_line
-
distance
end
end
end
end
spec/lib/gitlab/diff/line_mapper_spec.rb
0 → 100644
View file @
e9e06ca6
require
'spec_helper'
describe
Gitlab
::
Diff
::
LineMapper
,
lib:
true
do
include
RepoHelpers
let
(
:project
)
{
create
(
:project
)
}
let
(
:repository
)
{
project
.
repository
}
let
(
:commit
)
{
project
.
commit
(
sample_commit
.
id
)
}
let
(
:diffs
)
{
commit
.
diffs
}
let
(
:diff
)
{
diffs
.
first
}
let
(
:diff_file
)
{
Gitlab
::
Diff
::
File
.
new
(
diff
,
diff_refs:
commit
.
diff_refs
,
repository:
repository
)
}
subject
{
described_class
.
new
(
diff_file
)
}
describe
'#old_to_new'
do
context
"with a diff file"
do
let
(
:mapping
)
do
{
1
=>
1
,
2
=>
2
,
3
=>
3
,
4
=>
4
,
5
=>
5
,
6
=>
6
,
7
=>
7
,
8
=>
8
,
9
=>
nil
,
# nil => 9,
10
=>
10
,
11
=>
11
,
12
=>
12
,
13
=>
nil
,
14
=>
nil
,
# nil => 15,
# nil => 16,
# nil => 17,
# nil => 18,
# nil => 19,
# nil => 20,
15
=>
21
,
16
=>
22
,
17
=>
23
,
18
=>
24
,
19
=>
25
,
20
=>
26
,
21
=>
27
,
# nil => 28,
22
=>
29
,
23
=>
30
,
24
=>
31
,
25
=>
32
,
26
=>
33
,
27
=>
34
,
28
=>
35
,
29
=>
36
,
30
=>
37
}
end
it
'returns the new line number for the old line number'
do
mapping
.
each
do
|
old_line
,
new_line
|
expect
(
subject
.
old_to_new
(
old_line
)).
to
eq
(
new_line
)
end
end
end
context
"without a diff file"
do
let
(
:diff_file
)
{
nil
}
it
"returns the same line number"
do
expect
(
subject
.
old_to_new
(
100
)).
to
eq
(
100
)
end
end
end
describe
'#new_to_old'
do
context
"with a diff file"
do
let
(
:mapping
)
do
{
1
=>
1
,
2
=>
2
,
3
=>
3
,
4
=>
4
,
5
=>
5
,
6
=>
6
,
7
=>
7
,
8
=>
8
,
# nil => 9,
9
=>
nil
,
10
=>
10
,
11
=>
11
,
12
=>
12
,
# nil => 13,
# nil => 14,
13
=>
nil
,
14
=>
nil
,
15
=>
nil
,
16
=>
nil
,
17
=>
nil
,
18
=>
nil
,
19
=>
nil
,
20
=>
nil
,
21
=>
15
,
22
=>
16
,
23
=>
17
,
24
=>
18
,
25
=>
19
,
26
=>
20
,
27
=>
21
,
28
=>
nil
,
29
=>
22
,
30
=>
23
,
31
=>
24
,
32
=>
25
,
33
=>
26
,
34
=>
27
,
35
=>
28
,
36
=>
29
,
37
=>
30
}
end
it
'returns the old line number for the new line number'
do
mapping
.
each
do
|
new_line
,
old_line
|
expect
(
subject
.
new_to_old
(
new_line
)).
to
eq
(
old_line
)
end
end
end
context
"without a diff file"
do
let
(
:diff_file
)
{
nil
}
it
"returns the same line number"
do
expect
(
subject
.
new_to_old
(
100
)).
to
eq
(
100
)
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