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

Skip to content

Commit efc659b

Browse files
author
Vicent Marti
committed
Merge pull request libgit2#3489 from libgit2/vmg/reuc-insert
Better REUC generation when merging
2 parents 2382d1b + 7a02e93 commit efc659b

File tree

3 files changed

+66
-49
lines changed

3 files changed

+66
-49
lines changed

include/git2/merge.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ typedef enum {
7979
* GIT_EMERGECONFLICT and no index will be returned.
8080
*/
8181
GIT_MERGE_TREE_FAIL_ON_CONFLICT = (1 << 1),
82+
83+
/**
84+
* Do not write the REUC extension on the generated index
85+
*/
86+
GIT_MERGE_TREE_SKIP_REUC = (1 << 2),
8287
} git_merge_tree_flag_t;
8388

8489
/**

src/index.c

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,27 +2000,24 @@ size_t git_index_reuc_entrycount(git_index *index)
20002000
return index->reuc.length;
20012001
}
20022002

2003+
static int index_reuc_on_dup(void **old, void *new)
2004+
{
2005+
index_entry_reuc_free(*old);
2006+
*old = new;
2007+
return GIT_EEXISTS;
2008+
}
2009+
20032010
static int index_reuc_insert(
20042011
git_index *index,
2005-
git_index_reuc_entry *reuc,
2006-
int replace)
2012+
git_index_reuc_entry *reuc)
20072013
{
2008-
git_index_reuc_entry **existing = NULL;
2009-
size_t position;
2014+
int res;
20102015

20112016
assert(index && reuc && reuc->path != NULL);
2017+
assert(git_vector_is_sorted(&index->reuc));
20122018

2013-
if (!git_index_reuc_find(&position, index, reuc->path))
2014-
existing = (git_index_reuc_entry **)&index->reuc.contents[position];
2015-
2016-
if (!replace || !existing)
2017-
return git_vector_insert(&index->reuc, reuc);
2018-
2019-
/* exists, replace it */
2020-
git__free(*existing);
2021-
*existing = reuc;
2022-
2023-
return 0;
2019+
res = git_vector_insert_sorted(&index->reuc, reuc, &index_reuc_on_dup);
2020+
return res == GIT_EEXISTS ? 0 : res;
20242021
}
20252022

