Class: Gitlab::Diff::PositionTracer::LineStrategy
- Inherits:
-
BaseStrategy
- Object
- BaseStrategy
- Gitlab::Diff::PositionTracer::LineStrategy
- Defined in:
- lib/gitlab/diff/position_tracer/line_strategy.rb
Instance Attribute Summary
Attributes inherited from BaseStrategy
Instance Method Summary collapse
Methods inherited from BaseStrategy
Constructor Details
This class inherits a constructor from Gitlab::Diff::PositionTracer::BaseStrategy
Instance Method Details
#trace(position) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/gitlab/diff/position_tracer/line_strategy.rb', line 7 def trace(position) # Suppose we have an MR with source branch `feature` and target branch `master`. # When the MR was created, the head of `master` was commit A, and the # head of `feature` was commit B, resulting in the original diff A->B. # Since creation, `master` was updated to C. # Now `feature` is being updated to D, and the newly generated MR diff is C->D. # It is possible that C and D are direct descendants of A and B respectively, # but this isn't necessarily the case as rebases and merges come into play. # # Suppose we have a diff note on the original diff A->B. Now that the MR # is updated, we need to find out what line in C->D corresponds to the # line the note was originally created on, so that we can update the diff note's # records and continue to display it in the right place in the diffs. # If we cannot find this line in the new diff, this means the diff note is now # outdated, and we will display that fact to the user. # # In the new diff, the file the diff note was originally created on may # have been renamed, deleted or even created, if the file existed in A and B, # but was removed in C, and restored in D. # # Every diff note stores a Position object that defines a specific location, # identified by paths and line numbers, within a specific diff, identified # by start, head and base commit ids. # # For diff notes for diff A->B, the position looks like this: # Position # start_sha - ID of commit A # head_sha - ID of commit B # base_sha - ID of base commit of A and B # old_path - path as of A (nil if file was newly created) # new_path - path as of B (nil if file was deleted) # old_line - line number as of A (nil if file was newly created) # new_line - line number as of B (nil if file was deleted) # # We can easily update `start_sha` and `head_sha` to hold the IDs of # commits C and D, and can trivially determine `base_sha` based on those, # but need to find the paths and line numbers as of C and D. # # If the file was unchanged or newly created in A->B, the path as of D can be found # by generating diff B->D ("head to head"), finding the diff file with # `diff_file.old_path == position.new_path`, and taking `diff_file.new_path`. # The path as of C can be found by taking diff C->D, finding the diff file # with that same `new_path` and taking `diff_file.old_path`. # The line number as of D can be found by using the LineMapper on diff B->D # and providing the line number as of B. # The line number as of C can be found by using the LineMapper on diff C->D # and providing the line number as of D. # # If the file was deleted in A->B, the path as of C can be found # by generating diff A->C ("base to base"), finding the diff file with # `diff_file.old_path == position.old_path`, and taking `diff_file.new_path`. # The path as of D can be found by taking diff C->D, finding the diff file # with `old_path` set to that `diff_file.new_path` and taking `diff_file.new_path`. # The line number as of C can be found by using the LineMapper on diff A->C # and providing the line number as of A. # The line number as of D can be found by using the LineMapper on diff C->D # and providing the line number as of C. @ignore_whitespace_change = position.ignore_whitespace_change if position.added? trace_added_line(position) elsif position.removed? trace_removed_line(position) else # unchanged trace_unchanged_line(position) end end |