summaryrefslogtreecommitdiff
path: root/builtin-blame.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2009-06-03 07:43:22 (GMT)
committerJunio C Hamano <gitster@pobox.com>2009-06-03 07:49:34 (GMT)
commita9b2d42486ee0b461220bf3895114926d9ddf9be (patch)
tree2095415de94a148adfbc4ef960b8ac85e02660f8 /builtin-blame.c
parent8dc3a47c3edcee923225000e93f8052c50e5a004 (diff)
downloadgit-a9b2d42486ee0b461220bf3895114926d9ddf9be.zip
git-a9b2d42486ee0b461220bf3895114926d9ddf9be.tar.gz
git-a9b2d42486ee0b461220bf3895114926d9ddf9be.tar.bz2
blame: correctly handle a path that used to be a directory
When trying to see if the same path exists in the parent, we ran "diff-tree" with pathspec set to the path we are interested in with the parent, and expect either to have exactly one resulting filepair (either "changed from the parent", "created when there was none") or nothing (when there is no change from the parent). If the path used to be a directory, however, we will also see unbounded number of entries that talk about the files that used to exist underneath the directory in question. Correctly pick only the entry that describes the path we are interested in in such a case (namely, the creation of the path as a regular file). Noticed by Ben Willard. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-blame.c')
-rw-r--r--builtin-blame.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/builtin-blame.c b/builtin-blame.c
index cf74a92..0afdb16 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -362,18 +362,28 @@ static struct origin *find_origin(struct scoreboard *sb,
"", &diff_opts);
diffcore_std(&diff_opts);
- /* It is either one entry that says "modified", or "created",
- * or nothing.
- */
if (!diff_queued_diff.nr) {
/* The path is the same as parent */
porigin = get_origin(sb, parent, origin->path);
hashcpy(porigin->blob_sha1, origin->blob_sha1);
- }
- else if (diff_queued_diff.nr != 1)
- die("internal error in blame::find_origin");
- else {
- struct diff_filepair *p = diff_queued_diff.queue[0];
+ } else {
+ /*
+ * Since origin->path is a pathspec, if the parent
+ * commit had it as a directory, we will see a whole
+ * bunch of deletion of files in the directory that we
+ * do not care about.
+ */
+ int i;
+ struct diff_filepair *p = NULL;
+ for (i = 0; i < diff_queued_diff.nr; i++) {
+ const char *name;
+ p = diff_queued_diff.queue[i];
+ name = p->one->path ? p->one->path : p->two->path;
+ if (!strcmp(name, origin->path))
+ break;
+ }
+ if (!p)
+ die("internal error in blame::find_origin");
switch (p->status) {
default:
die("internal error in blame::find_origin (%c)",