Commit b2414661332f7fd6a6819395f1505a58f8d75b5e

Edward Thomson 2012-11-28T22:43:55

status should ignore conflicts entries in the index

diff --git a/src/iterator.c b/src/iterator.c
index bd586ce..0fdf0c6 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -340,14 +340,6 @@ static int index_iterator__current(
 	index_iterator *ii = (index_iterator *)self;
 	const git_index_entry *ie = git_index_get_byindex(ii->index, ii->current);
 
-	if (ie != NULL &&
-		ii->base.end != NULL &&
-		ITERATOR_PREFIXCMP(ii->base, ie->path, ii->base.end) > 0)
-	{
-		ii->current = git_index_entrycount(ii->index);
-		ie = NULL;
-	}
-
 	if (entry)
 		*entry = ie;
 
@@ -360,6 +352,29 @@ static int index_iterator__at_end(git_iterator *self)
 	return (ii->current >= git_index_entrycount(ii->index));
 }
 
+static void index_iterator__skip_conflicts(
+	index_iterator *ii)
+{
+	size_t entrycount = git_index_entrycount(ii->index);
+	const git_index_entry *ie;
+
+	while (ii->current < entrycount) {
+		ie = git_index_get_byindex(ii->index, ii->current);
+
+		if (ie == NULL ||
+			(ii->base.end != NULL &&
+			ITERATOR_PREFIXCMP(ii->base, ie->path, ii->base.end) > 0)) {
+			ii->current = entrycount;
+			break;
+		}
+
+		if (git_index_entry_stage(ie) == 0)
+			break;
+
+		ii->current++;
+	}
+}
+
 static int index_iterator__advance(
 	git_iterator *self, const git_index_entry **entry)
 {
@@ -368,6 +383,8 @@ static int index_iterator__advance(
 	if (ii->current < git_index_entrycount(ii->index))
 		ii->current++;
 
+	index_iterator__skip_conflicts(ii);
+
 	return index_iterator__current(self, entry);
 }
 
@@ -382,7 +399,9 @@ static int index_iterator__seek(git_iterator *self, const char *prefix)
 static int index_iterator__reset(git_iterator *self)
 {
 	index_iterator *ii = (index_iterator *)self;
-	ii->current = 0;
+	ii->current = ii->base.start ?
+		git_index__prefix_position(ii->index, ii->base.start) : 0;
+	index_iterator__skip_conflicts(ii);
 	return 0;
 }
 
@@ -406,7 +425,8 @@ int git_iterator_for_index_range(
 
 	ii->index = index;
 	ii->base.ignore_case = ii->index->ignore_case;
-	ii->current = start ? git_index__prefix_position(ii->index, start) : 0;
+
+	index_iterator__reset((git_iterator *)ii);
 
 	*iter = (git_iterator *)ii;
 
diff --git a/tests-clar/status/worktree.c b/tests-clar/status/worktree.c
index 838a043..7ae1883 100644
--- a/tests-clar/status/worktree.c
+++ b/tests-clar/status/worktree.c
@@ -843,3 +843,79 @@ void test_status_worktree__line_endings_dont_count_as_changes_with_autocrlf(void
 
 	cl_assert_equal_i(GIT_STATUS_CURRENT, status);
 }
+
+void test_status_worktree__conflicted_item(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_index *index;
+	unsigned int status;
+	git_index_entry ancestor_entry, our_entry, their_entry;
+
+	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
+	memset(&our_entry, 0x0, sizeof(git_index_entry));
+	memset(&their_entry, 0x0, sizeof(git_index_entry));
+
+	ancestor_entry.path = "modified_file";
+	git_oid_fromstr(&ancestor_entry.oid,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	our_entry.path = "modified_file";
+	git_oid_fromstr(&our_entry.oid,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	their_entry.path = "modified_file";
+	git_oid_fromstr(&their_entry.oid,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	cl_git_pass(git_status_file(&status, repo, "modified_file"));
+	cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status);
+
+	cl_git_pass(git_repository_index(&index, repo));
+	cl_git_pass(git_index_conflict_add(index, &ancestor_entry,
+		&our_entry, &their_entry));
+
+	cl_git_pass(git_status_file(&status, repo, "modified_file"));
+	cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status);
+
+	git_index_free(index);
+}
+
+void test_status_worktree__conflict_with_diff3(void)
+{
+	git_repository *repo = cl_git_sandbox_init("status");
+	git_index *index;
+	unsigned int status;
+	git_index_entry ancestor_entry, our_entry, their_entry;
+
+	memset(&ancestor_entry, 0x0, sizeof(git_index_entry));
+	memset(&our_entry, 0x0, sizeof(git_index_entry));
+	memset(&their_entry, 0x0, sizeof(git_index_entry));
+
+	ancestor_entry.path = "modified_file";
+	git_oid_fromstr(&ancestor_entry.oid,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	our_entry.path = "modified_file";
+	git_oid_fromstr(&our_entry.oid,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	their_entry.path = "modified_file";
+	git_oid_fromstr(&their_entry.oid,
+		"452e4244b5d083ddf0460acf1ecc74db9dcfa11a");
+
+	cl_git_pass(git_status_file(&status, repo, "modified_file"));
+	cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status);
+
+	cl_git_pass(git_repository_index(&index, repo));
+
+	cl_git_pass(git_index_remove(index, "modified_file", 0));
+	cl_git_pass(git_index_conflict_add(index, &ancestor_entry,
+		&our_entry, &their_entry));
+
+	cl_git_pass(git_status_file(&status, repo, "modified_file"));
+
+	cl_assert_equal_i(GIT_STATUS_INDEX_DELETED | GIT_STATUS_WT_NEW, status);
+
+	git_index_free(index);
+}
+