Walking forward through history (i.e., topologically earliest
commits first), we filter the parent list of every commit as
follows. Consider a parent P:
- If P touches any of the interesting line ranges, we keep it.
- If P is a merge and it takes all the interesting line ranges
from one of its parents, P is rewritten to this parent, else
we keep P.
- Otherwise, P is rewritten to its (only) parent P^.
Signed-off-by: Bo Yang <struggleyb.nku@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
To correctly track the line ranges over several branches,
we must make sure that we have processed all children before
reaching the commit itself.
Thus we introduce a first pass in cmd_line_log that runs
prepare_revision_walk to achieve the topological ordering.
Signed-off-by: Bo Yang <struggleyb.nku@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Since diff_line_range can form a single list through its
'next' pointer, we provide two kind of clone.
diff_line_range_clone:
used to clone only the element node and set the
element's 'next' pointer to NULL.
diff_line_range_clone_deeply:
used to clone the whole list of ranges.
Signed-off-by: Bo Yang <struggleyb.nku@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Both 'git blame -L' and 'git log -L' parse the same style
of line number arguments, so put the 'parse_loc' function
to line.c and export it.
The caller of parse_loc should provide a callback function
which is used to calculate the start position of the nth line.
Other parts such as regexp search, line number parsing are
abstracted and re-used.
Note that, we can use '$' to specify the last line of a file.
Signed-off-by: Bo Yang <struggleyb.nku@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
'struct diff_line_range' is the main data structure to keep
track of the line ranges we are currently interested in. The
user starts digging from a line range, and after examining the
diff that affects that range by a commit, we can find a new
range that corresponds to this range. So, we will associate this
new range with the commit's parent commit.
There is one 'diff_line_range' for each file, and there are
multiple 'struct line_range' in each 'diff_line_range'. In this way,
we support multiple ranges.
Within 'struct line_range', there are multiple 'struct print_range'
which represent a diff hunk.
Signed-off-by: Bo Yang <struggleyb.nku@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>