Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 879ebab

Browse files
committed
merge: Use git_index__fill to populate the index
Instead of calling `git_index_add` in a loop, use the new `git_index_fill` internal API to fill the index with the initial staged entries. The new `fill` helper assumes that all the entries will be unique and valid, so it can append them at the end of the entries vector and only sort it once at the end. It performs no validation checks. This prevents the quadratic behavior caused by having to sort the entries list once after every insertion.
1 parent 7f2c146 commit 879ebab

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

src/index.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,6 +1542,43 @@ int git_index_remove_bypath(git_index *index, const char *path)
15421542
return 0;
15431543
}
15441544

1545+
int git_index__fill(git_index *index, const git_vector *source_entries)
1546+
{
1547+
const git_index_entry *source_entry = NULL;
1548+
size_t i;
1549+
int ret = 0;
1550+
1551+
assert(index);
1552+
1553+
if (git_mutex_lock(&index->lock) < 0) {
1554+
giterr_set(GITERR_OS, "Unable to acquire index lock");
1555+
return -1;
1556+
}
1557+
1558+
git_vector_foreach(source_entries, i, source_entry) {
1559+
git_index_entry *entry = NULL;
1560+
1561+
if ((ret = index_entry_dup(&entry, index, source_entry)) < 0)
1562+
break;
1563+
1564+
entry->flags_extended |= GIT_IDXENTRY_UPTODATE;
1565+
1566+
ret = git_vector_insert(&index->entries, entry);
1567+
if (ret < 0)
1568+
break;
1569+
1570+
INSERT_IN_MAP(index, entry, ret);
1571+
if (ret < 0)
1572+
break;
1573+
}
1574+
1575+
if (!ret)
1576+
git_vector_sort(&index->entries);
1577+
1578+
git_mutex_unlock(&index->lock);
1579+
return ret;
1580+
}
1581+
15451582

15461583
int git_index_add(git_index *index, const git_index_entry *source_entry)
15471584
{

src/index.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ GIT_INLINE(bool) git_index_entry_newer_than_index(
113113
extern int git_index__find_pos(
114114
size_t *at_pos, git_index *index, const char *path, size_t path_len, int stage);
115115

116+
extern int git_index__fill(git_index *index, const git_vector *source_entries);
117+
116118
extern void git_index__set_ignore_case(git_index *index, bool ignore_case);
117119

118120
extern unsigned int git_index__create_mode(unsigned int mode);

src/merge.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,7 +1739,6 @@ static int index_from_diff_list(git_index **out,
17391739
{
17401740
git_index *index;
17411741
size_t i;
1742-
git_index_entry *entry;
17431742
git_merge_diff *conflict;
17441743
int error = 0;
17451744

@@ -1748,10 +1747,8 @@ static int index_from_diff_list(git_index **out,
17481747
if ((error = git_index_new(&index)) < 0)
17491748
return error;
17501749

1751-
git_vector_foreach(&diff_list->staged, i, entry) {
1752-
if ((error = git_index_add(index, entry)) < 0)
1753-
goto on_error;
1754-
}
1750+
if ((error = git_index__fill(index, &diff_list->staged)) < 0)
1751+
goto on_error;
17551752

17561753
git_vector_foreach(&diff_list->conflicts, i, conflict) {
17571754
const git_index_entry *ancestor =

0 commit comments

Comments
 (0)