Commit 6481e06258608f46c2c45e74a8f9cf8c42347004

Vicent Martí 2013-11-13T01:41:09

Merge pull request #1958 from libgit2/blame-fixes Blame fixes

diff --git a/src/blame.c b/src/blame.c
index 01d3fc0..219a6bf 100644
--- a/src/blame.c
+++ b/src/blame.c
@@ -75,6 +75,9 @@ static git_blame_hunk* dup_hunk(git_blame_hunk *hunk)
 			hunk->orig_path);
 	git_oid_cpy(&newhunk->orig_commit_id, &hunk->orig_commit_id);
 	git_oid_cpy(&newhunk->final_commit_id, &hunk->final_commit_id);
+	newhunk->boundary = hunk->boundary;
+	newhunk->final_signature = git_signature_dup(hunk->final_signature);
+	newhunk->orig_signature = git_signature_dup(hunk->orig_signature);
 	return newhunk;
 }
 
@@ -381,9 +384,13 @@ static int buffer_hunk_cb(
 	wedge_line = (hunk->old_lines == 0) ? hunk->new_start : hunk->old_start;
 	blame->current_diff_line = wedge_line;
 
-	/* If this hunk doesn't start between existing hunks, split a hunk up so it does */
 	blame->current_hunk = (git_blame_hunk*)git_blame_get_hunk_byline(blame, wedge_line);
-	if (!hunk_starts_at_or_after_line(blame->current_hunk, wedge_line)){
+	if (!blame->current_hunk) {
+		/* Line added at the end of the file */
+		blame->current_hunk = new_hunk(wedge_line, 0, wedge_line, blame->path);
+		git_vector_insert(&blame->hunks, blame->current_hunk);
+	} else if (!hunk_starts_at_or_after_line(blame->current_hunk, wedge_line)){
+		/* If this hunk doesn't start between existing hunks, split a hunk up so it does */
 		blame->current_hunk = split_hunk_in_vector(&blame->hunks, blame->current_hunk,
 				wedge_line - blame->current_hunk->orig_start_line_number, true);
 	}
@@ -404,13 +411,6 @@ static int buffer_line_cb(
 	GIT_UNUSED(hunk);
 	GIT_UNUSED(line);
 
-#ifdef DO_DEBUG
-	{
-		char *str = git__substrdup(content, content_len);
-		git__free(str);
-	}
-#endif
-
 	if (line->origin == GIT_DIFF_LINE_ADDITION) {
 		if (hunk_is_bufferblame(blame->current_hunk) &&
 		    hunk_ends_at_or_before_line(blame->current_hunk, blame->current_diff_line)) {
diff --git a/src/signature.c b/src/signature.c
index 52ca2b3..ec51a42 100644
--- a/src/signature.c
+++ b/src/signature.c
@@ -84,8 +84,12 @@ int git_signature_new(git_signature **sig_out, const char *name, const char *ema
 
 git_signature *git_signature_dup(const git_signature *sig)
 {
-	git_signature *new = git__calloc(1, sizeof(git_signature));
+	git_signature *new;
 
+	if (sig == NULL)
+		return NULL;
+
+	new = git__calloc(1, sizeof(git_signature));
 	if (new == NULL)
 		return NULL;
 
diff --git a/tests-clar/blame/buffer.c b/tests-clar/blame/buffer.c
index 69b2d54..912ee98 100644
--- a/tests-clar/blame/buffer.c
+++ b/tests-clar/blame/buffer.c
@@ -19,6 +19,8 @@ void test_blame_buffer__cleanup(void)
 
 void test_blame_buffer__added_line(void)
 {
+	const git_blame_hunk *hunk;
+
 	const char *buffer = "\
 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
 EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
@@ -39,6 +41,10 @@ CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
 	cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
 	cl_assert_equal_i(5, git_blame_get_hunk_count(g_bufferblame));
 	check_blame_hunk_index(g_repo, g_bufferblame, 2, 6, 1, 0, "000000", "b.txt");
+
+	hunk = git_blame_get_hunk_byline(g_bufferblame, 16);
+	cl_assert(hunk);
+	cl_assert_equal_s("Ben Straub", hunk->final_signature->name);
 }
 
 void test_blame_buffer__deleted_line(void)
@@ -128,3 +134,33 @@ CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
 	check_blame_hunk_index(g_repo, g_bufferblame, 3, 7, 1, 0, "00000000", "b.txt");
 	check_blame_hunk_index(g_repo, g_bufferblame, 4, 8, 3, 0, "63d671eb", "b.txt");
 }
+
+void test_blame_buffer__add_lines_at_end(void)
+{
+	const char *buffer = "\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n\
+\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\n\
+\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\n\
+\n\
+abc\n\
+def\n";
+	cl_git_pass(git_blame_buffer(&g_bufferblame, g_fileblame, buffer, strlen(buffer)));
+
+	cl_assert_equal_i(5, git_blame_get_hunk_count(g_bufferblame));
+	check_blame_hunk_index(g_repo, g_bufferblame, 0,  1, 4, 0, "da237394", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 1,  5, 1, 1, "b99f7ac0", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 2,  6, 5, 0, "63d671eb", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 3, 11, 5, 0, "aa06ecca", "b.txt");
+	check_blame_hunk_index(g_repo, g_bufferblame, 4, 16, 2, 0, "00000000", "b.txt");
+}