Merge branch 'jc/blame-reverse'
It is a common mistake to say "git blame --reverse OLD path", expecting that the command line is dwimmed as if asking how lines in path in an old revision OLD have survived up to the current commit. * jc/blame-reverse: blame: dwim "blame --reverse OLD" as "blame --reverse OLD.." blame: improve diagnosis for "--reverse NEW"
This commit is contained in:
commit
1172e16af0
@ -28,12 +28,13 @@ include::line-range-format.txt[]
|
|||||||
-S <revs-file>::
|
-S <revs-file>::
|
||||||
Use revisions from revs-file instead of calling linkgit:git-rev-list[1].
|
Use revisions from revs-file instead of calling linkgit:git-rev-list[1].
|
||||||
|
|
||||||
--reverse::
|
--reverse <rev>..<rev>::
|
||||||
Walk history forward instead of backward. Instead of showing
|
Walk history forward instead of backward. Instead of showing
|
||||||
the revision in which a line appeared, this shows the last
|
the revision in which a line appeared, this shows the last
|
||||||
revision in which a line has existed. This requires a range of
|
revision in which a line has existed. This requires a range of
|
||||||
revision like START..END where the path to blame exists in
|
revision like START..END where the path to blame exists in
|
||||||
START.
|
START. `git blame --reverse START` is taken as `git blame
|
||||||
|
--reverse START..HEAD` for convenience.
|
||||||
|
|
||||||
-p::
|
-p::
|
||||||
--porcelain::
|
--porcelain::
|
||||||
|
@ -10,7 +10,7 @@ SYNOPSIS
|
|||||||
[verse]
|
[verse]
|
||||||
'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental]
|
'git blame' [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-e] [-p] [-w] [--incremental]
|
||||||
[-L <range>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]
|
[-L <range>] [-S <revs-file>] [-M] [-C] [-C] [-C] [--since=<date>]
|
||||||
[--progress] [--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>]
|
[--progress] [--abbrev=<n>] [<rev> | --contents <file> | --reverse <rev>..<rev>]
|
||||||
[--] <file>
|
[--] <file>
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
@ -2456,6 +2456,41 @@ static char *prepare_final(struct scoreboard *sb)
|
|||||||
return xstrdup_or_null(name);
|
return xstrdup_or_null(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *dwim_reverse_initial(struct scoreboard *sb)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* DWIM "git blame --reverse ONE -- PATH" as
|
||||||
|
* "git blame --reverse ONE..HEAD -- PATH" but only do so
|
||||||
|
* when it makes sense.
|
||||||
|
*/
|
||||||
|
struct object *obj;
|
||||||
|
struct commit *head_commit;
|
||||||
|
unsigned char head_sha1[20];
|
||||||
|
|
||||||
|
if (sb->revs->pending.nr != 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Is that sole rev a committish? */
|
||||||
|
obj = sb->revs->pending.objects[0].item;
|
||||||
|
obj = deref_tag(obj, NULL, 0);
|
||||||
|
if (obj->type != OBJ_COMMIT)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Do we have HEAD? */
|
||||||
|
if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_sha1, NULL))
|
||||||
|
return NULL;
|
||||||
|
head_commit = lookup_commit_reference_gently(head_sha1, 1);
|
||||||
|
if (!head_commit)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Turn "ONE" into "ONE..HEAD" then */
|
||||||
|
obj->flags |= UNINTERESTING;
|
||||||
|
add_pending_object(sb->revs, &head_commit->object, "HEAD");
|
||||||
|
|
||||||
|
sb->final = (struct commit *)obj;
|
||||||
|
return sb->revs->pending.objects[0].name;
|
||||||
|
}
|
||||||
|
|
||||||
static char *prepare_initial(struct scoreboard *sb)
|
static char *prepare_initial(struct scoreboard *sb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -2474,14 +2509,17 @@ static char *prepare_initial(struct scoreboard *sb)
|
|||||||
if (obj->type != OBJ_COMMIT)
|
if (obj->type != OBJ_COMMIT)
|
||||||
die("Non commit %s?", revs->pending.objects[i].name);
|
die("Non commit %s?", revs->pending.objects[i].name);
|
||||||
if (sb->final)
|
if (sb->final)
|
||||||
die("More than one commit to dig down to %s and %s?",
|
die("More than one commit to dig up from, %s and %s?",
|
||||||
revs->pending.objects[i].name,
|
revs->pending.objects[i].name,
|
||||||
final_commit_name);
|
final_commit_name);
|
||||||
sb->final = (struct commit *) obj;
|
sb->final = (struct commit *) obj;
|
||||||
final_commit_name = revs->pending.objects[i].name;
|
final_commit_name = revs->pending.objects[i].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!final_commit_name)
|
if (!final_commit_name)
|
||||||
die("No commit to dig down to?");
|
final_commit_name = dwim_reverse_initial(sb);
|
||||||
|
if (!final_commit_name)
|
||||||
|
die("No commit to dig up from?");
|
||||||
return xstrdup(final_commit_name);
|
return xstrdup(final_commit_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user