Merge pull request #1111 from ethomson/conflictstatus status should ignore conflicts entries in the index
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
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);
+}
+