rugged 0.23.0b2 → 0.23.0b4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/ident.c
CHANGED
|
@@ -56,7 +56,7 @@ static int ident_insert_id(
|
|
|
56
56
|
return GIT_PASSTHROUGH;
|
|
57
57
|
|
|
58
58
|
need_size = (size_t)(id_start - from->ptr) +
|
|
59
|
-
5 /* "$Id: " */ + GIT_OID_HEXSZ +
|
|
59
|
+
5 /* "$Id: " */ + GIT_OID_HEXSZ + 2 /* " $" */ +
|
|
60
60
|
(size_t)(from_end - id_end);
|
|
61
61
|
|
|
62
62
|
if (git_buf_grow(to, need_size) < 0)
|
|
@@ -65,7 +65,7 @@ static int ident_insert_id(
|
|
|
65
65
|
git_buf_set(to, from->ptr, (size_t)(id_start - from->ptr));
|
|
66
66
|
git_buf_put(to, "$Id: ", 5);
|
|
67
67
|
git_buf_put(to, oid, GIT_OID_HEXSZ);
|
|
68
|
-
|
|
68
|
+
git_buf_put(to, " $", 2);
|
|
69
69
|
git_buf_put(to, id_end, (size_t)(from_end - id_end));
|
|
70
70
|
|
|
71
71
|
return git_buf_oom(to) ? -1 : 0;
|
data/vendor/libgit2/src/ignore.c
CHANGED
data/vendor/libgit2/src/index.c
CHANGED
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
#include "git2/config.h"
|
|
25
25
|
#include "git2/sys/index.h"
|
|
26
26
|
|
|
27
|
+
static int index_apply_to_wd_diff(git_index *index, int action, const git_strarray *paths,
|
|
28
|
+
unsigned int flags,
|
|
29
|
+
git_index_matched_path_cb cb, void *payload);
|
|
30
|
+
|
|
27
31
|
#define entry_size(type,len) ((offsetof(type, path) + (len) + 8) & ~7)
|
|
28
32
|
#define short_entry_size(len) entry_size(struct entry_short, len)
|
|
29
33
|
#define long_entry_size(len) entry_size(struct entry_long, len)
|
|
@@ -112,7 +116,7 @@ static int read_header(struct index_header *dest, const void *buffer);
|
|
|
112
116
|
|
|
113
117
|
static int parse_index(git_index *index, const char *buffer, size_t buffer_size);
|
|
114
118
|
static bool is_index_extended(git_index *index);
|
|
115
|
-
static int write_index(git_index *index, git_filebuf *file);
|
|
119
|
+
static int write_index(git_oid *checksum, git_index *index, git_filebuf *file);
|
|
116
120
|
|
|
117
121
|
static void index_entry_free(git_index_entry *entry);
|
|
118
122
|
static void index_entry_reuc_free(git_index_reuc_entry *reuc);
|
|
@@ -594,6 +598,38 @@ int git_index_caps(const git_index *index)
|
|
|
594
598
|
(index->no_symlinks ? GIT_INDEXCAP_NO_SYMLINKS : 0));
|
|
595
599
|
}
|
|
596
600
|
|
|
601
|
+
const git_oid *git_index_checksum(git_index *index)
|
|
602
|
+
{
|
|
603
|
+
return &index->checksum;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Returns 1 for changed, 0 for not changed and <0 for errors
|
|
608
|
+
*/
|
|
609
|
+
static int compare_checksum(git_index *index)
|
|
610
|
+
{
|
|
611
|
+
int fd, error;
|
|
612
|
+
ssize_t bytes_read;
|
|
613
|
+
git_oid checksum = {{ 0 }};
|
|
614
|
+
|
|
615
|
+
if ((fd = p_open(index->index_file_path, O_RDONLY)) < 0)
|
|
616
|
+
return fd;
|
|
617
|
+
|
|
618
|
+
if ((error = p_lseek(fd, -20, SEEK_END)) < 0) {
|
|
619
|
+
p_close(fd);
|
|
620
|
+
giterr_set(GITERR_OS, "failed to seek to end of file");
|
|
621
|
+
return -1;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
bytes_read = p_read(fd, &checksum, GIT_OID_RAWSZ);
|
|
625
|
+
p_close(fd);
|
|
626
|
+
|
|
627
|
+
if (bytes_read < 0)
|
|
628
|
+
return -1;
|
|
629
|
+
|
|
630
|
+
return !!git_oid_cmp(&checksum, &index->checksum);
|
|
631
|
+
}
|
|
632
|
+
|
|
597
633
|
int git_index_read(git_index *index, int force)
|
|
598
634
|
{
|
|
599
635
|
int error = 0, updated;
|
|
@@ -612,8 +648,8 @@ int git_index_read(git_index *index, int force)
|
|
|
612
648
|
return 0;
|
|
613
649
|
}
|
|
614
650
|
|
|
615
|
-
updated = git_futils_filestamp_check(&stamp, index->index_file_path)
|
|
616
|
-
|
|
651
|
+
if ((updated = git_futils_filestamp_check(&stamp, index->index_file_path) < 0) ||
|
|
652
|
+
((updated = compare_checksum(index)) < 0)) {
|
|
617
653
|
giterr_set(
|
|
618
654
|
GITERR_INDEX,
|
|
619
655
|
"Failed to read index: '%s' no longer exists",
|
|
@@ -643,15 +679,68 @@ int git_index_read(git_index *index, int force)
|
|
|
643
679
|
}
|
|
644
680
|
|
|
645
681
|
int git_index__changed_relative_to(
|
|
646
|
-
git_index *index, const
|
|
682
|
+
git_index *index, const git_oid *checksum)
|
|
647
683
|
{
|
|
648
684
|
/* attempt to update index (ignoring errors) */
|
|
649
685
|
if (git_index_read(index, false) < 0)
|
|
650
686
|
giterr_clear();
|
|
651
687
|
|
|
652
|
-
return (index->
|
|
653
|
-
|
|
654
|
-
|
|
688
|
+
return !!git_oid_cmp(&index->checksum, checksum);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
static bool is_racy_timestamp(git_time_t stamp, git_index_entry *entry)
|
|
692
|
+
{
|
|
693
|
+
/* Git special-cases submodules in the check */
|
|
694
|
+
if (S_ISGITLINK(entry->mode))
|
|
695
|
+
return false;
|
|
696
|
+
|
|
697
|
+
/* If we never read the index, we can't have this race either */
|
|
698
|
+
if (stamp == 0)
|
|
699
|
+
return false;
|
|
700
|
+
|
|
701
|
+
/* If the timestamp is the same or newer than the index, it's racy */
|
|
702
|
+
return ((int32_t) stamp) <= entry->mtime.seconds;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/*
|
|
706
|
+
* Force the next diff to take a look at those entries which have the
|
|
707
|
+
* same timestamp as the current index.
|
|
708
|
+
*/
|
|
709
|
+
static int truncate_racily_clean(git_index *index)
|
|
710
|
+
{
|
|
711
|
+
size_t i;
|
|
712
|
+
int error;
|
|
713
|
+
git_index_entry *entry;
|
|
714
|
+
git_time_t ts = index->stamp.mtime;
|
|
715
|
+
git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
|
|
716
|
+
git_diff *diff;
|
|
717
|
+
|
|
718
|
+
/* Nothing to do if there's no repo to talk about */
|
|
719
|
+
if (!INDEX_OWNER(index))
|
|
720
|
+
return 0;
|
|
721
|
+
|
|
722
|
+
/* If there's no workdir, we can't know where to even check */
|
|
723
|
+
if (!git_repository_workdir(INDEX_OWNER(index)))
|
|
724
|
+
return 0;
|
|
725
|
+
|
|
726
|
+
diff_opts.flags |= GIT_DIFF_INCLUDE_TYPECHANGE | GIT_DIFF_IGNORE_SUBMODULES | GIT_DIFF_DISABLE_PATHSPEC_MATCH;
|
|
727
|
+
git_vector_foreach(&index->entries, i, entry) {
|
|
728
|
+
if (!is_racy_timestamp(ts, entry))
|
|
729
|
+
continue;
|
|
730
|
+
|
|
731
|
+
diff_opts.pathspec.count = 1;
|
|
732
|
+
diff_opts.pathspec.strings = (char **) &entry->path;
|
|
733
|
+
|
|
734
|
+
if ((error = git_diff_index_to_workdir(&diff, INDEX_OWNER(index), index, &diff_opts)) < 0)
|
|
735
|
+
return error;
|
|
736
|
+
|
|
737
|
+
if (git_diff_num_deltas(diff) > 0)
|
|
738
|
+
entry->file_size = 0;
|
|
739
|
+
|
|
740
|
+
git_diff_free(diff);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
return 0;
|
|
655
744
|
}
|
|
656
745
|
|
|
657
746
|
int git_index_write(git_index *index)
|
|
@@ -659,6 +748,8 @@ int git_index_write(git_index *index)
|
|
|
659
748
|
git_indexwriter writer = GIT_INDEXWRITER_INIT;
|
|
660
749
|
int error;
|
|
661
750
|
|
|
751
|
+
truncate_racily_clean(index);
|
|
752
|
+
|
|
662
753
|
if ((error = git_indexwriter_init(&writer, index)) == 0)
|
|
663
754
|
error = git_indexwriter_commit(&writer);
|
|
664
755
|
|
|
@@ -1169,6 +1260,9 @@ int git_index_remove_bypath(git_index *index, const char *path)
|
|
|
1169
1260
|
ret != GIT_ENOTFOUND))
|
|
1170
1261
|
return ret;
|
|
1171
1262
|
|
|
1263
|
+
if (ret == GIT_ENOTFOUND)
|
|
1264
|
+
giterr_clear();
|
|
1265
|
+
|
|
1172
1266
|
return 0;
|
|
1173
1267
|
}
|
|
1174
1268
|
|
|
@@ -1310,6 +1404,30 @@ int git_index_conflict_add(git_index *index,
|
|
|
1310
1404
|
(ret = index_entry_dup(&entries[2], INDEX_OWNER(index), their_entry)) < 0)
|
|
1311
1405
|
goto on_error;
|
|
1312
1406
|
|
|
1407
|
+
/* Validate entries */
|
|
1408
|
+
for (i = 0; i < 3; i++) {
|
|
1409
|
+
if (entries[i] && !valid_filemode(entries[i]->mode)) {
|
|
1410
|
+
giterr_set(GITERR_INDEX, "invalid filemode for stage %d entry",
|
|
1411
|
+
i);
|
|
1412
|
+
return -1;
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
/* Remove existing index entries for each path */
|
|
1417
|
+
for (i = 0; i < 3; i++) {
|
|
1418
|
+
if (entries[i] == NULL)
|
|
1419
|
+
continue;
|
|
1420
|
+
|
|
1421
|
+
if ((ret = git_index_remove(index, entries[i]->path, 0)) != 0) {
|
|
1422
|
+
if (ret != GIT_ENOTFOUND)
|
|
1423
|
+
goto on_error;
|
|
1424
|
+
|
|
1425
|
+
giterr_clear();
|
|
1426
|
+
ret = 0;
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
/* Add the conflict entries */
|
|
1313
1431
|
for (i = 0; i < 3; i++) {
|
|
1314
1432
|
if (entries[i] == NULL)
|
|
1315
1433
|
continue;
|
|
@@ -1317,7 +1435,7 @@ int git_index_conflict_add(git_index *index,
|
|
|
1317
1435
|
/* Make sure stage is correct */
|
|
1318
1436
|
GIT_IDXENTRY_STAGE_SET(entries[i], i + 1);
|
|
1319
1437
|
|
|
1320
|
-
if ((ret = index_insert(index, &entries[i],
|
|
1438
|
+
if ((ret = index_insert(index, &entries[i], 0, true)) < 0)
|
|
1321
1439
|
goto on_error;
|
|
1322
1440
|
|
|
1323
1441
|
entries[i] = NULL; /* don't free if later entry fails */
|
|
@@ -1506,7 +1624,7 @@ int git_index_conflict_next(
|
|
|
1506
1624
|
while (iterator->cur < iterator->index->entries.length) {
|
|
1507
1625
|
entry = git_index_get_byindex(iterator->index, iterator->cur);
|
|
1508
1626
|
|
|
1509
|
-
if (
|
|
1627
|
+
if (git_index_entry_is_conflict(entry)) {
|
|
1510
1628
|
if ((len = index_conflict__get_byindex(
|
|
1511
1629
|
ancestor_out,
|
|
1512
1630
|
our_out,
|
|
@@ -2043,6 +2161,8 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
|
|
2043
2161
|
goto done;
|
|
2044
2162
|
}
|
|
2045
2163
|
|
|
2164
|
+
git_oid_cpy(&index->checksum, &checksum_calculated);
|
|
2165
|
+
|
|
2046
2166
|
#undef seek_forward
|
|
2047
2167
|
|
|
2048
2168
|
/* Entries are stored case-sensitively on disk, so re-sort now if
|
|
@@ -2306,7 +2426,7 @@ static int write_tree_extension(git_index *index, git_filebuf *file)
|
|
|
2306
2426
|
return error;
|
|
2307
2427
|
}
|
|
2308
2428
|
|
|
2309
|
-
static int write_index(git_index *index, git_filebuf *file)
|
|
2429
|
+
static int write_index(git_oid *checksum, git_index *index, git_filebuf *file)
|
|
2310
2430
|
{
|
|
2311
2431
|
git_oid hash_final;
|
|
2312
2432
|
struct index_header header;
|
|
@@ -2342,6 +2462,7 @@ static int write_index(git_index *index, git_filebuf *file)
|
|
|
2342
2462
|
|
|
2343
2463
|
/* get out the hash for all the contents we've appended to the file */
|
|
2344
2464
|
git_filebuf_hash(&hash_final, file);
|
|
2465
|
+
git_oid_cpy(checksum, &hash_final);
|
|
2345
2466
|
|
|
2346
2467
|
/* write it at the end of the file */
|
|
2347
2468
|
return git_filebuf_write(file, hash_final.id, GIT_OID_RAWSZ);
|
|
@@ -2352,6 +2473,11 @@ int git_index_entry_stage(const git_index_entry *entry)
|
|
|
2352
2473
|
return GIT_IDXENTRY_STAGE(entry);
|
|
2353
2474
|
}
|
|
2354
2475
|
|
|
2476
|
+
int git_index_entry_is_conflict(const git_index_entry *entry)
|
|
2477
|
+
{
|
|
2478
|
+
return (GIT_IDXENTRY_STAGE(entry) > 0);
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2355
2481
|
typedef struct read_tree_data {
|
|
2356
2482
|
git_index *index;
|
|
2357
2483
|
git_vector *old_entries;
|
|
@@ -2451,11 +2577,116 @@ int git_index_read_tree(git_index *index, const git_tree *tree)
|
|
|
2451
2577
|
return error;
|
|
2452
2578
|
}
|
|
2453
2579
|
|
|
2580
|
+
int git_index_read_index(
|
|
2581
|
+
git_index *index,
|
|
2582
|
+
const git_index *new_index)
|
|
2583
|
+
{
|
|
2584
|
+
git_vector new_entries = GIT_VECTOR_INIT,
|
|
2585
|
+
remove_entries = GIT_VECTOR_INIT;
|
|
2586
|
+
git_iterator *index_iterator = NULL;
|
|
2587
|
+
git_iterator *new_iterator = NULL;
|
|
2588
|
+
const git_index_entry *old_entry, *new_entry;
|
|
2589
|
+
git_index_entry *entry;
|
|
2590
|
+
size_t i;
|
|
2591
|
+
int error;
|
|
2592
|
+
|
|
2593
|
+
if ((error = git_vector_init(&new_entries, new_index->entries.length, index->entries._cmp)) < 0 ||
|
|
2594
|
+
(error = git_vector_init(&remove_entries, index->entries.length, NULL)) < 0)
|
|
2595
|
+
goto done;
|
|
2596
|
+
|
|
2597
|
+
if ((error = git_iterator_for_index(&index_iterator,
|
|
2598
|
+
index, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 ||
|
|
2599
|
+
(error = git_iterator_for_index(&new_iterator,
|
|
2600
|
+
(git_index *)new_index, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0)
|
|
2601
|
+
goto done;
|
|
2602
|
+
|
|
2603
|
+
if (((error = git_iterator_current(&old_entry, index_iterator)) < 0 &&
|
|
2604
|
+
error != GIT_ITEROVER) ||
|
|
2605
|
+
((error = git_iterator_current(&new_entry, new_iterator)) < 0 &&
|
|
2606
|
+
error != GIT_ITEROVER))
|
|
2607
|
+
goto done;
|
|
2608
|
+
|
|
2609
|
+
while (true) {
|
|
2610
|
+
int diff;
|
|
2611
|
+
|
|
2612
|
+
if (old_entry && new_entry)
|
|
2613
|
+
diff = git_index_entry_cmp(old_entry, new_entry);
|
|
2614
|
+
else if (!old_entry && new_entry)
|
|
2615
|
+
diff = 1;
|
|
2616
|
+
else if (old_entry && !new_entry)
|
|
2617
|
+
diff = -1;
|
|
2618
|
+
else
|
|
2619
|
+
break;
|
|
2620
|
+
|
|
2621
|
+
if (diff < 0) {
|
|
2622
|
+
git_vector_insert(&remove_entries, (git_index_entry *)old_entry);
|
|
2623
|
+
} else if (diff > 0) {
|
|
2624
|
+
if ((error = index_entry_dup(&entry, git_index_owner(index), new_entry)) < 0)
|
|
2625
|
+
goto done;
|
|
2626
|
+
|
|
2627
|
+
git_vector_insert(&new_entries, entry);
|
|
2628
|
+
} else {
|
|
2629
|
+
/* Path and stage are equal, if the OID is equal, keep it to
|
|
2630
|
+
* keep the stat cache data.
|
|
2631
|
+
*/
|
|
2632
|
+
if (git_oid_equal(&old_entry->id, &new_entry->id)) {
|
|
2633
|
+
git_vector_insert(&new_entries, (git_index_entry *)old_entry);
|
|
2634
|
+
} else {
|
|
2635
|
+
if ((error = index_entry_dup(&entry, git_index_owner(index), new_entry)) < 0)
|
|
2636
|
+
goto done;
|
|
2637
|
+
|
|
2638
|
+
git_vector_insert(&new_entries, entry);
|
|
2639
|
+
git_vector_insert(&remove_entries, (git_index_entry *)old_entry);
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
|
|
2643
|
+
if (diff <= 0) {
|
|
2644
|
+
if ((error = git_iterator_advance(&old_entry, index_iterator)) < 0 &&
|
|
2645
|
+
error != GIT_ITEROVER)
|
|
2646
|
+
goto done;
|
|
2647
|
+
}
|
|
2648
|
+
|
|
2649
|
+
if (diff >= 0) {
|
|
2650
|
+
if ((error = git_iterator_advance(&new_entry, new_iterator)) < 0 &&
|
|
2651
|
+
error != GIT_ITEROVER)
|
|
2652
|
+
goto done;
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
|
|
2656
|
+
git_index_name_clear(index);
|
|
2657
|
+
git_index_reuc_clear(index);
|
|
2658
|
+
|
|
2659
|
+
git_vector_swap(&new_entries, &index->entries);
|
|
2660
|
+
|
|
2661
|
+
git_vector_foreach(&remove_entries, i, entry) {
|
|
2662
|
+
if (index->tree)
|
|
2663
|
+
git_tree_cache_invalidate_path(index->tree, entry->path);
|
|
2664
|
+
|
|
2665
|
+
index_entry_free(entry);
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2668
|
+
error = 0;
|
|
2669
|
+
|
|
2670
|
+
done:
|
|
2671
|
+
git_vector_free(&new_entries);
|
|
2672
|
+
git_vector_free(&remove_entries);
|
|
2673
|
+
git_iterator_free(index_iterator);
|
|
2674
|
+
git_iterator_free(new_iterator);
|
|
2675
|
+
return error;
|
|
2676
|
+
}
|
|
2677
|
+
|
|
2454
2678
|
git_repository *git_index_owner(const git_index *index)
|
|
2455
2679
|
{
|
|
2456
2680
|
return INDEX_OWNER(index);
|
|
2457
2681
|
}
|
|
2458
2682
|
|
|
2683
|
+
enum {
|
|
2684
|
+
INDEX_ACTION_NONE = 0,
|
|
2685
|
+
INDEX_ACTION_UPDATE = 1,
|
|
2686
|
+
INDEX_ACTION_REMOVE = 2,
|
|
2687
|
+
INDEX_ACTION_ADDALL = 3,
|
|
2688
|
+
};
|
|
2689
|
+
|
|
2459
2690
|
int git_index_add_all(
|
|
2460
2691
|
git_index *index,
|
|
2461
2692
|
const git_strarray *paths,
|
|
@@ -2466,29 +2697,15 @@ int git_index_add_all(
|
|
|
2466
2697
|
int error;
|
|
2467
2698
|
git_repository *repo;
|
|
2468
2699
|
git_iterator *wditer = NULL;
|
|
2469
|
-
const git_index_entry *wd = NULL;
|
|
2470
|
-
git_index_entry *entry;
|
|
2471
2700
|
git_pathspec ps;
|
|
2472
|
-
const char *match;
|
|
2473
|
-
size_t existing;
|
|
2474
2701
|
bool no_fnmatch = (flags & GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH) != 0;
|
|
2475
|
-
int ignorecase;
|
|
2476
|
-
git_oid blobid;
|
|
2477
2702
|
|
|
2478
2703
|
assert(index);
|
|
2479
2704
|
|
|
2480
|
-
if (INDEX_OWNER(index) == NULL)
|
|
2481
|
-
return create_index_error(-1,
|
|
2482
|
-
"Could not add paths to index. "
|
|
2483
|
-
"Index is not backed up by an existing repository.");
|
|
2484
|
-
|
|
2485
2705
|
repo = INDEX_OWNER(index);
|
|
2486
2706
|
if ((error = git_repository__ensure_not_bare(repo, "index add all")) < 0)
|
|
2487
2707
|
return error;
|
|
2488
2708
|
|
|
2489
|
-
if (git_repository__cvar(&ignorecase, repo, GIT_CVAR_IGNORECASE) < 0)
|
|
2490
|
-
return -1;
|
|
2491
|
-
|
|
2492
2709
|
if ((error = git_pathspec__init(&ps, paths)) < 0)
|
|
2493
2710
|
return error;
|
|
2494
2711
|
|
|
@@ -2499,77 +2716,118 @@ int git_index_add_all(
|
|
|
2499
2716
|
repo, &ps.pathspec, no_fnmatch)) < 0)
|
|
2500
2717
|
goto cleanup;
|
|
2501
2718
|
|
|
2502
|
-
|
|
2503
|
-
&wditer, repo, NULL, NULL, 0, ps.prefix, ps.prefix)) < 0)
|
|
2504
|
-
goto cleanup;
|
|
2719
|
+
error = index_apply_to_wd_diff(index, INDEX_ACTION_ADDALL, paths, flags, cb, payload);
|
|
2505
2720
|
|
|
2506
|
-
|
|
2721
|
+
if (error)
|
|
2722
|
+
giterr_set_after_callback(error);
|
|
2507
2723
|
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
continue;
|
|
2724
|
+
cleanup:
|
|
2725
|
+
git_iterator_free(wditer);
|
|
2726
|
+
git_pathspec__clear(&ps);
|
|
2512
2727
|
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
git_iterator_current_is_ignored(wditer) &&
|
|
2516
|
-
index_find(&existing, index, wd->path, 0, 0, true) < 0)
|
|
2517
|
-
continue;
|
|
2728
|
+
return error;
|
|
2729
|
+
}
|
|
2518
2730
|
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
}
|
|
2527
|
-
}
|
|
2731
|
+
struct foreach_diff_data {
|
|
2732
|
+
git_index *index;
|
|
2733
|
+
const git_pathspec *pathspec;
|
|
2734
|
+
unsigned int flags;
|
|
2735
|
+
git_index_matched_path_cb cb;
|
|
2736
|
+
void *payload;
|
|
2737
|
+
};
|
|
2528
2738
|
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2739
|
+
static int apply_each_file(const git_diff_delta *delta, float progress, void *payload)
|
|
2740
|
+
{
|
|
2741
|
+
struct foreach_diff_data *data = payload;
|
|
2742
|
+
const char *match, *path;
|
|
2743
|
+
int error = 0;
|
|
2532
2744
|
|
|
2533
|
-
|
|
2534
|
-
if ((error = git_blob_create_fromworkdir(&blobid, repo, wd->path)) < 0)
|
|
2535
|
-
break;
|
|
2745
|
+
GIT_UNUSED(progress);
|
|
2536
2746
|
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2747
|
+
path = delta->old_file.path;
|
|
2748
|
+
|
|
2749
|
+
/* We only want those which match the pathspecs */
|
|
2750
|
+
if (!git_pathspec__match(
|
|
2751
|
+
&data->pathspec->pathspec, path, false, (bool)data->index->ignore_case,
|
|
2752
|
+
&match, NULL))
|
|
2753
|
+
return 0;
|
|
2540
2754
|
|
|
2541
|
-
|
|
2755
|
+
if (data->cb)
|
|
2756
|
+
error = data->cb(path, match, data->payload);
|
|
2542
2757
|
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2758
|
+
if (error > 0) /* skip this entry */
|
|
2759
|
+
return 0;
|
|
2760
|
+
if (error < 0) /* actual error */
|
|
2761
|
+
return error;
|
|
2546
2762
|
|
|
2547
|
-
|
|
2763
|
+
/* If the workdir item does not exist, remove it from the index. */
|
|
2764
|
+
if ((delta->new_file.flags & GIT_DIFF_FLAG_EXISTS) == 0)
|
|
2765
|
+
error = git_index_remove_bypath(data->index, path);
|
|
2766
|
+
else
|
|
2767
|
+
error = git_index_add_bypath(data->index, delta->new_file.path);
|
|
2548
2768
|
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2769
|
+
return error;
|
|
2770
|
+
}
|
|
2771
|
+
|
|
2772
|
+
static int index_apply_to_wd_diff(git_index *index, int action, const git_strarray *paths,
|
|
2773
|
+
unsigned int flags,
|
|
2774
|
+
git_index_matched_path_cb cb, void *payload)
|
|
2775
|
+
{
|
|
2776
|
+
int error;
|
|
2777
|
+
git_diff *diff;
|
|
2778
|
+
git_pathspec ps;
|
|
2779
|
+
git_repository *repo;
|
|
2780
|
+
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
|
|
2781
|
+
struct foreach_diff_data data = {
|
|
2782
|
+
index,
|
|
2783
|
+
NULL,
|
|
2784
|
+
flags,
|
|
2785
|
+
cb,
|
|
2786
|
+
payload,
|
|
2787
|
+
};
|
|
2788
|
+
|
|
2789
|
+
assert(index);
|
|
2790
|
+
assert(action == INDEX_ACTION_UPDATE || action == INDEX_ACTION_ADDALL);
|
|
2791
|
+
|
|
2792
|
+
repo = INDEX_OWNER(index);
|
|
2793
|
+
|
|
2794
|
+
if (!repo) {
|
|
2795
|
+
return create_index_error(-1,
|
|
2796
|
+
"cannot run update; the index is not backed up by a repository.");
|
|
2797
|
+
}
|
|
2798
|
+
|
|
2799
|
+
/*
|
|
2800
|
+
* We do the matching ourselves intead of passing the list to
|
|
2801
|
+
* diff because we want to tell the callback which one
|
|
2802
|
+
* matched, which we do not know if we ask diff to filter for us.
|
|
2803
|
+
*/
|
|
2804
|
+
if ((error = git_pathspec__init(&ps, paths)) < 0)
|
|
2805
|
+
return error;
|
|
2806
|
+
|
|
2807
|
+
opts.flags = GIT_DIFF_INCLUDE_TYPECHANGE;
|
|
2808
|
+
if (action == INDEX_ACTION_ADDALL) {
|
|
2809
|
+
opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED |
|
|
2810
|
+
GIT_DIFF_RECURSE_UNTRACKED_DIRS;
|
|
2811
|
+
|
|
2812
|
+
if (flags == GIT_INDEX_ADD_FORCE)
|
|
2813
|
+
opts.flags |= GIT_DIFF_INCLUDE_IGNORED;
|
|
2555
2814
|
}
|
|
2556
2815
|
|
|
2557
|
-
if (error
|
|
2558
|
-
|
|
2816
|
+
if ((error = git_diff_index_to_workdir(&diff, repo, index, &opts)) < 0)
|
|
2817
|
+
goto cleanup;
|
|
2818
|
+
|
|
2819
|
+
data.pathspec = &ps;
|
|
2820
|
+
error = git_diff_foreach(diff, apply_each_file, NULL, NULL, NULL, &data);
|
|
2821
|
+
git_diff_free(diff);
|
|
2822
|
+
|
|
2823
|
+
if (error) /* make sure error is set if callback stopped iteration */
|
|
2824
|
+
giterr_set_after_callback(error);
|
|
2559
2825
|
|
|
2560
2826
|
cleanup:
|
|
2561
|
-
git_iterator_free(wditer);
|
|
2562
2827
|
git_pathspec__clear(&ps);
|
|
2563
|
-
|
|
2564
2828
|
return error;
|
|
2565
2829
|
}
|
|
2566
2830
|
|
|
2567
|
-
enum {
|
|
2568
|
-
INDEX_ACTION_NONE = 0,
|
|
2569
|
-
INDEX_ACTION_UPDATE = 1,
|
|
2570
|
-
INDEX_ACTION_REMOVE = 2,
|
|
2571
|
-
};
|
|
2572
|
-
|
|
2573
2831
|
static int index_apply_to_all(
|
|
2574
2832
|
git_index *index,
|
|
2575
2833
|
int action,
|
|
@@ -2666,9 +2924,7 @@ int git_index_update_all(
|
|
|
2666
2924
|
git_index_matched_path_cb cb,
|
|
2667
2925
|
void *payload)
|
|
2668
2926
|
{
|
|
2669
|
-
int error =
|
|
2670
|
-
index, INDEX_ACTION_UPDATE, pathspec, cb, payload);
|
|
2671
|
-
|
|
2927
|
+
int error = index_apply_to_wd_diff(index, INDEX_ACTION_UPDATE, pathspec, 0, cb, payload);
|
|
2672
2928
|
if (error) /* make sure error is set if callback stopped iteration */
|
|
2673
2929
|
giterr_set_after_callback(error);
|
|
2674
2930
|
|
|
@@ -2769,6 +3025,7 @@ int git_indexwriter_init_for_operation(
|
|
|
2769
3025
|
int git_indexwriter_commit(git_indexwriter *writer)
|
|
2770
3026
|
{
|
|
2771
3027
|
int error;
|
|
3028
|
+
git_oid checksum = {{ 0 }};
|
|
2772
3029
|
|
|
2773
3030
|
if (!writer->should_write)
|
|
2774
3031
|
return 0;
|
|
@@ -2778,7 +3035,7 @@ int git_indexwriter_commit(git_indexwriter *writer)
|
|
|
2778
3035
|
|
|
2779
3036
|
git_vector_sort(&writer->index->reuc);
|
|
2780
3037
|
|
|
2781
|
-
if ((error = write_index(writer->index, &writer->file)) < 0) {
|
|
3038
|
+
if ((error = write_index(&checksum, writer->index, &writer->file)) < 0) {
|
|
2782
3039
|
git_indexwriter_cleanup(writer);
|
|
2783
3040
|
return error;
|
|
2784
3041
|
}
|
|
@@ -2793,6 +3050,7 @@ int git_indexwriter_commit(git_indexwriter *writer)
|
|
|
2793
3050
|
}
|
|
2794
3051
|
|
|
2795
3052
|
writer->index->on_disk = 1;
|
|
3053
|
+
git_oid_cpy(&writer->index->checksum, &checksum);
|
|
2796
3054
|
|
|
2797
3055
|
git_index_free(writer->index);
|
|
2798
3056
|
writer->index = NULL;
|