summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard R. Link <brlink@debian.org>2014-01-13 07:30:25 +0100
committerJunio C Hamano <gitster@pobox.com>2014-01-14 11:49:26 -0800
commit0b4e246ba94de0ffae9fddfe89e8e47b265c36c8 (patch)
treeaeaf3c6113e8ab51ab78e080e86cf09f4a897e58
parent14598b907008dc9952428662a30ecfd74dc90a79 (diff)
downloadgit-bl/blame-full-history.tar.gz
blame: new option --prefer-first to better handle merged cherry-picksbl/blame-full-history
Allows to disable the git blame optimization of assuming that if there is a parent of a merge commit that has the exactly same file content, then only this parent is to be looked at. This optimization, while being faster in the usual case, means that in the case of cherry-picks the blamed commit depends on which other commits touched a file. If for example one commit A modified both files b and c. And there are commits B and C, B only modifies file b and C only modifies file c (so that no conflicts happen), and assume A is cherry-picked as A' and the two branches then merged: --o-----B---A \ \ ---C---A'--M--- Then without this new option git blame blames the A|A' changes of file b to A while blaming the changes of c to A'. With the new option --prefer-first it blames both changes to the same commit and to the one more on the "left" side of the graph. Signed-off-by: Bernhard R. Link <brlink@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Documentation/blame-options.txt6
-rw-r--r--builtin/blame.c7
2 files changed, 11 insertions, 2 deletions
diff --git a/Documentation/blame-options.txt b/Documentation/blame-options.txt
index 0cebc4f692..b2e7fb8951 100644
--- a/Documentation/blame-options.txt
+++ b/Documentation/blame-options.txt
@@ -48,6 +48,12 @@ include::line-range-format.txt[]
Show the result incrementally in a format designed for
machine consumption.
+--prefer-first::
+ If a line was introduced by two commits (for example via
+ a merged cherry-pick), prefer the commit that was
+ first merged in the history of always following the
+ first parent.
+
--encoding=<encoding>::
Specifies the encoding used to output author names
and commit summaries. Setting it to `none` makes blame
diff --git a/builtin/blame.c b/builtin/blame.c
index e44a6bb30a..2520241cca 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -45,6 +45,7 @@ static int incremental;
static int xdl_opts;
static int abbrev = -1;
static int no_whole_file_rename;
+static int prefer_first;
static enum date_mode blame_date_mode = DATE_ISO8601;
static size_t blame_date_width;
@@ -1248,7 +1249,8 @@ static void pass_blame(struct scoreboard *sb, struct origin *origin, int opt)
porigin = find(sb, p, origin);
if (!porigin)
continue;
- if (!hashcmp(porigin->blob_sha1, origin->blob_sha1)) {
+ if (!prefer_first &&
+ !hashcmp(porigin->blob_sha1, origin->blob_sha1)) {
pass_whole_blame(sb, origin, porigin);
origin_decref(porigin);
goto finish;
@@ -2247,7 +2249,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
static const char *contents_from = NULL;
static const struct option options[] = {
OPT_BOOL(0, "incremental", &incremental, N_("Show blame entries as we find them, incrementally")),
- OPT_BOOL('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: off)")),
+ OPT_BOOL(0, "prefer-first", &prefer_first, N_("Prefer blaming commits merged earlier")),
+ OPT_BOOL('b', NULL, &blank_boundary, N_("Show blank SHA-1 for boundary commits (Default: ff)")),
OPT_BOOL(0, "root", &show_root, N_("Do not treat root commits as boundaries (Default: off)")),
OPT_BOOL(0, "show-stats", &show_stats, N_("Show work cost statistics")),
OPT_BIT(0, "score-debug", &output_option, N_("Show output score for blame entries"), OUTPUT_SHOW_SCORE),