20262023
int git_index_reuc_add(git_index *index, const char *path,
@@ -2035,7 +2032,7 @@ int git_index_reuc_add(git_index *index, const char *path,
20352032

20362033
if ((error = index_entry_reuc_init(&reuc, path, ancestor_mode,
20372034
ancestor_oid, our_mode, our_oid, their_mode, their_oid)) < 0 ||
2038-
(error = index_reuc_insert(index, reuc, 1)) < 0)
2035+
(error = index_reuc_insert(index, reuc)) < 0)
20392036
index_entry_reuc_free(reuc);
20402037

20412038
return error;
@@ -2055,7 +2052,7 @@ const git_index_reuc_entry *git_index_reuc_get_bypath(
20552052
if (!index->reuc.length)
20562053
return NULL;
20572054

2058-
git_vector_sort(&index->reuc);
2055+
assert(git_vector_is_sorted(&index->reuc));
20592056

20602057
if (git_index_reuc_find(&pos, index, path) < 0)
20612058
return NULL;
@@ -2067,8 +2064,8 @@ const git_index_reuc_entry *git_index_reuc_get_byindex(
20672064
git_index *index, size_t n)
20682065
{
20692066
assert(index);
2067+
assert(git_vector_is_sorted(&index->reuc));
20702068

2071-
git_vector_sort(&index->reuc);
20722069
return git_vector_get(&index->reuc, n);
20732070
}
20742071

@@ -2077,7 +2074,7 @@ int git_index_reuc_remove(git_index *index, size_t position)
20772074
int error;
20782075
git_index_reuc_entry *reuc;
20792076

2080-
git_vector_sort(&index->reuc);
2077+
assert(git_vector_is_sorted(&index->reuc));
20812078

20822079
reuc = git_vector_get(&index->reuc, position);
20832080
error = git_vector_remove(&index->reuc, position);

src/merge.c

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1541,7 +1541,45 @@ static int merge_index_insert_reuc(
15411541
mode[0], oid[0], mode[1], oid[1], mode[2], oid[2]);
15421542
}
15431543

1544-
int index_from_diff_list(git_index **out, git_merge_diff_list *diff_list)
1544+
static int index_update_reuc(git_index *index, git_merge_diff_list *diff_list)
1545+
{
1546+
int error;
1547+
size_t i;
1548+
git_merge_diff *conflict;
1549+
1550+
/* Add each entry in the resolved conflict to the REUC independently, since
1551+
* the paths may differ due to renames. */
1552+
git_vector_foreach(&diff_list->resolved, i, conflict) {
1553+
const git_index_entry *ancestor =
1554+
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
1555+
&conflict->ancestor_entry : NULL;
1556+
1557+
const git_index_entry *ours =
1558+
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
1559+
&conflict->our_entry : NULL;
1560+
1561+
const git_index_entry *theirs =
1562+
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
1563+
&conflict->their_entry : NULL;
1564+
1565+
if (ancestor != NULL &&
1566+
(error = merge_index_insert_reuc(index, TREE_IDX_ANCESTOR, ancestor)) < 0)
1567+
return error;
1568+
1569+
if (ours != NULL &&
1570+
(error = merge_index_insert_reuc(index, TREE_IDX_OURS, ours)) < 0)
1571+
return error;
1572+
1573+
if (theirs != NULL &&
1574+
(error = merge_index_insert_reuc(index, TREE_IDX_THEIRS, theirs)) < 0)
1575+
return error;
1576+
}
1577+
1578+
return 0;
1579+
}
1580+
1581+
static int index_from_diff_list(git_index **out,
1582+
git_merge_diff_list *diff_list, bool skip_reuc)
15451583
{
15461584
git_index *index;
15471585
size_t i;
@@ -1600,31 +1638,8 @@ int index_from_diff_list(git_index **out, git_merge_diff_list *diff_list)
16001638
}
16011639
}
16021640

1603-
/* Add each entry in the resolved conflict to the REUC independently, since
1604-
* the paths may differ due to renames. */
1605-
git_vector_foreach(&diff_list->resolved, i, conflict) {
1606-
const git_index_entry *ancestor =
1607-
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
1608-
&conflict->ancestor_entry : NULL;
1609-
1610-
const git_index_entry *ours =
1611-
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
1612-
&conflict->our_entry : NULL;
1613-
1614-
const git_index_entry *theirs =
1615-
GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
1616-
&conflict->their_entry : NULL;
1617-
1618-
if (ancestor != NULL &&
1619-
(error = merge_index_insert_reuc(index, TREE_IDX_ANCESTOR, ancestor)) < 0)
1620-
goto on_error;
1621-
1622-
if (ours != NULL &&
1623-
(error = merge_index_insert_reuc(index, TREE_IDX_OURS, ours)) < 0)
1624-
goto on_error;
1625-
1626-
if (theirs != NULL &&
1627-
(error = merge_index_insert_reuc(index, TREE_IDX_THEIRS, theirs)) < 0)
1641+
if (!skip_reuc) {
1642+
if ((error = index_update_reuc(index, diff_list)) < 0)
16281643
goto on_error;
16291644
}
16301645

@@ -1633,7 +1648,6 @@ int index_from_diff_list(git_index **out, git_merge_diff_list *diff_list)
16331648

16341649
on_error:
16351650
git_index_free(index);
1636-
16371651
return error;
16381652
}
16391653

@@ -1712,12 +1726,13 @@ int git_merge__iterators(
17121726
}
17131727
}
17141728

1729+
error = index_from_diff_list(out, diff_list,
1730+
(opts.tree_flags & GIT_MERGE_TREE_SKIP_REUC));
1731+
1732+
done:
17151733
if (!given_opts || !given_opts->metric)
17161734
git__free(opts.metric);
17171735

1718-
error = index_from_diff_list(out, diff_list);
1719-
1720-
done:
17211736
git_merge_diff_list__free(diff_list);
17221737
git_iterator_free(empty_ancestor);
17231738
git_iterator_free(empty_ours);

0 commit comments

Comments
 (0)