rugged 0.23.0b2 → 0.23.0b4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/rugged/rugged_blob.c +39 -0
- data/ext/rugged/rugged_diff.c +7 -3
- data/ext/rugged/rugged_index.c +2 -2
- data/ext/rugged/rugged_remote.c +27 -148
- data/ext/rugged/rugged_remote_collection.c +134 -12
- data/ext/rugged/rugged_repo.c +74 -5
- data/ext/rugged/rugged_submodule.c +18 -208
- data/ext/rugged/rugged_submodule_collection.c +148 -0
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/AUTHORS +1 -0
- data/vendor/libgit2/CMakeLists.txt +33 -25
- data/vendor/libgit2/deps/winhttp/winhttp.def +29 -29
- data/vendor/libgit2/include/git2.h +1 -1
- data/vendor/libgit2/include/git2/blob.h +4 -6
- data/vendor/libgit2/include/git2/checkout.h +10 -1
- data/vendor/libgit2/include/git2/clone.h +6 -7
- data/vendor/libgit2/include/git2/commit.h +11 -0
- data/vendor/libgit2/include/git2/cred_helpers.h +2 -2
- data/vendor/libgit2/include/git2/describe.h +1 -1
- data/vendor/libgit2/include/git2/diff.h +68 -11
- data/vendor/libgit2/include/git2/errors.h +4 -1
- data/vendor/libgit2/include/git2/filter.h +16 -0
- data/vendor/libgit2/include/git2/index.h +38 -11
- data/vendor/libgit2/include/git2/odb.h +1 -1
- data/vendor/libgit2/include/git2/odb_backend.h +2 -2
- data/vendor/libgit2/include/git2/remote.h +300 -207
- data/vendor/libgit2/include/git2/reset.h +1 -0
- data/vendor/libgit2/include/git2/stash.h +135 -4
- data/vendor/libgit2/include/git2/status.h +1 -0
- data/vendor/libgit2/include/git2/submodule.h +46 -75
- data/vendor/libgit2/include/git2/sys/odb_backend.h +1 -1
- data/vendor/libgit2/include/git2/sys/stream.h +2 -0
- data/vendor/libgit2/include/git2/sys/transport.h +1 -21
- data/vendor/libgit2/include/git2/transport.h +27 -0
- data/vendor/libgit2/include/git2/types.h +20 -10
- data/vendor/libgit2/include/git2/version.h +3 -3
- data/vendor/libgit2/libgit2.pc.in +4 -2
- data/vendor/libgit2/src/attr.c +2 -1
- data/vendor/libgit2/src/attr_file.c +18 -37
- data/vendor/libgit2/src/blame.c +2 -2
- data/vendor/libgit2/src/blob.c +4 -3
- data/vendor/libgit2/src/branch.c +6 -3
- data/vendor/libgit2/src/buf_text.c +4 -6
- data/vendor/libgit2/src/buf_text.h +1 -2
- data/vendor/libgit2/src/buffer.c +8 -6
- data/vendor/libgit2/src/buffer.h +1 -1
- data/vendor/libgit2/src/cache.c +1 -0
- data/vendor/libgit2/src/checkout.c +34 -20
- data/vendor/libgit2/src/clone.c +29 -29
- data/vendor/libgit2/src/commit.c +65 -0
- data/vendor/libgit2/src/common.h +5 -0
- data/vendor/libgit2/src/config.c +20 -0
- data/vendor/libgit2/src/config.h +6 -0
- data/vendor/libgit2/src/config_file.c +2 -2
- data/vendor/libgit2/src/crlf.c +39 -17
- data/vendor/libgit2/src/curl_stream.c +257 -0
- data/vendor/libgit2/src/curl_stream.h +14 -0
- data/vendor/libgit2/src/diff.c +223 -88
- data/vendor/libgit2/src/diff.h +21 -1
- data/vendor/libgit2/src/diff_file.c +23 -13
- data/vendor/libgit2/src/diff_file.h +4 -2
- data/vendor/libgit2/src/diff_patch.c +266 -71
- data/vendor/libgit2/src/diff_patch.h +36 -0
- data/vendor/libgit2/src/diff_print.c +156 -126
- data/vendor/libgit2/src/diff_tform.c +32 -54
- data/vendor/libgit2/src/fetch.c +27 -10
- data/vendor/libgit2/src/fetch.h +2 -2
- data/vendor/libgit2/src/filebuf.c +1 -1
- data/vendor/libgit2/src/fileops.c +6 -2
- data/vendor/libgit2/src/filter.c +28 -7
- data/vendor/libgit2/src/fnmatch.c +5 -5
- data/vendor/libgit2/src/global.c +16 -0
- data/vendor/libgit2/src/ident.c +2 -2
- data/vendor/libgit2/src/ignore.c +1 -0
- data/vendor/libgit2/src/index.c +338 -80
- data/vendor/libgit2/src/index.h +4 -1
- data/vendor/libgit2/src/indexer.c +19 -5
- data/vendor/libgit2/src/iterator.c +118 -11
- data/vendor/libgit2/src/iterator.h +25 -0
- data/vendor/libgit2/src/merge.c +96 -106
- data/vendor/libgit2/src/merge.h +14 -4
- data/vendor/libgit2/src/netops.c +3 -3
- data/vendor/libgit2/src/odb.c +17 -9
- data/vendor/libgit2/src/odb.h +1 -1
- data/vendor/libgit2/src/odb_loose.c +2 -2
- data/vendor/libgit2/src/odb_pack.c +1 -1
- data/vendor/libgit2/src/openssl_stream.c +118 -27
- data/vendor/libgit2/src/pack-objects.c +28 -0
- data/vendor/libgit2/src/pack-objects.h +1 -0
- data/vendor/libgit2/src/pack.c +18 -10
- data/vendor/libgit2/src/path.c +16 -11
- data/vendor/libgit2/src/path.h +1 -1
- data/vendor/libgit2/src/push.c +26 -42
- data/vendor/libgit2/src/push.h +2 -34
- data/vendor/libgit2/src/rebase.c +1 -1
- data/vendor/libgit2/src/refs.c +1 -1
- data/vendor/libgit2/src/refspec.c +6 -0
- data/vendor/libgit2/src/remote.c +381 -274
- data/vendor/libgit2/src/remote.h +0 -4
- data/vendor/libgit2/src/repository.c +33 -12
- data/vendor/libgit2/src/repository.h +0 -1
- data/vendor/libgit2/src/reset.c +1 -0
- data/vendor/libgit2/src/stash.c +439 -17
- data/vendor/libgit2/src/status.c +6 -0
- data/vendor/libgit2/src/stransport_stream.c +58 -21
- data/vendor/libgit2/src/stream.h +15 -0
- data/vendor/libgit2/src/submodule.c +410 -664
- data/vendor/libgit2/src/submodule.h +0 -24
- data/vendor/libgit2/src/transaction.c +1 -0
- data/vendor/libgit2/src/transports/cred.c +55 -1
- data/vendor/libgit2/src/transports/http.c +18 -2
- data/vendor/libgit2/src/transports/local.c +60 -59
- data/vendor/libgit2/src/transports/smart.h +1 -1
- data/vendor/libgit2/src/transports/smart_protocol.c +11 -11
- data/vendor/libgit2/src/transports/ssh.c +46 -7
- data/vendor/libgit2/src/unix/posix.h +4 -0
- data/vendor/libgit2/src/util.c +9 -9
- data/vendor/libgit2/src/util.h +9 -0
- data/vendor/libgit2/src/win32/posix.h +3 -0
- data/vendor/libgit2/src/win32/posix_w32.c +38 -0
- data/vendor/libgit2/src/win32/w32_util.h +10 -0
- metadata +4 -3
- data/vendor/libgit2/include/git2/push.h +0 -94
data/vendor/libgit2/src/index.h
CHANGED
@@ -22,6 +22,7 @@ struct git_index {
|
|
22
22
|
|
23
23
|
char *index_file_path;
|
24
24
|
git_futils_filestamp stamp;
|
25
|
+
git_oid checksum; /* checksum at the end of the file */
|
25
26
|
|
26
27
|
git_vector entries;
|
27
28
|
|
@@ -80,7 +81,7 @@ GIT_INLINE(const git_futils_filestamp *) git_index__filestamp(git_index *index)
|
|
80
81
|
return &index->stamp;
|
81
82
|
}
|
82
83
|
|
83
|
-
extern int git_index__changed_relative_to(git_index *index, const
|
84
|
+
extern int git_index__changed_relative_to(git_index *index, const git_oid *checksum);
|
84
85
|
|
85
86
|
/* Copy the current entries vector *and* increment the index refcount.
|
86
87
|
* Call `git_index__release_snapshot` when done.
|
@@ -93,6 +94,8 @@ extern int git_index_snapshot_find(
|
|
93
94
|
size_t *at_pos, git_vector *snap, git_vector_cmp entry_srch,
|
94
95
|
const char *path, size_t path_len, int stage);
|
95
96
|
|
97
|
+
/* Replace an index with a new index */
|
98
|
+
int git_index_read_index(git_index *index, const git_index *new_index);
|
96
99
|
|
97
100
|
typedef struct {
|
98
101
|
git_index *index;
|
@@ -325,6 +325,13 @@ on_error:
|
|
325
325
|
return -1;
|
326
326
|
}
|
327
327
|
|
328
|
+
GIT_INLINE(bool) has_entry(git_indexer *idx, git_oid *id)
|
329
|
+
{
|
330
|
+
khiter_t k;
|
331
|
+
k = kh_get(oid, idx->pack->idx_cache, id);
|
332
|
+
return (k != kh_end(idx->pack->idx_cache));
|
333
|
+
}
|
334
|
+
|
328
335
|
static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_entry *pentry, git_off_t entry_start)
|
329
336
|
{
|
330
337
|
int i, error;
|
@@ -339,8 +346,11 @@ static int save_entry(git_indexer *idx, struct entry *entry, struct git_pack_ent
|
|
339
346
|
|
340
347
|
pentry->offset = entry_start;
|
341
348
|
k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error);
|
342
|
-
|
349
|
+
|
350
|
+
if (error <= 0) {
|
351
|
+
giterr_set(GITERR_INDEXER, "cannot insert object into pack");
|
343
352
|
return -1;
|
353
|
+
}
|
344
354
|
|
345
355
|
kh_value(idx->pack->idx_cache, k) = pentry;
|
346
356
|
|
@@ -468,13 +478,14 @@ static int write_at(git_indexer *idx, const void *data, git_off_t offset, size_t
|
|
468
478
|
static int append_to_pack(git_indexer *idx, const void *data, size_t size)
|
469
479
|
{
|
470
480
|
git_off_t current_size = idx->pack->mwf.size;
|
481
|
+
int fd = idx->pack->mwf.fd;
|
471
482
|
|
472
483
|
if (!size)
|
473
484
|
return 0;
|
474
485
|
|
475
|
-
|
476
|
-
|
477
|
-
giterr_set(GITERR_OS, "
|
486
|
+
if (p_lseek(fd, current_size + size - 1, SEEK_SET) < 0 ||
|
487
|
+
p_write(idx->pack->mwf.fd, data, 1) < 0) {
|
488
|
+
giterr_set(GITERR_OS, "cannot extend packfile '%s'", idx->pack->pack_name);
|
478
489
|
return -1;
|
479
490
|
}
|
480
491
|
|
@@ -791,6 +802,9 @@ static int fix_thin_pack(git_indexer *idx, git_transfer_progress *stats)
|
|
791
802
|
git_oid_fromraw(&base, base_info);
|
792
803
|
git_mwindow_close(&w);
|
793
804
|
|
805
|
+
if (has_entry(idx, &base))
|
806
|
+
return 0;
|
807
|
+
|
794
808
|
if (inject_object(idx, &base) < 0)
|
795
809
|
return -1;
|
796
810
|
|
@@ -809,7 +823,7 @@ static int resolve_deltas(git_indexer *idx, git_transfer_progress *stats)
|
|
809
823
|
progressed = 0;
|
810
824
|
non_null = 0;
|
811
825
|
git_vector_foreach(&idx->deltas, i, delta) {
|
812
|
-
git_rawobj obj;
|
826
|
+
git_rawobj obj = {NULL};
|
813
827
|
|
814
828
|
if (!delta)
|
815
829
|
continue;
|
@@ -46,6 +46,7 @@
|
|
46
46
|
#define iterator__include_trees(I) iterator__flag(I,INCLUDE_TREES)
|
47
47
|
#define iterator__dont_autoexpand(I) iterator__flag(I,DONT_AUTOEXPAND)
|
48
48
|
#define iterator__do_autoexpand(I) !iterator__flag(I,DONT_AUTOEXPAND)
|
49
|
+
#define iterator__include_conflicts(I) iterator__flag(I, INCLUDE_CONFLICTS)
|
49
50
|
|
50
51
|
#define GIT_ITERATOR_FIRST_ACCESS (1 << 15)
|
51
52
|
#define iterator__has_been_accessed(I) iterator__flag(I,FIRST_ACCESS)
|
@@ -668,13 +669,16 @@ static const git_index_entry *index_iterator__index_entry(index_iterator *ii)
|
|
668
669
|
return ie;
|
669
670
|
}
|
670
671
|
|
671
|
-
static const git_index_entry *
|
672
|
+
static const git_index_entry *index_iterator__advance_over_conflicts(index_iterator *ii)
|
672
673
|
{
|
673
|
-
const git_index_entry *ie;
|
674
|
+
const git_index_entry *ie = index_iterator__index_entry(ii);
|
674
675
|
|
675
|
-
|
676
|
-
|
677
|
-
|
676
|
+
if (!iterator__include_conflicts(ii)) {
|
677
|
+
while (ie && git_index_entry_is_conflict(ie)) {
|
678
|
+
ii->current++;
|
679
|
+
ie = index_iterator__index_entry(ii);
|
680
|
+
}
|
681
|
+
}
|
678
682
|
|
679
683
|
return ie;
|
680
684
|
}
|
@@ -702,7 +706,7 @@ static void index_iterator__next_prefix_tree(index_iterator *ii)
|
|
702
706
|
|
703
707
|
static int index_iterator__first_prefix_tree(index_iterator *ii)
|
704
708
|
{
|
705
|
-
const git_index_entry *ie =
|
709
|
+
const git_index_entry *ie = index_iterator__advance_over_conflicts(ii);
|
706
710
|
const char *scan, *prior, *slash;
|
707
711
|
|
708
712
|
if (!ie || !iterator__include_trees(ii))
|
@@ -825,7 +829,7 @@ static int index_iterator__reset(
|
|
825
829
|
git_index_snapshot_find(
|
826
830
|
&ii->current, &ii->entries, ii->entry_srch, ii->base.start, 0, 0);
|
827
831
|
|
828
|
-
if ((ie =
|
832
|
+
if ((ie = index_iterator__advance_over_conflicts(ii)) == NULL)
|
829
833
|
return 0;
|
830
834
|
|
831
835
|
if (git_buf_sets(&ii->partial, ie->path) < 0)
|
@@ -1401,10 +1405,10 @@ GIT_INLINE(bool) workdir_path_is_dotgit(const git_buf *path)
|
|
1401
1405
|
if (path->ptr[len - 1] == '/')
|
1402
1406
|
len--;
|
1403
1407
|
|
1404
|
-
if (
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
+
if (git__tolower(path->ptr[len - 1]) != 't' ||
|
1409
|
+
git__tolower(path->ptr[len - 2]) != 'i' ||
|
1410
|
+
git__tolower(path->ptr[len - 3]) != 'g' ||
|
1411
|
+
git__tolower(path->ptr[len - 4]) != '.')
|
1408
1412
|
return false;
|
1409
1413
|
|
1410
1414
|
return (len == 4 || path->ptr[len - 5] == '/');
|
@@ -1758,6 +1762,18 @@ int git_iterator_current_workdir_path(git_buf **path, git_iterator *iter)
|
|
1758
1762
|
return 0;
|
1759
1763
|
}
|
1760
1764
|
|
1765
|
+
int git_iterator_index(git_index **out, git_iterator *iter)
|
1766
|
+
{
|
1767
|
+
workdir_iterator *wi = (workdir_iterator *)iter;
|
1768
|
+
|
1769
|
+
if (iter->type != GIT_ITERATOR_TYPE_WORKDIR)
|
1770
|
+
*out = NULL;
|
1771
|
+
|
1772
|
+
*out = wi->index;
|
1773
|
+
|
1774
|
+
return 0;
|
1775
|
+
}
|
1776
|
+
|
1761
1777
|
int git_iterator_advance_over_with_status(
|
1762
1778
|
const git_index_entry **entryptr,
|
1763
1779
|
git_iterator_status_t *status,
|
@@ -1827,3 +1843,94 @@ int git_iterator_advance_over_with_status(
|
|
1827
1843
|
return error;
|
1828
1844
|
}
|
1829
1845
|
|
1846
|
+
int git_iterator_walk(
|
1847
|
+
git_iterator **iterators,
|
1848
|
+
size_t cnt,
|
1849
|
+
git_iterator_walk_cb cb,
|
1850
|
+
void *data)
|
1851
|
+
{
|
1852
|
+
const git_index_entry **iterator_item; /* next in each iterator */
|
1853
|
+
const git_index_entry **cur_items; /* current path in each iter */
|
1854
|
+
const git_index_entry *first_match;
|
1855
|
+
int cur_item_modified;
|
1856
|
+
size_t i, j;
|
1857
|
+
int error = 0;
|
1858
|
+
|
1859
|
+
iterator_item = git__calloc(cnt, sizeof(git_index_entry *));
|
1860
|
+
cur_items = git__calloc(cnt, sizeof(git_index_entry *));
|
1861
|
+
|
1862
|
+
GITERR_CHECK_ALLOC(iterator_item);
|
1863
|
+
GITERR_CHECK_ALLOC(cur_items);
|
1864
|
+
|
1865
|
+
/* Set up the iterators */
|
1866
|
+
for (i = 0; i < cnt; i++) {
|
1867
|
+
error = git_iterator_current(&iterator_item[i], iterators[i]);
|
1868
|
+
|
1869
|
+
if (error < 0 && error != GIT_ITEROVER)
|
1870
|
+
goto done;
|
1871
|
+
}
|
1872
|
+
|
1873
|
+
while (true) {
|
1874
|
+
for (i = 0; i < cnt; i++)
|
1875
|
+
cur_items[i] = NULL;
|
1876
|
+
|
1877
|
+
first_match = NULL;
|
1878
|
+
cur_item_modified = 0;
|
1879
|
+
|
1880
|
+
/* Find the next path(s) to consume from each iterator */
|
1881
|
+
for (i = 0; i < cnt; i++) {
|
1882
|
+
if (iterator_item[i] == NULL)
|
1883
|
+
continue;
|
1884
|
+
|
1885
|
+
if (first_match == NULL) {
|
1886
|
+
first_match = iterator_item[i];
|
1887
|
+
cur_items[i] = iterator_item[i];
|
1888
|
+
} else {
|
1889
|
+
int path_diff = git_index_entry_cmp(iterator_item[i], first_match);
|
1890
|
+
|
1891
|
+
if (path_diff < 0) {
|
1892
|
+
/* Found an index entry that sorts before the one we're
|
1893
|
+
* looking at. Forget that we've seen the other and
|
1894
|
+
* look at the other iterators for this path.
|
1895
|
+
*/
|
1896
|
+
for (j = 0; j < i; j++)
|
1897
|
+
cur_items[j] = NULL;
|
1898
|
+
|
1899
|
+
first_match = iterator_item[i];
|
1900
|
+
cur_items[i] = iterator_item[i];
|
1901
|
+
} else if (path_diff > 0) {
|
1902
|
+
/* No entry for the current item, this is modified */
|
1903
|
+
cur_item_modified = 1;
|
1904
|
+
} else if (path_diff == 0) {
|
1905
|
+
cur_items[i] = iterator_item[i];
|
1906
|
+
}
|
1907
|
+
}
|
1908
|
+
}
|
1909
|
+
|
1910
|
+
if (first_match == NULL)
|
1911
|
+
break;
|
1912
|
+
|
1913
|
+
if ((error = cb(cur_items, data)) != 0)
|
1914
|
+
goto done;
|
1915
|
+
|
1916
|
+
/* Advance each iterator that participated */
|
1917
|
+
for (i = 0; i < cnt; i++) {
|
1918
|
+
if (cur_items[i] == NULL)
|
1919
|
+
continue;
|
1920
|
+
|
1921
|
+
error = git_iterator_advance(&iterator_item[i], iterators[i]);
|
1922
|
+
|
1923
|
+
if (error < 0 && error != GIT_ITEROVER)
|
1924
|
+
goto done;
|
1925
|
+
}
|
1926
|
+
}
|
1927
|
+
|
1928
|
+
done:
|
1929
|
+
git__free(iterator_item);
|
1930
|
+
git__free(cur_items);
|
1931
|
+
|
1932
|
+
if (error == GIT_ITEROVER)
|
1933
|
+
error = 0;
|
1934
|
+
|
1935
|
+
return error;
|
1936
|
+
}
|
@@ -11,6 +11,7 @@
|
|
11
11
|
#include "git2/index.h"
|
12
12
|
#include "vector.h"
|
13
13
|
#include "buffer.h"
|
14
|
+
#include "ignore.h"
|
14
15
|
|
15
16
|
typedef struct git_iterator git_iterator;
|
16
17
|
|
@@ -33,6 +34,8 @@ typedef enum {
|
|
33
34
|
GIT_ITERATOR_DONT_AUTOEXPAND = (1u << 3),
|
34
35
|
/** convert precomposed unicode to decomposed unicode */
|
35
36
|
GIT_ITERATOR_PRECOMPOSE_UNICODE = (1u << 4),
|
37
|
+
/** include conflicts */
|
38
|
+
GIT_ITERATOR_INCLUDE_CONFLICTS = (1u << 5),
|
36
39
|
} git_iterator_flag_t;
|
37
40
|
|
38
41
|
typedef struct {
|
@@ -284,4 +287,26 @@ typedef enum {
|
|
284
287
|
extern int git_iterator_advance_over_with_status(
|
285
288
|
const git_index_entry **entry, git_iterator_status_t *status, git_iterator *iter);
|
286
289
|
|
290
|
+
/**
|
291
|
+
* Retrieve the index stored in the iterator.
|
292
|
+
*
|
293
|
+
* Only implemented for the workdir iterator
|
294
|
+
*/
|
295
|
+
extern int git_iterator_index(git_index **out, git_iterator *iter);
|
296
|
+
|
297
|
+
typedef int (*git_iterator_walk_cb)(
|
298
|
+
const git_index_entry **entries,
|
299
|
+
void *data);
|
300
|
+
|
301
|
+
/**
|
302
|
+
* Walk the given iterators in lock-step. The given callback will be
|
303
|
+
* called for each unique path, with the index entry in each iterator
|
304
|
+
* (or NULL if the given iterator does not contain that path).
|
305
|
+
*/
|
306
|
+
extern int git_iterator_walk(
|
307
|
+
git_iterator **iterators,
|
308
|
+
size_t cnt,
|
309
|
+
git_iterator_walk_cb cb,
|
310
|
+
void *data);
|
311
|
+
|
287
312
|
#endif
|
data/vendor/libgit2/src/merge.c
CHANGED
@@ -1143,9 +1143,9 @@ static void merge_diff_list_count_candidates(
|
|
1143
1143
|
if (GIT_MERGE_INDEX_ENTRY_EXISTS(entry->ancestor_entry) &&
|
1144
1144
|
(!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->our_entry) ||
|
1145
1145
|
!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->their_entry)))
|
1146
|
-
src_count++;
|
1146
|
+
(*src_count)++;
|
1147
1147
|
else if (!GIT_MERGE_INDEX_ENTRY_EXISTS(entry->ancestor_entry))
|
1148
|
-
tgt_count++;
|
1148
|
+
(*tgt_count)++;
|
1149
1149
|
}
|
1150
1150
|
}
|
1151
1151
|
|
@@ -1449,108 +1449,44 @@ static int merge_diff_list_insert_unmodified(
|
|
1449
1449
|
return error;
|
1450
1450
|
}
|
1451
1451
|
|
1452
|
-
|
1453
|
-
git_merge_diff_list *diff_list
|
1454
|
-
|
1455
|
-
|
1456
|
-
const git_tree *their_tree)
|
1457
|
-
{
|
1458
|
-
git_iterator *iterators[3] = {0};
|
1459
|
-
const git_index_entry *items[3] = {0}, *best_cur_item, *cur_items[3];
|
1460
|
-
git_vector_cmp entry_compare = git_index_entry_cmp;
|
1461
|
-
struct merge_diff_df_data df_data = {0};
|
1462
|
-
int cur_item_modified;
|
1463
|
-
size_t i, j;
|
1464
|
-
int error = 0;
|
1465
|
-
|
1466
|
-
assert(diff_list && (our_tree || their_tree));
|
1467
|
-
|
1468
|
-
if ((error = git_iterator_for_tree(&iterators[TREE_IDX_ANCESTOR], (git_tree *)ancestor_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
|
1469
|
-
(error = git_iterator_for_tree(&iterators[TREE_IDX_OURS], (git_tree *)our_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
|
1470
|
-
(error = git_iterator_for_tree(&iterators[TREE_IDX_THEIRS], (git_tree *)their_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0)
|
1471
|
-
goto done;
|
1472
|
-
|
1473
|
-
/* Set up the iterators */
|
1474
|
-
for (i = 0; i < 3; i++) {
|
1475
|
-
error = git_iterator_current(&items[i], iterators[i]);
|
1476
|
-
|
1477
|
-
if (error < 0 && error != GIT_ITEROVER)
|
1478
|
-
goto done;
|
1479
|
-
}
|
1480
|
-
|
1481
|
-
while (true) {
|
1482
|
-
for (i = 0; i < 3; i++)
|
1483
|
-
cur_items[i] = NULL;
|
1484
|
-
|
1485
|
-
best_cur_item = NULL;
|
1486
|
-
cur_item_modified = 0;
|
1452
|
+
struct merge_diff_find_data {
|
1453
|
+
git_merge_diff_list *diff_list;
|
1454
|
+
struct merge_diff_df_data df_data;
|
1455
|
+
};
|
1487
1456
|
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
}
|
1457
|
+
static int queue_difference(const git_index_entry **entries, void *data)
|
1458
|
+
{
|
1459
|
+
struct merge_diff_find_data *find_data = data;
|
1460
|
+
bool item_modified = false;
|
1461
|
+
size_t i;
|
1494
1462
|
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
/*
|
1503
|
-
* Found an item that sorts before our current item, make
|
1504
|
-
* our current item this one.
|
1505
|
-
*/
|
1506
|
-
for (j = 0; j < i; j++)
|
1507
|
-
cur_items[j] = NULL;
|
1508
|
-
|
1509
|
-
cur_item_modified = 1;
|
1510
|
-
best_cur_item = items[i];
|
1511
|
-
cur_items[i] = items[i];
|
1512
|
-
} else if (path_diff > 0) {
|
1513
|
-
/* No entry for the current item, this is modified */
|
1514
|
-
cur_item_modified = 1;
|
1515
|
-
} else if (path_diff == 0) {
|
1516
|
-
cur_items[i] = items[i];
|
1517
|
-
|
1518
|
-
if (!cur_item_modified)
|
1519
|
-
cur_item_modified = index_entry_cmp(best_cur_item, items[i]);
|
1520
|
-
}
|
1463
|
+
if (!entries[0] || !entries[1] || !entries[2]) {
|
1464
|
+
item_modified = true;
|
1465
|
+
} else {
|
1466
|
+
for (i = 1; i < 3; i++) {
|
1467
|
+
if (index_entry_cmp(entries[0], entries[i]) != 0) {
|
1468
|
+
item_modified = true;
|
1469
|
+
break;
|
1521
1470
|
}
|
1522
1471
|
}
|
1523
|
-
|
1524
|
-
if (best_cur_item == NULL)
|
1525
|
-
break;
|
1526
|
-
|
1527
|
-
if (cur_item_modified)
|
1528
|
-
error = merge_diff_list_insert_conflict(diff_list, &df_data, cur_items);
|
1529
|
-
else
|
1530
|
-
error = merge_diff_list_insert_unmodified(diff_list, cur_items);
|
1531
|
-
if (error < 0)
|
1532
|
-
goto done;
|
1533
|
-
|
1534
|
-
/* Advance each iterator that participated */
|
1535
|
-
for (i = 0; i < 3; i++) {
|
1536
|
-
if (cur_items[i] == NULL)
|
1537
|
-
continue;
|
1538
|
-
|
1539
|
-
error = git_iterator_advance(&items[i], iterators[i]);
|
1540
|
-
|
1541
|
-
if (error < 0 && error != GIT_ITEROVER)
|
1542
|
-
goto done;
|
1543
|
-
}
|
1544
1472
|
}
|
1545
1473
|
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1474
|
+
return item_modified ?
|
1475
|
+
merge_diff_list_insert_conflict(
|
1476
|
+
find_data->diff_list, &find_data->df_data, entries) :
|
1477
|
+
merge_diff_list_insert_unmodified(find_data->diff_list, entries);
|
1478
|
+
}
|
1549
1479
|
|
1550
|
-
|
1551
|
-
|
1480
|
+
int git_merge_diff_list__find_differences(
|
1481
|
+
git_merge_diff_list *diff_list,
|
1482
|
+
git_iterator *ancestor_iter,
|
1483
|
+
git_iterator *our_iter,
|
1484
|
+
git_iterator *their_iter)
|
1485
|
+
{
|
1486
|
+
git_iterator *iterators[3] = { ancestor_iter, our_iter, their_iter };
|
1487
|
+
struct merge_diff_find_data find_data = { diff_list };
|
1552
1488
|
|
1553
|
-
return
|
1489
|
+
return git_iterator_walk(iterators, 3, queue_difference, &find_data);
|
1554
1490
|
}
|
1555
1491
|
|
1556
1492
|
git_merge_diff_list *git_merge_diff_list__alloc(git_repository *repo)
|
@@ -1757,14 +1693,28 @@ on_error:
|
|
1757
1693
|
return error;
|
1758
1694
|
}
|
1759
1695
|
|
1760
|
-
|
1696
|
+
static git_iterator *iterator_given_or_empty(git_iterator **empty, git_iterator *given)
|
1697
|
+
{
|
1698
|
+
if (given)
|
1699
|
+
return given;
|
1700
|
+
|
1701
|
+
if (git_iterator_for_nothing(empty, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL) < 0)
|
1702
|
+
return NULL;
|
1703
|
+
|
1704
|
+
return *empty;
|
1705
|
+
}
|
1706
|
+
|
1707
|
+
int git_merge__iterators(
|
1761
1708
|
git_index **out,
|
1762
1709
|
git_repository *repo,
|
1763
|
-
|
1764
|
-
|
1765
|
-
|
1710
|
+
git_iterator *ancestor_iter,
|
1711
|
+
git_iterator *our_iter,
|
1712
|
+
git_iterator *theirs_iter,
|
1766
1713
|
const git_merge_options *given_opts)
|
1767
1714
|
{
|
1715
|
+
git_iterator *empty_ancestor = NULL,
|
1716
|
+
*empty_ours = NULL,
|
1717
|
+
*empty_theirs = NULL;
|
1768
1718
|
git_merge_diff_list *diff_list;
|
1769
1719
|
git_merge_options opts;
|
1770
1720
|
git_merge_diff *conflict;
|
@@ -1772,11 +1722,12 @@ int git_merge_trees(
|
|
1772
1722
|
size_t i;
|
1773
1723
|
int error = 0;
|
1774
1724
|
|
1775
|
-
assert(out && repo
|
1725
|
+
assert(out && repo);
|
1776
1726
|
|
1777
1727
|
*out = NULL;
|
1778
1728
|
|
1779
|
-
GITERR_CHECK_VERSION(
|
1729
|
+
GITERR_CHECK_VERSION(
|
1730
|
+
given_opts, GIT_MERGE_OPTIONS_VERSION, "git_merge_options");
|
1780
1731
|
|
1781
1732
|
if ((error = merge_normalize_opts(repo, &opts, given_opts)) < 0)
|
1782
1733
|
return error;
|
@@ -1784,7 +1735,12 @@ int git_merge_trees(
|
|
1784
1735
|
diff_list = git_merge_diff_list__alloc(repo);
|
1785
1736
|
GITERR_CHECK_ALLOC(diff_list);
|
1786
1737
|
|
1787
|
-
|
1738
|
+
ancestor_iter = iterator_given_or_empty(&empty_ancestor, ancestor_iter);
|
1739
|
+
our_iter = iterator_given_or_empty(&empty_ours, our_iter);
|
1740
|
+
theirs_iter = iterator_given_or_empty(&empty_theirs, theirs_iter);
|
1741
|
+
|
1742
|
+
if ((error = git_merge_diff_list__find_differences(
|
1743
|
+
diff_list, ancestor_iter, our_iter, theirs_iter)) < 0 ||
|
1788
1744
|
(error = git_merge_diff_list__find_renames(repo, diff_list, &opts)) < 0)
|
1789
1745
|
goto done;
|
1790
1746
|
|
@@ -1808,10 +1764,44 @@ int git_merge_trees(
|
|
1808
1764
|
|
1809
1765
|
done:
|
1810
1766
|
git_merge_diff_list__free(diff_list);
|
1767
|
+
git_iterator_free(empty_ancestor);
|
1768
|
+
git_iterator_free(empty_ours);
|
1769
|
+
git_iterator_free(empty_theirs);
|
1811
1770
|
|
1812
1771
|
return error;
|
1813
1772
|
}
|
1814
1773
|
|
1774
|
+
int git_merge_trees(
|
1775
|
+
git_index **out,
|
1776
|
+
git_repository *repo,
|
1777
|
+
const git_tree *ancestor_tree,
|
1778
|
+
const git_tree *our_tree,
|
1779
|
+
const git_tree *their_tree,
|
1780
|
+
const git_merge_options *merge_opts)
|
1781
|
+
{
|
1782
|
+
git_iterator *ancestor_iter = NULL, *our_iter = NULL, *their_iter = NULL;
|
1783
|
+
int error;
|
1784
|
+
|
1785
|
+
if ((error = git_iterator_for_tree(&ancestor_iter, (git_tree *)ancestor_tree,
|
1786
|
+
GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
|
1787
|
+
(error = git_iterator_for_tree(&our_iter, (git_tree *)our_tree,
|
1788
|
+
GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
|
1789
|
+
(error = git_iterator_for_tree(&their_iter, (git_tree *)their_tree,
|
1790
|
+
GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0)
|
1791
|
+
goto done;
|
1792
|
+
|
1793
|
+
error = git_merge__iterators(
|
1794
|
+
out, repo, ancestor_iter, our_iter, their_iter, merge_opts);
|
1795
|
+
|
1796
|
+
done:
|
1797
|
+
git_iterator_free(ancestor_iter);
|
1798
|
+
git_iterator_free(our_iter);
|
1799
|
+
git_iterator_free(their_iter);
|
1800
|
+
|
1801
|
+
return error;
|
1802
|
+
}
|
1803
|
+
|
1804
|
+
|
1815
1805
|
int git_merge_commits(
|
1816
1806
|
git_index **out,
|
1817
1807
|
git_repository *repo,
|
@@ -2446,7 +2436,7 @@ int git_merge__check_result(git_repository *repo, git_index *index_new)
|
|
2446
2436
|
for (i = 0; i < git_index_entrycount(index_new); i++) {
|
2447
2437
|
e = git_index_get_byindex(index_new, i);
|
2448
2438
|
|
2449
|
-
if (
|
2439
|
+
if (git_index_entry_is_conflict(e) &&
|
2450
2440
|
(git_vector_last(&paths) == NULL ||
|
2451
2441
|
strcmp(git_vector_last(&paths), e->path) != 0)) {
|
2452
2442
|
|
@@ -2463,7 +2453,7 @@ int git_merge__check_result(git_repository *repo, git_index *index_new)
|
|
2463
2453
|
if ((conflicts = index_conflicts + wd_conflicts) > 0) {
|
2464
2454
|
giterr_set(GITERR_MERGE, "%d uncommitted change%s would be overwritten by merge",
|
2465
2455
|
conflicts, (conflicts != 1) ? "s" : "");
|
2466
|
-
error =
|
2456
|
+
error = GIT_ECONFLICT;
|
2467
2457
|
}
|
2468
2458
|
|
2469
2459
|
done:
|
@@ -2498,7 +2488,7 @@ int git_merge__append_conflicts_to_merge_msg(
|
|
2498
2488
|
for (i = 0; i < git_index_entrycount(index); i++) {
|
2499
2489
|
const git_index_entry *e = git_index_get_byindex(index, i);
|
2500
2490
|
|
2501
|
-
if (
|
2491
|
+
if (!git_index_entry_is_conflict(e))
|
2502
2492
|
continue;
|
2503
2493
|
|
2504
2494
|
if (last == NULL || strcmp(e->path, last) != 0)
|