rugged 0.25.0b5 → 0.25.0b6
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_patch.c +77 -17
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +8 -6
- data/vendor/libgit2/include/git2/checkout.h +7 -0
- data/vendor/libgit2/include/git2/common.h +1 -0
- data/vendor/libgit2/include/git2/diff.h +54 -7
- data/vendor/libgit2/include/git2/errors.h +2 -1
- data/vendor/libgit2/include/git2/index.h +25 -0
- data/vendor/libgit2/include/git2/pack.h +4 -4
- data/vendor/libgit2/include/git2/repository.h +20 -1
- data/vendor/libgit2/include/git2/submodule.h +11 -3
- data/vendor/libgit2/include/git2/sys/odb_backend.h +11 -0
- data/vendor/libgit2/src/apply.c +369 -0
- data/vendor/libgit2/src/apply.h +21 -0
- data/vendor/libgit2/src/array.h +0 -1
- data/vendor/libgit2/src/blame_git.c +18 -8
- data/vendor/libgit2/src/buffer.c +252 -20
- data/vendor/libgit2/src/buffer.h +8 -0
- data/vendor/libgit2/src/checkout.c +7 -1
- data/vendor/libgit2/src/clone.c +0 -8
- data/vendor/libgit2/src/common.h +1 -1
- data/vendor/libgit2/src/crlf.c +1 -0
- data/vendor/libgit2/src/delta.c +238 -62
- data/vendor/libgit2/src/delta.h +79 -58
- data/vendor/libgit2/src/diff.c +32 -1547
- data/vendor/libgit2/src/diff.h +12 -122
- data/vendor/libgit2/src/diff_driver.c +1 -2
- data/vendor/libgit2/src/diff_file.c +3 -0
- data/vendor/libgit2/src/diff_generate.c +1611 -0
- data/vendor/libgit2/src/diff_generate.h +123 -0
- data/vendor/libgit2/src/diff_parse.c +105 -0
- data/vendor/libgit2/src/diff_print.c +259 -142
- data/vendor/libgit2/src/diff_stats.c +3 -2
- data/vendor/libgit2/src/diff_tform.c +1 -0
- data/vendor/libgit2/src/diff_tform.h +22 -0
- data/vendor/libgit2/src/diff_xdiff.c +9 -9
- data/vendor/libgit2/src/diff_xdiff.h +5 -5
- data/vendor/libgit2/src/fileops.c +13 -0
- data/vendor/libgit2/src/fileops.h +6 -0
- data/vendor/libgit2/src/global.c +9 -8
- data/vendor/libgit2/src/ignore.c +45 -16
- data/vendor/libgit2/src/index.c +161 -47
- data/vendor/libgit2/src/index.h +2 -0
- data/vendor/libgit2/src/merge.c +2 -0
- data/vendor/libgit2/src/mwindow.c +8 -19
- data/vendor/libgit2/src/mwindow.h +1 -2
- data/vendor/libgit2/src/odb.c +46 -10
- data/vendor/libgit2/src/odb_loose.c +19 -1
- data/vendor/libgit2/src/odb_pack.c +27 -4
- data/vendor/libgit2/src/pack-objects.c +106 -77
- data/vendor/libgit2/src/pack-objects.h +13 -12
- data/vendor/libgit2/src/pack.c +4 -3
- data/vendor/libgit2/src/pack.h +2 -0
- data/vendor/libgit2/src/patch.c +207 -0
- data/vendor/libgit2/src/patch.h +66 -0
- data/vendor/libgit2/src/{diff_patch.c → patch_generate.c} +171 -359
- data/vendor/libgit2/src/patch_generate.h +66 -0
- data/vendor/libgit2/src/patch_parse.c +1121 -0
- data/vendor/libgit2/src/patch_parse.h +54 -0
- data/vendor/libgit2/src/path.c +19 -0
- data/vendor/libgit2/src/path.h +6 -0
- data/vendor/libgit2/src/pool.h +5 -0
- data/vendor/libgit2/src/remote.c +15 -80
- data/vendor/libgit2/src/repository.c +227 -39
- data/vendor/libgit2/src/settings.c +11 -5
- data/vendor/libgit2/src/stash.c +1 -0
- data/vendor/libgit2/src/status.c +1 -0
- data/vendor/libgit2/src/stransport_stream.c +14 -9
- data/vendor/libgit2/src/submodule.c +16 -4
- data/vendor/libgit2/src/sysdir.c +41 -47
- data/vendor/libgit2/src/sysdir.h +0 -5
- data/vendor/libgit2/src/thread-utils.h +5 -51
- data/vendor/libgit2/src/transport.c +3 -5
- data/vendor/libgit2/src/transports/http.c +2 -3
- data/vendor/libgit2/src/transports/smart_pkt.c +1 -0
- data/vendor/libgit2/src/transports/smart_protocol.c +11 -0
- data/vendor/libgit2/src/transports/winhttp.c +16 -2
- data/vendor/libgit2/src/unix/pthread.h +54 -0
- data/vendor/libgit2/src/util.c +23 -5
- data/vendor/libgit2/src/util.h +10 -0
- data/vendor/libgit2/src/varint.c +44 -0
- data/vendor/libgit2/src/varint.h +15 -0
- data/vendor/libgit2/src/vector.c +42 -0
- data/vendor/libgit2/src/vector.h +3 -0
- data/vendor/libgit2/src/win32/precompiled.h +1 -1
- data/vendor/libgit2/src/win32/{pthread.c → thread.c} +50 -80
- data/vendor/libgit2/src/win32/thread.h +62 -0
- data/vendor/libgit2/src/zstream.c +36 -7
- data/vendor/libgit2/src/zstream.h +8 -1
- metadata +20 -9
- data/vendor/libgit2/src/delta-apply.c +0 -166
- data/vendor/libgit2/src/delta-apply.h +0 -62
- data/vendor/libgit2/src/diff_patch.h +0 -83
- data/vendor/libgit2/src/win32/pthread.h +0 -92
data/vendor/libgit2/src/index.h
CHANGED
data/vendor/libgit2/src/merge.c
CHANGED
@@ -33,25 +33,20 @@ static git_mwindow_ctl mem_ctl;
|
|
33
33
|
/* Global list of mwindow files, to open packs once across repos */
|
34
34
|
git_strmap *git__pack_cache = NULL;
|
35
35
|
|
36
|
-
|
37
|
-
* Run under mwindow lock
|
38
|
-
*/
|
39
|
-
int git_mwindow_files_init(void)
|
36
|
+
static void git_mwindow_files_free(void)
|
40
37
|
{
|
41
|
-
|
42
|
-
return 0;
|
43
|
-
|
44
|
-
git__on_shutdown(git_mwindow_files_free);
|
38
|
+
git_strmap *tmp = git__pack_cache;
|
45
39
|
|
46
|
-
|
40
|
+
git__pack_cache = NULL;
|
41
|
+
git_strmap_free(tmp);
|
47
42
|
}
|
48
43
|
|
49
|
-
|
44
|
+
int git_mwindow_global_init(void)
|
50
45
|
{
|
51
|
-
|
46
|
+
assert(!git__pack_cache);
|
52
47
|
|
53
|
-
|
54
|
-
|
48
|
+
git__on_shutdown(git_mwindow_files_free);
|
49
|
+
return git_strmap_alloc(&git__pack_cache);
|
55
50
|
}
|
56
51
|
|
57
52
|
int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
|
@@ -69,12 +64,6 @@ int git_mwindow_get_pack(struct git_pack_file **out, const char *path)
|
|
69
64
|
return -1;
|
70
65
|
}
|
71
66
|
|
72
|
-
if (git_mwindow_files_init() < 0) {
|
73
|
-
git_mutex_unlock(&git__mwindow_mutex);
|
74
|
-
git__free(packname);
|
75
|
-
return -1;
|
76
|
-
}
|
77
|
-
|
78
67
|
pos = git_strmap_lookup_index(git__pack_cache, packname);
|
79
68
|
git__free(packname);
|
80
69
|
|
@@ -43,8 +43,7 @@ int git_mwindow_file_register(git_mwindow_file *mwf);
|
|
43
43
|
void git_mwindow_file_deregister(git_mwindow_file *mwf);
|
44
44
|
void git_mwindow_close(git_mwindow **w_cursor);
|
45
45
|
|
46
|
-
int
|
47
|
-
void git_mwindow_files_free(void);
|
46
|
+
extern int git_mwindow_global_init(void);
|
48
47
|
|
49
48
|
struct git_pack_file; /* just declaration to avoid cyclical includes */
|
50
49
|
int git_mwindow_get_pack(struct git_pack_file **out, const char *path);
|
data/vendor/libgit2/src/odb.c
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
#include "fileops.h"
|
13
13
|
#include "hash.h"
|
14
14
|
#include "odb.h"
|
15
|
-
#include "delta
|
15
|
+
#include "delta.h"
|
16
16
|
#include "filter.h"
|
17
17
|
#include "repository.h"
|
18
18
|
|
@@ -54,14 +54,9 @@ static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_
|
|
54
54
|
|
55
55
|
static git_otype odb_hardcoded_type(const git_oid *id)
|
56
56
|
{
|
57
|
-
static git_oid empty_blob = {{ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b,
|
58
|
-
0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 }};
|
59
57
|
static git_oid empty_tree = {{ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
|
60
58
|
0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 }};
|
61
59
|
|
62
|
-
if (!git_oid_cmp(id, &empty_blob))
|
63
|
-
return GIT_OBJ_BLOB;
|
64
|
-
|
65
60
|
if (!git_oid_cmp(id, &empty_tree))
|
66
61
|
return GIT_OBJ_TREE;
|
67
62
|
|
@@ -654,7 +649,10 @@ void git_odb_free(git_odb *db)
|
|
654
649
|
GIT_REFCOUNT_DEC(db, odb_free);
|
655
650
|
}
|
656
651
|
|
657
|
-
static int odb_exists_1(
|
652
|
+
static int odb_exists_1(
|
653
|
+
git_odb *db,
|
654
|
+
const git_oid *id,
|
655
|
+
bool only_refreshed)
|
658
656
|
{
|
659
657
|
size_t i;
|
660
658
|
bool found = false;
|
@@ -673,6 +671,44 @@ static int odb_exists_1(git_odb *db, const git_oid *id, bool only_refreshed)
|
|
673
671
|
return (int)found;
|
674
672
|
}
|
675
673
|
|
674
|
+
static int odb_freshen_1(
|
675
|
+
git_odb *db,
|
676
|
+
const git_oid *id,
|
677
|
+
bool only_refreshed)
|
678
|
+
{
|
679
|
+
size_t i;
|
680
|
+
bool found = false;
|
681
|
+
|
682
|
+
for (i = 0; i < db->backends.length && !found; ++i) {
|
683
|
+
backend_internal *internal = git_vector_get(&db->backends, i);
|
684
|
+
git_odb_backend *b = internal->backend;
|
685
|
+
|
686
|
+
if (only_refreshed && !b->refresh)
|
687
|
+
continue;
|
688
|
+
|
689
|
+
if (b->freshen != NULL)
|
690
|
+
found = !b->freshen(b, id);
|
691
|
+
else if (b->exists != NULL)
|
692
|
+
found = b->exists(b, id);
|
693
|
+
}
|
694
|
+
|
695
|
+
return (int)found;
|
696
|
+
}
|
697
|
+
|
698
|
+
static int odb_freshen(git_odb *db, const git_oid *id)
|
699
|
+
{
|
700
|
+
assert(db && id);
|
701
|
+
|
702
|
+
if (odb_freshen_1(db, id, false))
|
703
|
+
return 1;
|
704
|
+
|
705
|
+
if (!git_odb_refresh(db))
|
706
|
+
return odb_freshen_1(db, id, true);
|
707
|
+
|
708
|
+
/* Failed to refresh, hence not found */
|
709
|
+
return 0;
|
710
|
+
}
|
711
|
+
|
676
712
|
int git_odb_exists(git_odb *db, const git_oid *id)
|
677
713
|
{
|
678
714
|
git_odb_object *object;
|
@@ -1131,7 +1167,7 @@ int git_odb_write(
|
|
1131
1167
|
assert(oid && db);
|
1132
1168
|
|
1133
1169
|
git_odb_hash(oid, data, len, type);
|
1134
|
-
if (
|
1170
|
+
if (odb_freshen(db, oid))
|
1135
1171
|
return 0;
|
1136
1172
|
|
1137
1173
|
for (i = 0; i < db->backends.length && error < 0; ++i) {
|
@@ -1257,7 +1293,7 @@ int git_odb_stream_finalize_write(git_oid *out, git_odb_stream *stream)
|
|
1257
1293
|
|
1258
1294
|
git_hash_final(out, stream->hash_ctx);
|
1259
1295
|
|
1260
|
-
if (
|
1296
|
+
if (odb_freshen(stream->backend->odb, out))
|
1261
1297
|
return 0;
|
1262
1298
|
|
1263
1299
|
return stream->finalize_write(stream, out);
|
@@ -1362,7 +1398,7 @@ int git_odb__error_notfound(
|
|
1362
1398
|
{
|
1363
1399
|
if (oid != NULL) {
|
1364
1400
|
char oid_str[GIT_OID_HEXSZ + 1];
|
1365
|
-
git_oid_tostr(oid_str, oid_len, oid);
|
1401
|
+
git_oid_tostr(oid_str, oid_len+1, oid);
|
1366
1402
|
giterr_set(GITERR_ODB, "Object not found - %s (%.*s)",
|
1367
1403
|
message, oid_len, oid_str);
|
1368
1404
|
} else
|
@@ -12,7 +12,7 @@
|
|
12
12
|
#include "fileops.h"
|
13
13
|
#include "hash.h"
|
14
14
|
#include "odb.h"
|
15
|
-
#include "delta
|
15
|
+
#include "delta.h"
|
16
16
|
#include "filebuf.h"
|
17
17
|
|
18
18
|
#include "git2/odb_backend.h"
|
@@ -918,6 +918,23 @@ cleanup:
|
|
918
918
|
return error;
|
919
919
|
}
|
920
920
|
|
921
|
+
static int loose_backend__freshen(
|
922
|
+
git_odb_backend *_backend,
|
923
|
+
const git_oid *oid)
|
924
|
+
{
|
925
|
+
loose_backend *backend = (loose_backend *)_backend;
|
926
|
+
git_buf path = GIT_BUF_INIT;
|
927
|
+
int error;
|
928
|
+
|
929
|
+
if (object_file_name(&path, backend, oid) < 0)
|
930
|
+
return -1;
|
931
|
+
|
932
|
+
error = git_futils_touch(path.ptr, NULL);
|
933
|
+
git_buf_free(&path);
|
934
|
+
|
935
|
+
return error;
|
936
|
+
}
|
937
|
+
|
921
938
|
static void loose_backend__free(git_odb_backend *_backend)
|
922
939
|
{
|
923
940
|
loose_backend *backend;
|
@@ -975,6 +992,7 @@ int git_odb_backend_loose(
|
|
975
992
|
backend->parent.exists = &loose_backend__exists;
|
976
993
|
backend->parent.exists_prefix = &loose_backend__exists_prefix;
|
977
994
|
backend->parent.foreach = &loose_backend__foreach;
|
995
|
+
backend->parent.freshen = &loose_backend__freshen;
|
978
996
|
backend->parent.free = &loose_backend__free;
|
979
997
|
|
980
998
|
*backend_out = (git_odb_backend *)backend;
|
@@ -13,13 +13,16 @@
|
|
13
13
|
#include "fileops.h"
|
14
14
|
#include "hash.h"
|
15
15
|
#include "odb.h"
|
16
|
-
#include "delta
|
16
|
+
#include "delta.h"
|
17
17
|
#include "sha1_lookup.h"
|
18
18
|
#include "mwindow.h"
|
19
19
|
#include "pack.h"
|
20
20
|
|
21
21
|
#include "git2/odb_backend.h"
|
22
22
|
|
23
|
+
/* re-freshen pack files no more than every 2 seconds */
|
24
|
+
#define FRESHEN_FREQUENCY 2
|
25
|
+
|
23
26
|
struct pack_backend {
|
24
27
|
git_odb_backend parent;
|
25
28
|
git_vector packs;
|
@@ -363,6 +366,28 @@ static int pack_backend__read_header(
|
|
363
366
|
return git_packfile_resolve_header(len_p, type_p, e.p, e.offset);
|
364
367
|
}
|
365
368
|
|
369
|
+
static int pack_backend__freshen(
|
370
|
+
git_odb_backend *backend, const git_oid *oid)
|
371
|
+
{
|
372
|
+
struct git_pack_entry e;
|
373
|
+
time_t now;
|
374
|
+
int error;
|
375
|
+
|
376
|
+
if ((error = pack_entry_find(&e, (struct pack_backend *)backend, oid)) < 0)
|
377
|
+
return error;
|
378
|
+
|
379
|
+
now = time(NULL);
|
380
|
+
|
381
|
+
if (e.p->last_freshen > now - FRESHEN_FREQUENCY)
|
382
|
+
return 0;
|
383
|
+
|
384
|
+
if ((error = git_futils_touch(e.p->pack_name, &now)) < 0)
|
385
|
+
return error;
|
386
|
+
|
387
|
+
e.p->last_freshen = now;
|
388
|
+
return 0;
|
389
|
+
}
|
390
|
+
|
366
391
|
static int pack_backend__read(
|
367
392
|
void **buffer_p, size_t *len_p, git_otype *type_p,
|
368
393
|
git_odb_backend *backend, const git_oid *oid)
|
@@ -560,6 +585,7 @@ static int pack_backend__alloc(struct pack_backend **out, size_t initial_size)
|
|
560
585
|
backend->parent.refresh = &pack_backend__refresh;
|
561
586
|
backend->parent.foreach = &pack_backend__foreach;
|
562
587
|
backend->parent.writepack = &pack_backend__writepack;
|
588
|
+
backend->parent.freshen = &pack_backend__freshen;
|
563
589
|
backend->parent.free = &pack_backend__free;
|
564
590
|
|
565
591
|
*out = backend;
|
@@ -591,9 +617,6 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
|
|
591
617
|
struct pack_backend *backend = NULL;
|
592
618
|
git_buf path = GIT_BUF_INIT;
|
593
619
|
|
594
|
-
if (git_mwindow_files_init() < 0)
|
595
|
-
return -1;
|
596
|
-
|
597
620
|
if (pack_backend__alloc(&backend, 8) < 0)
|
598
621
|
return -1;
|
599
622
|
|
@@ -28,7 +28,7 @@ struct unpacked {
|
|
28
28
|
git_pobject *object;
|
29
29
|
void *data;
|
30
30
|
struct git_delta_index *index;
|
31
|
-
|
31
|
+
size_t depth;
|
32
32
|
};
|
33
33
|
|
34
34
|
struct tree_walk_context {
|
@@ -99,8 +99,15 @@ static int packbuilder_config(git_packbuilder *pb)
|
|
99
99
|
|
100
100
|
#define config_get(KEY,DST,DFLT) do { \
|
101
101
|
ret = git_config_get_int64(&val, config, KEY); \
|
102
|
-
if (!ret)
|
103
|
-
|
102
|
+
if (!ret) { \
|
103
|
+
if (!git__is_sizet(val)) { \
|
104
|
+
giterr_set(GITERR_CONFIG, \
|
105
|
+
"configuration value '%s' is too large", KEY); \
|
106
|
+
ret = -1; \
|
107
|
+
goto out; \
|
108
|
+
} \
|
109
|
+
(DST) = (size_t)val; \
|
110
|
+
} else if (ret == GIT_ENOTFOUND) { \
|
104
111
|
(DST) = (DFLT); \
|
105
112
|
ret = 0; \
|
106
113
|
} else if (ret < 0) goto out; } while (0)
|
@@ -144,7 +151,7 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
|
|
144
151
|
pb->nr_threads = 1; /* do not spawn any thread by default */
|
145
152
|
|
146
153
|
if (git_hash_ctx_init(&pb->ctx) < 0 ||
|
147
|
-
git_zstream_init(&pb->zstream) < 0 ||
|
154
|
+
git_zstream_init(&pb->zstream, GIT_ZSTREAM_DEFLATE) < 0 ||
|
148
155
|
git_repository_odb(&pb->odb, repo) < 0 ||
|
149
156
|
packbuilder_config(pb) < 0)
|
150
157
|
goto on_error;
|
@@ -187,7 +194,7 @@ static void rehash(git_packbuilder *pb)
|
|
187
194
|
{
|
188
195
|
git_pobject *po;
|
189
196
|
khiter_t pos;
|
190
|
-
|
197
|
+
size_t i;
|
191
198
|
int ret;
|
192
199
|
|
193
200
|
kh_clear(oid, pb->object_ix);
|
@@ -222,7 +229,7 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
|
|
222
229
|
return -1;
|
223
230
|
}
|
224
231
|
|
225
|
-
pb->nr_alloc =
|
232
|
+
pb->nr_alloc = newsize;
|
226
233
|
|
227
234
|
pb->object_list = git__reallocarray(pb->object_list,
|
228
235
|
pb->nr_alloc, sizeof(*po));
|
@@ -272,8 +279,9 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
|
|
272
279
|
static int get_delta(void **out, git_odb *odb, git_pobject *po)
|
273
280
|
{
|
274
281
|
git_odb_object *src = NULL, *trg = NULL;
|
275
|
-
|
282
|
+
size_t delta_size;
|
276
283
|
void *delta_buf;
|
284
|
+
int error;
|
277
285
|
|
278
286
|
*out = NULL;
|
279
287
|
|
@@ -281,12 +289,15 @@ static int get_delta(void **out, git_odb *odb, git_pobject *po)
|
|
281
289
|
git_odb_read(&trg, odb, &po->id) < 0)
|
282
290
|
goto on_error;
|
283
291
|
|
284
|
-
|
285
|
-
git_odb_object_data(src),
|
286
|
-
git_odb_object_data(trg),
|
287
|
-
|
292
|
+
error = git_delta(&delta_buf, &delta_size,
|
293
|
+
git_odb_object_data(src), git_odb_object_size(src),
|
294
|
+
git_odb_object_data(trg), git_odb_object_size(trg),
|
295
|
+
0);
|
288
296
|
|
289
|
-
if (
|
297
|
+
if (error < 0 && error != GIT_EBUFS)
|
298
|
+
goto on_error;
|
299
|
+
|
300
|
+
if (error == GIT_EBUFS || delta_size != po->delta_size) {
|
290
301
|
giterr_set(GITERR_INVALID, "Delta size changed");
|
291
302
|
goto on_error;
|
292
303
|
}
|
@@ -437,8 +448,8 @@ static int write_one(
|
|
437
448
|
return write_object(pb, po, write_cb, cb_data);
|
438
449
|
}
|
439
450
|
|
440
|
-
GIT_INLINE(void) add_to_write_order(git_pobject **wo,
|
441
|
-
|
451
|
+
GIT_INLINE(void) add_to_write_order(git_pobject **wo, size_t *endp,
|
452
|
+
git_pobject *po)
|
442
453
|
{
|
443
454
|
if (po->filled)
|
444
455
|
return;
|
@@ -446,8 +457,8 @@ GIT_INLINE(void) add_to_write_order(git_pobject **wo, unsigned int *endp,
|
|
446
457
|
po->filled = 1;
|
447
458
|
}
|
448
459
|
|
449
|
-
static void add_descendants_to_write_order(git_pobject **wo,
|
450
|
-
|
460
|
+
static void add_descendants_to_write_order(git_pobject **wo, size_t *endp,
|
461
|
+
git_pobject *po)
|
451
462
|
{
|
452
463
|
int add_to_order = 1;
|
453
464
|
while (po) {
|
@@ -488,8 +499,8 @@ static void add_descendants_to_write_order(git_pobject **wo, unsigned int *endp,
|
|
488
499
|
};
|
489
500
|
}
|
490
501
|
|
491
|
-
static void add_family_to_write_order(git_pobject **wo,
|
492
|
-
|
502
|
+
static void add_family_to_write_order(git_pobject **wo, size_t *endp,
|
503
|
+
git_pobject *po)
|
493
504
|
{
|
494
505
|
git_pobject *root;
|
495
506
|
|
@@ -520,7 +531,7 @@ static int cb_tag_foreach(const char *name, git_oid *oid, void *data)
|
|
520
531
|
|
521
532
|
static git_pobject **compute_write_order(git_packbuilder *pb)
|
522
533
|
{
|
523
|
-
|
534
|
+
size_t i, wo_end, last_untagged;
|
524
535
|
git_pobject **wo;
|
525
536
|
|
526
537
|
if ((wo = git__mallocarray(pb->nr_objects, sizeof(*wo))) == NULL)
|
@@ -625,13 +636,18 @@ static int write_pack(git_packbuilder *pb,
|
|
625
636
|
enum write_one_status status;
|
626
637
|
struct git_pack_header ph;
|
627
638
|
git_oid entry_oid;
|
628
|
-
|
639
|
+
size_t i = 0;
|
629
640
|
int error = 0;
|
630
641
|
|
631
642
|
write_order = compute_write_order(pb);
|
632
643
|
if (write_order == NULL)
|
633
644
|
return -1;
|
634
645
|
|
646
|
+
if (!git__is_uint32(pb->nr_objects)) {
|
647
|
+
giterr_set(GITERR_INVALID, "too many objects");
|
648
|
+
return -1;
|
649
|
+
}
|
650
|
+
|
635
651
|
/* Write pack header */
|
636
652
|
ph.hdr_signature = htonl(PACK_SIGNATURE);
|
637
653
|
ph.hdr_version = htonl(PACK_VERSION);
|
@@ -707,11 +723,18 @@ static int type_size_sort(const void *_a, const void *_b)
|
|
707
723
|
return a < b ? -1 : (a > b); /* newest first */
|
708
724
|
}
|
709
725
|
|
710
|
-
static int delta_cacheable(
|
711
|
-
|
726
|
+
static int delta_cacheable(
|
727
|
+
git_packbuilder *pb,
|
728
|
+
size_t src_size,
|
729
|
+
size_t trg_size,
|
730
|
+
size_t delta_size)
|
712
731
|
{
|
713
|
-
|
714
|
-
|
732
|
+
size_t new_size;
|
733
|
+
|
734
|
+
if (git__add_sizet_overflow(&new_size, pb->delta_cache_size, delta_size))
|
735
|
+
return 0;
|
736
|
+
|
737
|
+
if (pb->max_delta_cache_size && new_size > pb->max_delta_cache_size)
|
715
738
|
return 0;
|
716
739
|
|
717
740
|
if (delta_size < pb->cache_max_small_delta_size)
|
@@ -725,15 +748,14 @@ static int delta_cacheable(git_packbuilder *pb, unsigned long src_size,
|
|
725
748
|
}
|
726
749
|
|
727
750
|
static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
728
|
-
struct unpacked *src,
|
729
|
-
|
751
|
+
struct unpacked *src, size_t max_depth,
|
752
|
+
size_t *mem_usage, int *ret)
|
730
753
|
{
|
731
754
|
git_pobject *trg_object = trg->object;
|
732
755
|
git_pobject *src_object = src->object;
|
733
756
|
git_odb_object *obj;
|
734
|
-
|
735
|
-
|
736
|
-
unsigned int ref_depth;
|
757
|
+
size_t trg_size, src_size, delta_size, sizediff, max_size, sz;
|
758
|
+
size_t ref_depth;
|
737
759
|
void *delta_buf;
|
738
760
|
|
739
761
|
/* Don't bother doing diffs between different types */
|
@@ -751,7 +773,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
751
773
|
return 0;
|
752
774
|
|
753
775
|
/* Now some size filtering heuristics. */
|
754
|
-
trg_size =
|
776
|
+
trg_size = trg_object->size;
|
755
777
|
if (!trg_object->delta) {
|
756
778
|
max_size = trg_size/2 - 20;
|
757
779
|
ref_depth = 1;
|
@@ -765,7 +787,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
765
787
|
if (max_size == 0)
|
766
788
|
return 0;
|
767
789
|
|
768
|
-
src_size =
|
790
|
+
src_size = src_object->size;
|
769
791
|
sizediff = src_size < trg_size ? trg_size - src_size : 0;
|
770
792
|
if (sizediff >= max_size)
|
771
793
|
return 0;
|
@@ -777,7 +799,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
777
799
|
if (git_odb_read(&obj, pb->odb, &trg_object->id) < 0)
|
778
800
|
return -1;
|
779
801
|
|
780
|
-
sz =
|
802
|
+
sz = git_odb_object_size(obj);
|
781
803
|
trg->data = git__malloc(sz);
|
782
804
|
GITERR_CHECK_ALLOC(trg->data);
|
783
805
|
memcpy(trg->data, git_odb_object_data(obj), sz);
|
@@ -799,7 +821,7 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
799
821
|
!git__is_ulong(obj_sz = git_odb_object_size(obj)))
|
800
822
|
return -1;
|
801
823
|
|
802
|
-
sz =
|
824
|
+
sz = obj_sz;
|
803
825
|
src->data = git__malloc(sz);
|
804
826
|
GITERR_CHECK_ALLOC(src->data);
|
805
827
|
memcpy(src->data, git_odb_object_data(obj), sz);
|
@@ -815,16 +837,14 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
815
837
|
*mem_usage += sz;
|
816
838
|
}
|
817
839
|
if (!src->index) {
|
818
|
-
src->index
|
819
|
-
if (!src->index)
|
840
|
+
if (git_delta_index_init(&src->index, src->data, src_size) < 0)
|
820
841
|
return 0; /* suboptimal pack - out of memory */
|
821
842
|
|
822
|
-
*mem_usage +=
|
843
|
+
*mem_usage += git_delta_index_size(src->index);
|
823
844
|
}
|
824
845
|
|
825
|
-
delta_buf
|
826
|
-
|
827
|
-
if (!delta_buf)
|
846
|
+
if (git_delta_create_from_index(&delta_buf, &delta_size, src->index, trg->data, trg_size,
|
847
|
+
max_size) < 0)
|
828
848
|
return 0;
|
829
849
|
|
830
850
|
if (trg_object->delta) {
|
@@ -839,11 +859,12 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
839
859
|
git_packbuilder__cache_lock(pb);
|
840
860
|
if (trg_object->delta_data) {
|
841
861
|
git__free(trg_object->delta_data);
|
862
|
+
assert(pb->delta_cache_size >= trg_object->delta_size);
|
842
863
|
pb->delta_cache_size -= trg_object->delta_size;
|
843
864
|
trg_object->delta_data = NULL;
|
844
865
|
}
|
845
866
|
if (delta_cacheable(pb, src_size, trg_size, delta_size)) {
|
846
|
-
bool overflow =
|
867
|
+
bool overflow = git__add_sizet_overflow(
|
847
868
|
&pb->delta_cache_size, pb->delta_cache_size, delta_size);
|
848
869
|
|
849
870
|
git_packbuilder__cache_unlock(pb);
|
@@ -869,13 +890,13 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
869
890
|
return 0;
|
870
891
|
}
|
871
892
|
|
872
|
-
static
|
893
|
+
static size_t check_delta_limit(git_pobject *me, size_t n)
|
873
894
|
{
|
874
895
|
git_pobject *child = me->delta_child;
|
875
|
-
|
896
|
+
size_t m = n;
|
876
897
|
|
877
898
|
while (child) {
|
878
|
-
|
899
|
+
size_t c = check_delta_limit(child, n + 1);
|
879
900
|
if (m < c)
|
880
901
|
m = c;
|
881
902
|
child = child->delta_sibling;
|
@@ -883,13 +904,18 @@ static unsigned int check_delta_limit(git_pobject *me, unsigned int n)
|
|
883
904
|
return m;
|
884
905
|
}
|
885
906
|
|
886
|
-
static
|
907
|
+
static size_t free_unpacked(struct unpacked *n)
|
887
908
|
{
|
888
|
-
|
889
|
-
|
909
|
+
size_t freed_mem = 0;
|
910
|
+
|
911
|
+
if (n->index) {
|
912
|
+
freed_mem += git_delta_index_size(n->index);
|
913
|
+
git_delta_index_free(n->index);
|
914
|
+
}
|
890
915
|
n->index = NULL;
|
916
|
+
|
891
917
|
if (n->data) {
|
892
|
-
freed_mem +=
|
918
|
+
freed_mem += n->object->size;
|
893
919
|
git__free(n->data);
|
894
920
|
n->data = NULL;
|
895
921
|
}
|
@@ -898,7 +924,8 @@ static unsigned long free_unpacked(struct unpacked *n)
|
|
898
924
|
return freed_mem;
|
899
925
|
}
|
900
926
|
|
901
|
-
static int report_delta_progress(
|
927
|
+
static int report_delta_progress(
|
928
|
+
git_packbuilder *pb, uint32_t count, bool force)
|
902
929
|
{
|
903
930
|
int ret;
|
904
931
|
|
@@ -922,15 +949,14 @@ static int report_delta_progress(git_packbuilder *pb, uint32_t count, bool force
|
|
922
949
|
}
|
923
950
|
|
924
951
|
static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
925
|
-
|
926
|
-
int depth)
|
952
|
+
size_t *list_size, size_t window, size_t depth)
|
927
953
|
{
|
928
954
|
git_pobject *po;
|
929
955
|
git_buf zbuf = GIT_BUF_INIT;
|
930
956
|
struct unpacked *array;
|
931
|
-
|
932
|
-
|
933
|
-
|
957
|
+
size_t idx = 0, count = 0;
|
958
|
+
size_t mem_usage = 0;
|
959
|
+
size_t i;
|
934
960
|
int error = -1;
|
935
961
|
|
936
962
|
array = git__calloc(window, sizeof(struct unpacked));
|
@@ -938,7 +964,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
938
964
|
|
939
965
|
for (;;) {
|
940
966
|
struct unpacked *n = array + idx;
|
941
|
-
|
967
|
+
size_t max_depth, j, best_base = SIZE_MAX;
|
942
968
|
|
943
969
|
git_packbuilder__progress_lock(pb);
|
944
970
|
if (!*list_size) {
|
@@ -959,7 +985,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
959
985
|
while (pb->window_memory_limit &&
|
960
986
|
mem_usage > pb->window_memory_limit &&
|
961
987
|
count > 1) {
|
962
|
-
|
988
|
+
size_t tail = (idx + window - count) % window;
|
963
989
|
mem_usage -= free_unpacked(array + tail);
|
964
990
|
count--;
|
965
991
|
}
|
@@ -971,15 +997,18 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
971
997
|
*/
|
972
998
|
max_depth = depth;
|
973
999
|
if (po->delta_child) {
|
974
|
-
|
975
|
-
|
1000
|
+
size_t delta_limit = check_delta_limit(po, 0);
|
1001
|
+
|
1002
|
+
if (delta_limit > max_depth)
|
976
1003
|
goto next;
|
1004
|
+
|
1005
|
+
max_depth -= delta_limit;
|
977
1006
|
}
|
978
1007
|
|
979
1008
|
j = window;
|
980
1009
|
while (--j > 0) {
|
981
1010
|
int ret;
|
982
|
-
|
1011
|
+
size_t other_idx = idx + j;
|
983
1012
|
struct unpacked *m;
|
984
1013
|
|
985
1014
|
if (other_idx >= window)
|
@@ -1020,7 +1049,7 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
1020
1049
|
GITERR_CHECK_ALLOC(po->delta_data);
|
1021
1050
|
|
1022
1051
|
memcpy(po->delta_data, zbuf.ptr, zbuf.size);
|
1023
|
-
po->z_delta_size =
|
1052
|
+
po->z_delta_size = zbuf.size;
|
1024
1053
|
git_buf_clear(&zbuf);
|
1025
1054
|
|
1026
1055
|
git_packbuilder__cache_lock(pb);
|
@@ -1044,10 +1073,10 @@ static int find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
1044
1073
|
*/
|
1045
1074
|
if (po->delta) {
|
1046
1075
|
struct unpacked swap = array[best_base];
|
1047
|
-
|
1048
|
-
|
1076
|
+
size_t dist = (window + idx - best_base) % window;
|
1077
|
+
size_t dst = best_base;
|
1049
1078
|
while (dist--) {
|
1050
|
-
|
1079
|
+
size_t src = (dst + 1) % window;
|
1051
1080
|
array[dst] = array[src];
|
1052
1081
|
dst = src;
|
1053
1082
|
}
|
@@ -1085,13 +1114,13 @@ struct thread_params {
|
|
1085
1114
|
git_cond cond;
|
1086
1115
|
git_mutex mutex;
|
1087
1116
|
|
1088
|
-
|
1089
|
-
|
1117
|
+
size_t list_size;
|
1118
|
+
size_t remaining;
|
1090
1119
|
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1120
|
+
size_t window;
|
1121
|
+
size_t depth;
|
1122
|
+
size_t working;
|
1123
|
+
size_t data_ready;
|
1095
1124
|
};
|
1096
1125
|
|
1097
1126
|
static void *threaded_find_deltas(void *arg)
|
@@ -1133,11 +1162,11 @@ static void *threaded_find_deltas(void *arg)
|
|
1133
1162
|
}
|
1134
1163
|
|
1135
1164
|
static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
1136
|
-
|
1137
|
-
int depth)
|
1165
|
+
size_t list_size, size_t window, size_t depth)
|
1138
1166
|
{
|
1139
1167
|
struct thread_params *p;
|
1140
|
-
|
1168
|
+
size_t i;
|
1169
|
+
int ret, active_threads = 0;
|
1141
1170
|
|
1142
1171
|
if (!pb->nr_threads)
|
1143
1172
|
pb->nr_threads = git_online_cpus();
|
@@ -1152,7 +1181,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
1152
1181
|
|
1153
1182
|
/* Partition the work among the threads */
|
1154
1183
|
for (i = 0; i < pb->nr_threads; ++i) {
|
1155
|
-
|
1184
|
+
size_t sub_size = list_size / (pb->nr_threads - i);
|
1156
1185
|
|
1157
1186
|
/* don't use too small segments or no deltas will be found */
|
1158
1187
|
if (sub_size < 2*window && i+1 < pb->nr_threads)
|
@@ -1186,7 +1215,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
1186
1215
|
git_mutex_init(&p[i].mutex);
|
1187
1216
|
git_cond_init(&p[i].cond);
|
1188
1217
|
|
1189
|
-
ret = git_thread_create(&p[i].thread,
|
1218
|
+
ret = git_thread_create(&p[i].thread,
|
1190
1219
|
threaded_find_deltas, &p[i]);
|
1191
1220
|
if (ret) {
|
1192
1221
|
giterr_set(GITERR_THREAD, "unable to create thread");
|
@@ -1206,7 +1235,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
1206
1235
|
while (active_threads) {
|
1207
1236
|
struct thread_params *target = NULL;
|
1208
1237
|
struct thread_params *victim = NULL;
|
1209
|
-
|
1238
|
+
size_t sub_size = 0;
|
1210
1239
|
|
1211
1240
|
/* Start by locating a thread that has transitioned its
|
1212
1241
|
* 'working' flag from 1 -> 0. This indicates that it is
|
@@ -1286,7 +1315,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
1286
1315
|
static int prepare_pack(git_packbuilder *pb)
|
1287
1316
|
{
|
1288
1317
|
git_pobject **delta_list;
|
1289
|
-
|
1318
|
+
size_t i, n = 0;
|
1290
1319
|
|
1291
1320
|
if (pb->nr_objects == 0 || pb->done)
|
1292
1321
|
return 0; /* nothing to do */
|
@@ -1473,12 +1502,12 @@ cleanup:
|
|
1473
1502
|
return error;
|
1474
1503
|
}
|
1475
1504
|
|
1476
|
-
|
1505
|
+
size_t git_packbuilder_object_count(git_packbuilder *pb)
|
1477
1506
|
{
|
1478
1507
|
return pb->nr_objects;
|
1479
1508
|
}
|
1480
1509
|
|
1481
|
-
|
1510
|
+
size_t git_packbuilder_written(git_packbuilder *pb)
|
1482
1511
|
{
|
1483
1512
|
return pb->nr_written;
|
1484
1513
|
}
|