2017-05-24 13:15:32 +08:00
|
|
|
#ifndef BLAME_H
|
|
|
|
#define BLAME_H
|
|
|
|
|
|
|
|
#include "commit.h"
|
|
|
|
#include "xdiff-interface.h"
|
|
|
|
#include "revision.h"
|
|
|
|
#include "prio-queue.h"
|
2017-05-24 13:15:34 +08:00
|
|
|
#include "diff.h"
|
2017-05-24 13:15:32 +08:00
|
|
|
|
2017-05-24 13:15:35 +08:00
|
|
|
#define PICKAXE_BLAME_MOVE 01
|
|
|
|
#define PICKAXE_BLAME_COPY 02
|
|
|
|
#define PICKAXE_BLAME_COPY_HARDER 04
|
|
|
|
#define PICKAXE_BLAME_COPY_HARDEST 010
|
|
|
|
|
2017-05-24 13:15:36 +08:00
|
|
|
#define BLAME_DEFAULT_MOVE_SCORE 20
|
|
|
|
#define BLAME_DEFAULT_COPY_SCORE 40
|
|
|
|
|
2020-02-24 00:56:31 +08:00
|
|
|
struct fingerprint;
|
|
|
|
|
2017-05-24 13:15:32 +08:00
|
|
|
/*
|
|
|
|
* One blob in a commit that is being suspected
|
|
|
|
*/
|
|
|
|
struct blame_origin {
|
|
|
|
int refcnt;
|
|
|
|
/* Record preceding blame record for this blob */
|
|
|
|
struct blame_origin *previous;
|
|
|
|
/* origins are put in a list linked via `next' hanging off the
|
|
|
|
* corresponding commit's util field in order to make finding
|
|
|
|
* them fast. The presence in this chain does not count
|
|
|
|
* towards the origin's reference count. It is tempting to
|
|
|
|
* let it count as long as the commit is pending examination,
|
|
|
|
* but even under circumstances where the commit will be
|
|
|
|
* present multiple times in the priority queue of unexamined
|
|
|
|
* commits, processing the first instance will not leave any
|
|
|
|
* work requiring the origin data for the second instance. An
|
|
|
|
* interspersed commit changing that would have to be
|
|
|
|
* preexisting with a different ancestry and with the same
|
|
|
|
* commit date in order to wedge itself between two instances
|
|
|
|
* of the same commit in the priority queue _and_ produce
|
|
|
|
* blame entries relevant for it. While we don't want to let
|
|
|
|
* us get tripped up by this case, it certainly does not seem
|
|
|
|
* worth optimizing for.
|
|
|
|
*/
|
|
|
|
struct blame_origin *next;
|
|
|
|
struct commit *commit;
|
|
|
|
/* `suspects' contains blame entries that may be attributed to
|
|
|
|
* this origin's commit or to parent commits. When a commit
|
|
|
|
* is being processed, all suspects will be moved, either by
|
|
|
|
* assigning them to an origin in a different commit, or by
|
|
|
|
* shipping them to the scoreboard's ent list because they
|
|
|
|
* cannot be attributed to a different commit.
|
|
|
|
*/
|
|
|
|
struct blame_entry *suspects;
|
|
|
|
mmfile_t file;
|
2019-05-16 05:45:01 +08:00
|
|
|
int num_lines;
|
2020-02-24 00:56:31 +08:00
|
|
|
struct fingerprint *fingerprints;
|
2017-05-24 13:15:32 +08:00
|
|
|
struct object_id blob_oid;
|
2019-04-05 23:00:12 +08:00
|
|
|
unsigned short mode;
|
2017-05-24 13:15:32 +08:00
|
|
|
/* guilty gets set when shipping any suspects to the final
|
|
|
|
* blame list instead of other commits
|
|
|
|
*/
|
|
|
|
char guilty;
|
|
|
|
char path[FLEX_ARRAY];
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Each group of lines is described by a blame_entry; it can be split
|
|
|
|
* as we pass blame to the parents. They are arranged in linked lists
|
|
|
|
* kept as `suspects' of some unprocessed origin, or entered (when the
|
|
|
|
* blame origin has been finalized) into the scoreboard structure.
|
|
|
|
* While the scoreboard structure is only sorted at the end of
|
|
|
|
* processing (according to final image line number), the lists
|
|
|
|
* attached to an origin are sorted by the target line number.
|
|
|
|
*/
|
|
|
|
struct blame_entry {
|
|
|
|
struct blame_entry *next;
|
|
|
|
|
|
|
|
/* the first line of this group in the final image;
|
|
|
|
* internally all line numbers are 0 based.
|
|
|
|
*/
|
|
|
|
int lno;
|
|
|
|
|
|
|
|
/* how many lines this group has */
|
|
|
|
int num_lines;
|
|
|
|
|
|
|
|
/* the commit that introduced this group into the final image */
|
|
|
|
struct blame_origin *suspect;
|
|
|
|
|
|
|
|
/* the line number of the first line of this group in the
|
|
|
|
* suspect's file; internally all line numbers are 0 based.
|
|
|
|
*/
|
|
|
|
int s_lno;
|
|
|
|
|
|
|
|
/* how significant this entry is -- cached to avoid
|
|
|
|
* scanning the lines over and over.
|
|
|
|
*/
|
|
|
|
unsigned score;
|
blame: add config options for the output of ignored or unblamable lines
When ignoring commits, the commit that is blamed might not be
responsible for the change, due to the inaccuracy of our heuristic.
Users might want to know when a particular line has a potentially
inaccurate blame.
Furthermore, guess_line_blames() may fail to find any parent commit for
a given line touched by an ignored commit. Those 'unblamable' lines
remain blamed on an ignored commit. Users might want to know if a line
is unblamable so that they do not spend time investigating a commit they
know is uninteresting.
This patch adds two config options to mark these two types of lines in
the output of blame.
The first option can identify ignored lines by specifying
blame.markIgnoredLines. When this option is set, each blame line that
was blamed on a commit other than the ignored commit is marked with a
'?'.
For example:
278b6158d6fdb (Barret Rhoden 2016-04-11 13:57:54 -0400 26)
appears as:
?278b6158d6fd (Barret Rhoden 2016-04-11 13:57:54 -0400 26)
where the '?' is placed before the commit, and the hash has one fewer
characters.
Sometimes we are unable to even guess at what ancestor commit touched a
line. These lines are 'unblamable.' The second option,
blame.markUnblamableLines, will mark the line with '*'.
For example, say we ignore e5e8d36d04cbe, yet we are unable to blame
this line on another commit:
e5e8d36d04cbe (Barret Rhoden 2016-04-11 13:57:54 -0400 26)
appears as:
*e5e8d36d04cb (Barret Rhoden 2016-04-11 13:57:54 -0400 26)
When these config options are used together, every line touched by an
ignored commit will be marked with either a '?' or a '*'.
Signed-off-by: Barret Rhoden <brho@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-05-16 05:45:00 +08:00
|
|
|
int ignored;
|
|
|
|
int unblamable;
|
2017-05-24 13:15:32 +08:00
|
|
|
};
|
|
|
|
|
blame: use changed-path Bloom filters
The changed-path Bloom filters help reduce the amount of tree
parsing required during history queries. Before calculating a
diff, we can ask the filter if a path changed between a commit
and its first parent. If the filter says "no" then we can move
on without parsing trees. If the filter says "maybe" then we
parse trees to discover if the answer is actually "yes" or "no".
When computing a blame, there is a section in find_origin() that
computes a diff between a commit and one of its parents. When this
is the first parent, we can check the Bloom filters before calling
diff_tree_oid().
In order to make this work with the blame machinery, we need to
initialize a struct bloom_key with the initial path. But also, we
need to add more keys to a list if a rename is detected. We then
check to see if _any_ of these keys answer "maybe" in the diff.
During development, I purposefully left out this "add a new key
when a rename is detected" to see if the test suite would catch
my error. That is how I discovered the issues with
GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS from the previous change.
With that change, we can feel some confidence in the coverage of
this change.
If a user requests copy detection using "git blame -C", then there
are more places where the set of "important" files can expand. I
do not know enough about how this happens in the blame machinery.
Thus, the Bloom filter integration is explicitly disabled in this
mode. A later change could expand the bloom_key data with an
appropriate call (or calls) to add_bloom_key().
If we did not disable this mode, then the following tests would
fail:
t8003-blame-corner-cases.sh
t8011-blame-split-file.sh
Generally, this is a performance enhancement and should not
change the behavior of 'git blame' in any way. If a repo has a
commit-graph file with computed changed-path Bloom filters, then
they should notice improved performance for their 'git blame'
commands.
Here are some example timings that I found by blaming some paths
in the Linux kernel repository:
git blame arch/x86/kernel/topology.c >/dev/null
Before: 0.83s
After: 0.24s
git blame kernel/time/time.c >/dev/null
Before: 0.72s
After: 0.24s
git blame tools/perf/ui/stdio/hist.c >/dev/null
Before: 0.27s
After: 0.11s
I specifically looked for "deep" paths that were also edited many
times. As a counterpoint, the MAINTAINERS file was edited many
times but is located in the root tree. This means that the cost of
computing a diff relative to the pathspec is very small. Here are
the timings for that command:
git blame MAINTAINERS >/dev/null
Before: 20.1s
After: 18.0s
These timings are the best of five. The worst-case runs were on the
order of 2.5 minutes for both cases. Note that the MAINTAINERS file
has 18,740 lines across 17,000+ commits. This happens to be one of
the cases where this change provides the least improvement.
The lack of improvement for the MAINTAINERS file and the relatively
modest improvement for the other examples can be easily explained.
The blame machinery needs to compute line-level diffs to determine
which lines were changed by each commit. That makes up a large
proportion of the computation time, and this change does not
attempt to improve on that section of the algorithm. The
MAINTAINERS file is large and changed often, so it takes time to
determine which lines were updated by which commit. In contrast,
the code files are much smaller, and it takes longer to comute
the line-by-line diff for a single patch on the Linux mailing
lists.
Outside of the "-C" integration, I believe there is little more to
gain from the changed-path Bloom filters for 'git blame' after this
patch.
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-17 04:14:04 +08:00
|
|
|
struct blame_bloom_data;
|
|
|
|
|
2017-05-24 13:15:32 +08:00
|
|
|
/*
|
|
|
|
* The current state of the blame assignment.
|
|
|
|
*/
|
|
|
|
struct blame_scoreboard {
|
|
|
|
/* the final commit (i.e. where we started digging from) */
|
|
|
|
struct commit *final;
|
|
|
|
/* Priority queue for commits with unassigned blame records */
|
|
|
|
struct prio_queue commits;
|
2018-08-14 00:14:41 +08:00
|
|
|
struct repository *repo;
|
2017-05-24 13:15:32 +08:00
|
|
|
struct rev_info *revs;
|
|
|
|
const char *path;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The contents in the final image.
|
|
|
|
* Used by many functions to obtain contents of the nth line,
|
|
|
|
* indexed with scoreboard.lineno[blame_entry.lno].
|
|
|
|
*/
|
|
|
|
const char *final_buf;
|
|
|
|
unsigned long final_buf_size;
|
|
|
|
|
|
|
|
/* linked list of blames */
|
|
|
|
struct blame_entry *ent;
|
|
|
|
|
blame: add the ability to ignore commits and their changes
Commits that make formatting changes or function renames are often not
interesting when blaming a file. A user may deem such a commit as 'not
interesting' and want to ignore and its changes it when assigning blame.
For example, say a file has the following git history / rev-list:
---O---A---X---B---C---D---Y---E---F
Commits X and Y both touch a particular line, and the other commits do
not:
X: "Take a third parameter"
-MyFunc(1, 2);
+MyFunc(1, 2, 3);
Y: "Remove camelcase"
-MyFunc(1, 2, 3);
+my_func(1, 2, 3);
git-blame will blame Y for the change. I'd like to be able to ignore Y:
both the existence of the commit as well as any changes it made. This
differs from -S rev-list, which specifies the list of commits to
process for the blame. We would still process Y, but just don't let the
blame 'stick.'
This patch adds the ability for users to ignore a revision with
--ignore-rev=rev, which may be repeated. They can specify a set of
files of full object names of revs, e.g. SHA-1 hashes, one per line. A
single file may be specified with the blame.ignoreRevFile config option
or with --ignore-rev-file=file. Both the config option and the command
line option may be repeated multiple times. An empty file name "" will
clear the list of revs from previously processed files. Config options
are processed before command line options.
For a typical use case, projects will maintain the file containing
revisions for commits that perform mass reformatting, and their users
have the option to ignore all of the commits in that file.
Additionally, a user can use the --ignore-rev option for one-off
investigation. To go back to the example above, X was a substantive
change to the function, but not the change the user is interested in.
The user inspected X, but wanted to find the previous change to that
line - perhaps a commit that introduced that function call.
To make this work, we can't simply remove all ignored commits from the
rev-list. We need to diff the changes introduced by Y so that we can
ignore them. We let the blames get passed to Y, just like when
processing normally. When Y is the target, we make sure that Y does not
*keep* any blames. Any changes that Y is responsible for get passed to
its parent. Note we make one pass through all of the scapegoats
(parents) to attempt to pass blame normally; we don't know if we *need*
to ignore the commit until we've checked all of the parents.
The blame_entry will get passed up the tree until we find a commit that
has a diff chunk that affects those lines.
One issue is that the ignored commit *did* make some change, and there is
no general solution to finding the line in the parent commit that
corresponds to a given line in the ignored commit. That makes it hard
to attribute a particular line within an ignored commit's diff
correctly.
For example, the parent of an ignored commit has this, say at line 11:
commit-a 11) #include "a.h"
commit-b 12) #include "b.h"
Commit X, which we will ignore, swaps these lines:
commit-X 11) #include "b.h"
commit-X 12) #include "a.h"
We can pass that blame entry to the parent, but line 11 will be
attributed to commit A, even though "include b.h" came from commit B.
The blame mechanism will be looking at the parent's view of the file at
line number 11.
ignore_blame_entry() is set up to allow alternative algorithms for
guessing per-line blames. Any line that is not attributed to the parent
will continue to be blamed on the ignored commit as if that commit was
not ignored. Upcoming patches have the ability to detect these lines
and mark them in the blame output.
The existing algorithm is simple: blame each line on the corresponding
line in the parent's diff chunk. Any lines beyond that stay with the
target.
For example, the parent of an ignored commit has this, say at line 11:
commit-a 11) void new_func_1(void *x, void *y);
commit-b 12) void new_func_2(void *x, void *y);
commit-c 13) some_line_c
commit-d 14) some_line_d
After a commit 'X', we have:
commit-X 11) void new_func_1(void *x,
commit-X 12) void *y);
commit-X 13) void new_func_2(void *x,
commit-X 14) void *y);
commit-c 15) some_line_c
commit-d 16) some_line_d
Commit X nets two additionally lines: 13 and 14. The current
guess_line_blames() algorithm will not attribute these to the parent,
whose diff chunk is only two lines - not four.
When we ignore with the current algorithm, we get:
commit-a 11) void new_func_1(void *x,
commit-b 12) void *y);
commit-X 13) void new_func_2(void *x,
commit-X 14) void *y);
commit-c 15) some_line_c
commit-d 16) some_line_d
Note that line 12 was blamed on B, though B was the commit for
new_func_2(), not new_func_1(). Even when guess_line_blames() finds a
line in the parent, it may still be incorrect.
Signed-off-by: Barret Rhoden <brho@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-05-16 05:44:59 +08:00
|
|
|
struct oidset ignore_list;
|
|
|
|
|
2017-05-24 13:15:32 +08:00
|
|
|
/* look-up a line in the final buffer */
|
|
|
|
int num_lines;
|
|
|
|
int *lineno;
|
|
|
|
|
|
|
|
/* stats */
|
|
|
|
int num_read_blob;
|
|
|
|
int num_get_patch;
|
|
|
|
int num_commits;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* blame for a blame_entry with score lower than these thresholds
|
|
|
|
* is not passed to the parent using move/copy logic.
|
|
|
|
*/
|
|
|
|
unsigned move_score;
|
|
|
|
unsigned copy_score;
|
|
|
|
|
|
|
|
/* use this file's contents as the final image */
|
|
|
|
const char *contents_from;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
int reverse;
|
|
|
|
int show_root;
|
|
|
|
int xdl_opts;
|
|
|
|
int no_whole_file_rename;
|
|
|
|
int debug;
|
|
|
|
|
|
|
|
/* callbacks */
|
|
|
|
void(*on_sanity_fail)(struct blame_scoreboard *, int);
|
|
|
|
void(*found_guilty_entry)(struct blame_entry *, void *);
|
|
|
|
|
|
|
|
void *found_guilty_entry_data;
|
blame: use changed-path Bloom filters
The changed-path Bloom filters help reduce the amount of tree
parsing required during history queries. Before calculating a
diff, we can ask the filter if a path changed between a commit
and its first parent. If the filter says "no" then we can move
on without parsing trees. If the filter says "maybe" then we
parse trees to discover if the answer is actually "yes" or "no".
When computing a blame, there is a section in find_origin() that
computes a diff between a commit and one of its parents. When this
is the first parent, we can check the Bloom filters before calling
diff_tree_oid().
In order to make this work with the blame machinery, we need to
initialize a struct bloom_key with the initial path. But also, we
need to add more keys to a list if a rename is detected. We then
check to see if _any_ of these keys answer "maybe" in the diff.
During development, I purposefully left out this "add a new key
when a rename is detected" to see if the test suite would catch
my error. That is how I discovered the issues with
GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS from the previous change.
With that change, we can feel some confidence in the coverage of
this change.
If a user requests copy detection using "git blame -C", then there
are more places where the set of "important" files can expand. I
do not know enough about how this happens in the blame machinery.
Thus, the Bloom filter integration is explicitly disabled in this
mode. A later change could expand the bloom_key data with an
appropriate call (or calls) to add_bloom_key().
If we did not disable this mode, then the following tests would
fail:
t8003-blame-corner-cases.sh
t8011-blame-split-file.sh
Generally, this is a performance enhancement and should not
change the behavior of 'git blame' in any way. If a repo has a
commit-graph file with computed changed-path Bloom filters, then
they should notice improved performance for their 'git blame'
commands.
Here are some example timings that I found by blaming some paths
in the Linux kernel repository:
git blame arch/x86/kernel/topology.c >/dev/null
Before: 0.83s
After: 0.24s
git blame kernel/time/time.c >/dev/null
Before: 0.72s
After: 0.24s
git blame tools/perf/ui/stdio/hist.c >/dev/null
Before: 0.27s
After: 0.11s
I specifically looked for "deep" paths that were also edited many
times. As a counterpoint, the MAINTAINERS file was edited many
times but is located in the root tree. This means that the cost of
computing a diff relative to the pathspec is very small. Here are
the timings for that command:
git blame MAINTAINERS >/dev/null
Before: 20.1s
After: 18.0s
These timings are the best of five. The worst-case runs were on the
order of 2.5 minutes for both cases. Note that the MAINTAINERS file
has 18,740 lines across 17,000+ commits. This happens to be one of
the cases where this change provides the least improvement.
The lack of improvement for the MAINTAINERS file and the relatively
modest improvement for the other examples can be easily explained.
The blame machinery needs to compute line-level diffs to determine
which lines were changed by each commit. That makes up a large
proportion of the computation time, and this change does not
attempt to improve on that section of the algorithm. The
MAINTAINERS file is large and changed often, so it takes time to
determine which lines were updated by which commit. In contrast,
the code files are much smaller, and it takes longer to comute
the line-by-line diff for a single patch on the Linux mailing
lists.
Outside of the "-C" integration, I believe there is little more to
gain from the changed-path Bloom filters for 'git blame' after this
patch.
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-17 04:14:04 +08:00
|
|
|
struct blame_bloom_data *bloom_data;
|
2017-05-24 13:15:32 +08:00
|
|
|
};
|
|
|
|
|
2017-05-24 13:15:33 +08:00
|
|
|
/*
|
|
|
|
* Origin is refcounted and usually we keep the blob contents to be
|
|
|
|
* reused.
|
|
|
|
*/
|
|
|
|
static inline struct blame_origin *blame_origin_incref(struct blame_origin *o)
|
|
|
|
{
|
|
|
|
if (o)
|
|
|
|
o->refcnt++;
|
|
|
|
return o;
|
|
|
|
}
|
2018-06-30 17:20:22 +08:00
|
|
|
void blame_origin_decref(struct blame_origin *o);
|
|
|
|
|
|
|
|
void blame_coalesce(struct blame_scoreboard *sb);
|
|
|
|
void blame_sort_final(struct blame_scoreboard *sb);
|
|
|
|
unsigned blame_entry_score(struct blame_scoreboard *sb, struct blame_entry *e);
|
|
|
|
void assign_blame(struct blame_scoreboard *sb, int opt);
|
|
|
|
const char *blame_nth_line(struct blame_scoreboard *sb, long lno);
|
|
|
|
|
|
|
|
void init_scoreboard(struct blame_scoreboard *sb);
|
|
|
|
void setup_scoreboard(struct blame_scoreboard *sb,
|
|
|
|
struct blame_origin **orig);
|
2020-11-02 01:28:47 +08:00
|
|
|
void setup_blame_bloom_data(struct blame_scoreboard *sb);
|
blame: use changed-path Bloom filters
The changed-path Bloom filters help reduce the amount of tree
parsing required during history queries. Before calculating a
diff, we can ask the filter if a path changed between a commit
and its first parent. If the filter says "no" then we can move
on without parsing trees. If the filter says "maybe" then we
parse trees to discover if the answer is actually "yes" or "no".
When computing a blame, there is a section in find_origin() that
computes a diff between a commit and one of its parents. When this
is the first parent, we can check the Bloom filters before calling
diff_tree_oid().
In order to make this work with the blame machinery, we need to
initialize a struct bloom_key with the initial path. But also, we
need to add more keys to a list if a rename is detected. We then
check to see if _any_ of these keys answer "maybe" in the diff.
During development, I purposefully left out this "add a new key
when a rename is detected" to see if the test suite would catch
my error. That is how I discovered the issues with
GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS from the previous change.
With that change, we can feel some confidence in the coverage of
this change.
If a user requests copy detection using "git blame -C", then there
are more places where the set of "important" files can expand. I
do not know enough about how this happens in the blame machinery.
Thus, the Bloom filter integration is explicitly disabled in this
mode. A later change could expand the bloom_key data with an
appropriate call (or calls) to add_bloom_key().
If we did not disable this mode, then the following tests would
fail:
t8003-blame-corner-cases.sh
t8011-blame-split-file.sh
Generally, this is a performance enhancement and should not
change the behavior of 'git blame' in any way. If a repo has a
commit-graph file with computed changed-path Bloom filters, then
they should notice improved performance for their 'git blame'
commands.
Here are some example timings that I found by blaming some paths
in the Linux kernel repository:
git blame arch/x86/kernel/topology.c >/dev/null
Before: 0.83s
After: 0.24s
git blame kernel/time/time.c >/dev/null
Before: 0.72s
After: 0.24s
git blame tools/perf/ui/stdio/hist.c >/dev/null
Before: 0.27s
After: 0.11s
I specifically looked for "deep" paths that were also edited many
times. As a counterpoint, the MAINTAINERS file was edited many
times but is located in the root tree. This means that the cost of
computing a diff relative to the pathspec is very small. Here are
the timings for that command:
git blame MAINTAINERS >/dev/null
Before: 20.1s
After: 18.0s
These timings are the best of five. The worst-case runs were on the
order of 2.5 minutes for both cases. Note that the MAINTAINERS file
has 18,740 lines across 17,000+ commits. This happens to be one of
the cases where this change provides the least improvement.
The lack of improvement for the MAINTAINERS file and the relatively
modest improvement for the other examples can be easily explained.
The blame machinery needs to compute line-level diffs to determine
which lines were changed by each commit. That makes up a large
proportion of the computation time, and this change does not
attempt to improve on that section of the algorithm. The
MAINTAINERS file is large and changed often, so it takes time to
determine which lines were updated by which commit. In contrast,
the code files are much smaller, and it takes longer to comute
the line-by-line diff for a single patch on the Linux mailing
lists.
Outside of the "-C" integration, I believe there is little more to
gain from the changed-path Bloom filters for 'git blame' after this
patch.
Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-17 04:14:04 +08:00
|
|
|
void cleanup_scoreboard(struct blame_scoreboard *sb);
|
2018-06-30 17:20:22 +08:00
|
|
|
|
|
|
|
struct blame_entry *blame_entry_prepend(struct blame_entry *head,
|
|
|
|
long start, long end,
|
|
|
|
struct blame_origin *o);
|
2017-05-24 13:15:37 +08:00
|
|
|
|
2019-04-29 16:28:14 +08:00
|
|
|
struct blame_origin *get_blame_suspects(struct commit *commit);
|
2018-05-19 13:28:19 +08:00
|
|
|
|
2017-05-24 13:15:32 +08:00
|
|
|
#endif /* BLAME_H */
|