rugged 0.22.2 → 0.23.0b1
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.c +1 -2
- data/ext/rugged/rugged_branch_collection.c +6 -44
- data/ext/rugged/rugged_config.c +7 -3
- data/ext/rugged/rugged_diff_delta.c +1 -1
- data/ext/rugged/rugged_diff_line.c +1 -1
- data/ext/rugged/rugged_object.c +2 -2
- data/ext/rugged/rugged_reference_collection.c +12 -56
- data/ext/rugged/rugged_remote.c +4 -33
- data/ext/rugged/rugged_remote_collection.c +1 -1
- data/ext/rugged/rugged_repo.c +10 -36
- data/ext/rugged/rugged_settings.c +3 -3
- data/ext/rugged/rugged_tree.c +1 -1
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +10 -3
- data/vendor/libgit2/COPYING +15 -21
- data/vendor/libgit2/include/git2/annotated_commit.h +20 -3
- data/vendor/libgit2/include/git2/branch.h +20 -16
- data/vendor/libgit2/include/git2/checkout.h +32 -18
- data/vendor/libgit2/include/git2/cherrypick.h +2 -2
- data/vendor/libgit2/include/git2/clone.h +4 -10
- data/vendor/libgit2/include/git2/config.h +66 -12
- data/vendor/libgit2/include/git2/describe.h +3 -2
- data/vendor/libgit2/include/git2/diff.h +3 -3
- data/vendor/libgit2/include/git2/errors.h +1 -0
- data/vendor/libgit2/include/git2/filter.h +21 -5
- data/vendor/libgit2/include/git2/index.h +32 -0
- data/vendor/libgit2/include/git2/merge.h +20 -3
- data/vendor/libgit2/include/git2/oid.h +1 -1
- data/vendor/libgit2/include/git2/pack.h +13 -0
- data/vendor/libgit2/include/git2/patch.h +3 -6
- data/vendor/libgit2/include/git2/rebase.h +8 -12
- data/vendor/libgit2/include/git2/refs.h +19 -29
- data/vendor/libgit2/include/git2/remote.h +5 -11
- data/vendor/libgit2/include/git2/repository.h +44 -15
- data/vendor/libgit2/include/git2/reset.h +19 -10
- data/vendor/libgit2/include/git2/revert.h +2 -2
- data/vendor/libgit2/include/git2/submodule.h +3 -9
- data/vendor/libgit2/include/git2/sys/config.h +3 -1
- data/vendor/libgit2/include/git2/sys/filter.h +10 -2
- data/vendor/libgit2/include/git2/sys/hashsig.h +49 -22
- data/vendor/libgit2/include/git2/transport.h +1 -1
- data/vendor/libgit2/include/git2/types.h +10 -3
- data/vendor/libgit2/include/git2/version.h +3 -2
- data/vendor/libgit2/src/annotated_commit.c +28 -0
- data/vendor/libgit2/src/array.h +19 -8
- data/vendor/libgit2/src/attr.c +95 -35
- data/vendor/libgit2/src/attr_file.c +51 -17
- data/vendor/libgit2/src/attr_file.h +37 -10
- data/vendor/libgit2/src/attrcache.c +13 -7
- data/vendor/libgit2/src/attrcache.h +1 -0
- data/vendor/libgit2/src/blame.c +26 -2
- data/vendor/libgit2/src/blame_git.c +6 -2
- data/vendor/libgit2/src/blob.c +6 -8
- data/vendor/libgit2/src/branch.c +55 -43
- data/vendor/libgit2/src/buf_text.c +13 -6
- data/vendor/libgit2/src/buffer.c +110 -25
- data/vendor/libgit2/src/buffer.h +18 -0
- data/vendor/libgit2/src/checkout.c +164 -92
- data/vendor/libgit2/src/checkout.h +0 -7
- data/vendor/libgit2/src/cherrypick.c +13 -7
- data/vendor/libgit2/src/clone.c +23 -25
- data/vendor/libgit2/src/commit.c +3 -3
- data/vendor/libgit2/src/common.h +23 -1
- data/vendor/libgit2/src/config.c +137 -19
- data/vendor/libgit2/src/config.h +2 -2
- data/vendor/libgit2/src/config_cache.c +2 -1
- data/vendor/libgit2/src/config_file.c +39 -18
- data/vendor/libgit2/src/config_file.h +1 -1
- data/vendor/libgit2/src/crlf.c +1 -1
- data/vendor/libgit2/src/delta-apply.c +3 -2
- data/vendor/libgit2/src/delta.c +25 -6
- data/vendor/libgit2/src/describe.c +2 -0
- data/vendor/libgit2/src/diff.c +8 -5
- data/vendor/libgit2/src/diff_driver.c +39 -18
- data/vendor/libgit2/src/diff_file.c +1 -1
- data/vendor/libgit2/src/diff_patch.c +12 -6
- data/vendor/libgit2/src/diff_tform.c +21 -24
- data/vendor/libgit2/src/filebuf.c +14 -12
- data/vendor/libgit2/src/fileops.c +61 -18
- data/vendor/libgit2/src/fileops.h +11 -2
- data/vendor/libgit2/src/filter.c +351 -99
- data/vendor/libgit2/src/filter.h +17 -0
- data/vendor/libgit2/src/global.c +38 -9
- data/vendor/libgit2/src/hash/hash_generic.c +1 -1
- data/vendor/libgit2/src/hashsig.c +28 -16
- data/vendor/libgit2/src/ignore.c +2 -2
- data/vendor/libgit2/src/index.c +159 -42
- data/vendor/libgit2/src/index.h +29 -0
- data/vendor/libgit2/src/indexer.c +11 -2
- data/vendor/libgit2/src/integer.h +96 -0
- data/vendor/libgit2/src/iterator.c +5 -3
- data/vendor/libgit2/src/khash.h +41 -29
- data/vendor/libgit2/src/merge.c +48 -35
- data/vendor/libgit2/src/merge.h +0 -1
- data/vendor/libgit2/src/merge_file.c +13 -0
- data/vendor/libgit2/src/mwindow.c +1 -1
- data/vendor/libgit2/src/notes.c +1 -1
- data/vendor/libgit2/src/odb.c +13 -11
- data/vendor/libgit2/src/odb_loose.c +22 -10
- data/vendor/libgit2/src/odb_mempack.c +4 -2
- data/vendor/libgit2/src/offmap.h +3 -2
- data/vendor/libgit2/src/oid.c +1 -1
- data/vendor/libgit2/src/oidmap.h +2 -1
- data/vendor/libgit2/src/openssl_stream.c +6 -3
- data/vendor/libgit2/src/pack-objects.c +273 -12
- data/vendor/libgit2/src/pack-objects.h +10 -0
- data/vendor/libgit2/src/pack.c +17 -6
- data/vendor/libgit2/src/pack.h +1 -3
- data/vendor/libgit2/src/path.c +68 -38
- data/vendor/libgit2/src/pathspec.c +3 -0
- data/vendor/libgit2/src/pool.c +9 -8
- data/vendor/libgit2/src/posix.c +11 -1
- data/vendor/libgit2/src/push.c +15 -17
- data/vendor/libgit2/src/push.h +1 -6
- data/vendor/libgit2/src/rebase.c +77 -35
- data/vendor/libgit2/src/refdb_fs.c +2 -2
- data/vendor/libgit2/src/refs.c +107 -81
- data/vendor/libgit2/src/refs.h +2 -2
- data/vendor/libgit2/src/refspec.c +3 -0
- data/vendor/libgit2/src/remote.c +19 -21
- data/vendor/libgit2/src/repository.c +258 -67
- data/vendor/libgit2/src/repository.h +31 -16
- data/vendor/libgit2/src/reset.c +28 -12
- data/vendor/libgit2/src/revert.c +12 -7
- data/vendor/libgit2/src/revwalk.c +3 -5
- data/vendor/libgit2/src/revwalk.h +1 -1
- data/vendor/libgit2/src/sortedcache.c +5 -3
- data/vendor/libgit2/src/stash.c +3 -5
- data/vendor/libgit2/src/strmap.h +2 -1
- data/vendor/libgit2/src/submodule.c +5 -6
- data/vendor/libgit2/src/tag.c +7 -5
- data/vendor/libgit2/src/transaction.c +1 -1
- data/vendor/libgit2/src/transports/cred.c +5 -2
- data/vendor/libgit2/src/transports/git.c +2 -3
- data/vendor/libgit2/src/transports/local.c +15 -34
- data/vendor/libgit2/src/transports/smart.c +1 -1
- data/vendor/libgit2/src/transports/smart_pkt.c +58 -18
- data/vendor/libgit2/src/transports/smart_protocol.c +2 -2
- data/vendor/libgit2/src/transports/winhttp.c +2 -2
- data/vendor/libgit2/src/tree.c +7 -5
- data/vendor/libgit2/src/tsort.c +3 -1
- data/vendor/libgit2/src/util.c +25 -0
- data/vendor/libgit2/src/util.h +31 -27
- data/vendor/libgit2/src/vector.c +2 -7
- data/vendor/libgit2/src/win32/dir.c +5 -3
- data/vendor/libgit2/src/win32/git2.rc +8 -4
- data/vendor/libgit2/src/win32/mingw-compat.h +7 -0
- data/vendor/libgit2/src/win32/msvc-compat.h +3 -0
- data/vendor/libgit2/src/win32/posix.h +1 -3
- data/vendor/libgit2/src/win32/posix_w32.c +31 -7
- data/vendor/libgit2/src/win32/utf-conv.c +1 -3
- data/vendor/libgit2/src/zstream.c +1 -1
- metadata +5 -5
- data/vendor/libgit2/src/bswap.h +0 -97
data/vendor/libgit2/src/merge.h
CHANGED
@@ -151,6 +151,19 @@ static int git_merge_file__from_inputs(
|
|
151
151
|
if (options.flags & GIT_MERGE_FILE_STYLE_DIFF3)
|
152
152
|
xmparam.style = XDL_MERGE_DIFF3;
|
153
153
|
|
154
|
+
if (options.flags & GIT_MERGE_FILE_IGNORE_WHITESPACE)
|
155
|
+
xmparam.xpp.flags |= XDF_IGNORE_WHITESPACE;
|
156
|
+
if (options.flags & GIT_MERGE_FILE_IGNORE_WHITESPACE_CHANGE)
|
157
|
+
xmparam.xpp.flags |= XDF_IGNORE_WHITESPACE_CHANGE;
|
158
|
+
if (options.flags & GIT_MERGE_FILE_IGNORE_WHITESPACE_EOL)
|
159
|
+
xmparam.xpp.flags |= XDF_IGNORE_WHITESPACE_AT_EOL;
|
160
|
+
|
161
|
+
if (options.flags & GIT_MERGE_FILE_DIFF_PATIENCE)
|
162
|
+
xmparam.xpp.flags |= XDF_PATIENCE_DIFF;
|
163
|
+
|
164
|
+
if (options.flags & GIT_MERGE_FILE_DIFF_MINIMAL)
|
165
|
+
xmparam.xpp.flags |= XDF_NEED_MINIMAL;
|
166
|
+
|
154
167
|
if ((xdl_result = xdl_merge(&ancestor_mmfile, &our_mmfile,
|
155
168
|
&their_mmfile, &xmparam, &mmbuffer)) < 0) {
|
156
169
|
giterr_set(GITERR_MERGE, "Failed to merge files.");
|
data/vendor/libgit2/src/notes.c
CHANGED
data/vendor/libgit2/src/odb.c
CHANGED
@@ -216,41 +216,43 @@ int git_odb__hashfd_filtered(
|
|
216
216
|
int git_odb__hashlink(git_oid *out, const char *path)
|
217
217
|
{
|
218
218
|
struct stat st;
|
219
|
-
|
219
|
+
int size;
|
220
220
|
int result;
|
221
221
|
|
222
222
|
if (git_path_lstat(path, &st) < 0)
|
223
223
|
return -1;
|
224
224
|
|
225
|
-
|
226
|
-
|
227
|
-
if (!git__is_sizet(size)) {
|
228
|
-
giterr_set(GITERR_OS, "File size overflow for 32-bit systems");
|
225
|
+
if (!git__is_int(st.st_size) || (int)st.st_size < 0) {
|
226
|
+
giterr_set(GITERR_FILESYSTEM, "File size overflow for 32-bit systems");
|
229
227
|
return -1;
|
230
228
|
}
|
231
229
|
|
230
|
+
size = (int)st.st_size;
|
231
|
+
|
232
232
|
if (S_ISLNK(st.st_mode)) {
|
233
233
|
char *link_data;
|
234
|
-
|
234
|
+
int read_len;
|
235
|
+
size_t alloc_size;
|
235
236
|
|
236
|
-
|
237
|
+
GITERR_CHECK_ALLOC_ADD(&alloc_size, size, 1);
|
238
|
+
link_data = git__malloc(alloc_size);
|
237
239
|
GITERR_CHECK_ALLOC(link_data);
|
238
240
|
|
239
|
-
read_len = p_readlink(path, link_data,
|
241
|
+
read_len = p_readlink(path, link_data, size);
|
240
242
|
link_data[size] = '\0';
|
241
|
-
if (read_len !=
|
243
|
+
if (read_len != size) {
|
242
244
|
giterr_set(GITERR_OS, "Failed to read symlink data for '%s'", path);
|
243
245
|
git__free(link_data);
|
244
246
|
return -1;
|
245
247
|
}
|
246
248
|
|
247
|
-
result = git_odb_hash(out, link_data,
|
249
|
+
result = git_odb_hash(out, link_data, size, GIT_OBJ_BLOB);
|
248
250
|
git__free(link_data);
|
249
251
|
} else {
|
250
252
|
int fd = git_futils_open_ro(path);
|
251
253
|
if (fd < 0)
|
252
254
|
return -1;
|
253
|
-
result = git_odb__hashfd(out, fd,
|
255
|
+
result = git_odb__hashfd(out, fd, size, GIT_OBJ_BLOB);
|
254
256
|
p_close(fd);
|
255
257
|
}
|
256
258
|
|
@@ -63,8 +63,12 @@ typedef struct {
|
|
63
63
|
static int object_file_name(
|
64
64
|
git_buf *name, const loose_backend *be, const git_oid *id)
|
65
65
|
{
|
66
|
+
size_t alloclen;
|
67
|
+
|
66
68
|
/* expand length for object root + 40 hex sha1 chars + 2 * '/' + '\0' */
|
67
|
-
|
69
|
+
GITERR_CHECK_ALLOC_ADD(&alloclen, be->objects_dirlen, GIT_OID_HEXSZ);
|
70
|
+
GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 3);
|
71
|
+
if (git_buf_grow(name, alloclen) < 0)
|
68
72
|
return -1;
|
69
73
|
|
70
74
|
git_buf_set(name, be->objects_dir, be->objects_dirlen);
|
@@ -261,14 +265,15 @@ static int inflate_buffer(void *in, size_t inlen, void *out, size_t outlen)
|
|
261
265
|
static void *inflate_tail(z_stream *s, void *hb, size_t used, obj_hdr *hdr)
|
262
266
|
{
|
263
267
|
unsigned char *buf, *head = hb;
|
264
|
-
size_t tail;
|
268
|
+
size_t tail, alloc_size;
|
265
269
|
|
266
270
|
/*
|
267
271
|
* allocate a buffer to hold the inflated data and copy the
|
268
272
|
* initial sequence of inflated data from the tail of the
|
269
273
|
* head buffer, if any.
|
270
274
|
*/
|
271
|
-
if ((
|
275
|
+
if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, hdr->size, 1) ||
|
276
|
+
(buf = git__malloc(alloc_size)) == NULL) {
|
272
277
|
inflateEnd(s);
|
273
278
|
return NULL;
|
274
279
|
}
|
@@ -306,7 +311,7 @@ static int inflate_packlike_loose_disk_obj(git_rawobj *out, git_buf *obj)
|
|
306
311
|
{
|
307
312
|
unsigned char *in, *buf;
|
308
313
|
obj_hdr hdr;
|
309
|
-
size_t len, used;
|
314
|
+
size_t len, used, alloclen;
|
310
315
|
|
311
316
|
/*
|
312
317
|
* read the object header, which is an (uncompressed)
|
@@ -321,7 +326,8 @@ static int inflate_packlike_loose_disk_obj(git_rawobj *out, git_buf *obj)
|
|
321
326
|
/*
|
322
327
|
* allocate a buffer and inflate the data into it
|
323
328
|
*/
|
324
|
-
|
329
|
+
GITERR_CHECK_ALLOC_ADD(&alloclen, hdr.size, 1);
|
330
|
+
buf = git__malloc(alloclen);
|
325
331
|
GITERR_CHECK_ALLOC(buf);
|
326
332
|
|
327
333
|
in = ((unsigned char *)obj->ptr) + used;
|
@@ -515,12 +521,14 @@ static int locate_object_short_oid(
|
|
515
521
|
size_t len)
|
516
522
|
{
|
517
523
|
char *objects_dir = backend->objects_dir;
|
518
|
-
size_t dir_len = strlen(objects_dir);
|
524
|
+
size_t dir_len = strlen(objects_dir), alloc_len;
|
519
525
|
loose_locate_object_state state;
|
520
526
|
int error;
|
521
527
|
|
522
528
|
/* prealloc memory for OBJ_DIR/xx/xx..38x..xx */
|
523
|
-
|
529
|
+
GITERR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ);
|
530
|
+
GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 3);
|
531
|
+
if (git_buf_grow(object_location, alloc_len) < 0)
|
524
532
|
return -1;
|
525
533
|
|
526
534
|
git_buf_set(object_location, objects_dir, dir_len);
|
@@ -563,9 +571,11 @@ static int locate_object_short_oid(
|
|
563
571
|
return error;
|
564
572
|
|
565
573
|
/* Update the location according to the oid obtained */
|
574
|
+
GITERR_CHECK_ALLOC_ADD(&alloc_len, dir_len, GIT_OID_HEXSZ);
|
575
|
+
GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, 2);
|
566
576
|
|
567
577
|
git_buf_truncate(object_location, dir_len);
|
568
|
-
if (git_buf_grow(object_location,
|
578
|
+
if (git_buf_grow(object_location, alloc_len) < 0)
|
569
579
|
return -1;
|
570
580
|
|
571
581
|
git_oid_pathfmt(object_location->ptr + dir_len, res_oid);
|
@@ -922,13 +932,15 @@ int git_odb_backend_loose(
|
|
922
932
|
unsigned int file_mode)
|
923
933
|
{
|
924
934
|
loose_backend *backend;
|
925
|
-
size_t objects_dirlen;
|
935
|
+
size_t objects_dirlen, alloclen;
|
926
936
|
|
927
937
|
assert(backend_out && objects_dir);
|
928
938
|
|
929
939
|
objects_dirlen = strlen(objects_dir);
|
930
940
|
|
931
|
-
|
941
|
+
GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(loose_backend), objects_dirlen);
|
942
|
+
GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 2);
|
943
|
+
backend = git__calloc(1, alloclen);
|
932
944
|
GITERR_CHECK_ALLOC(backend);
|
933
945
|
|
934
946
|
backend->parent.version = GIT_ODB_BACKEND_VERSION;
|
@@ -18,7 +18,7 @@
|
|
18
18
|
#include "git2/types.h"
|
19
19
|
#include "git2/pack.h"
|
20
20
|
|
21
|
-
GIT__USE_OIDMAP
|
21
|
+
GIT__USE_OIDMAP
|
22
22
|
|
23
23
|
struct memobject {
|
24
24
|
git_oid oid;
|
@@ -38,6 +38,7 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void
|
|
38
38
|
struct memory_packer_db *db = (struct memory_packer_db *)_backend;
|
39
39
|
struct memobject *obj = NULL;
|
40
40
|
khiter_t pos;
|
41
|
+
size_t alloc_len;
|
41
42
|
int rval;
|
42
43
|
|
43
44
|
pos = kh_put(oid, db->objects, oid, &rval);
|
@@ -47,7 +48,8 @@ static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void
|
|
47
48
|
if (rval == 0)
|
48
49
|
return 0;
|
49
50
|
|
50
|
-
|
51
|
+
GITERR_CHECK_ALLOC_ADD(&alloc_len, sizeof(struct memobject), len);
|
52
|
+
obj = git__malloc(alloc_len);
|
51
53
|
GITERR_CHECK_ALLOC(obj);
|
52
54
|
|
53
55
|
memcpy(obj->data, data, len);
|
data/vendor/libgit2/src/offmap.h
CHANGED
@@ -13,14 +13,15 @@
|
|
13
13
|
#define kmalloc git__malloc
|
14
14
|
#define kcalloc git__calloc
|
15
15
|
#define krealloc git__realloc
|
16
|
+
#define kreallocarray git__reallocarray
|
16
17
|
#define kfree git__free
|
17
18
|
#include "khash.h"
|
18
19
|
|
19
|
-
__KHASH_TYPE(off, git_off_t, void *)
|
20
|
+
__KHASH_TYPE(off, git_off_t, void *)
|
20
21
|
typedef khash_t(off) git_offmap;
|
21
22
|
|
22
23
|
#define GIT__USE_OFFMAP \
|
23
|
-
__KHASH_IMPL(off, static kh_inline, git_off_t, void *, 1, kh_int64_hash_func, kh_int64_hash_equal)
|
24
|
+
__KHASH_IMPL(off, static kh_inline, git_off_t, void *, 1, kh_int64_hash_func, kh_int64_hash_equal)
|
24
25
|
|
25
26
|
#define git_offmap_alloc() kh_init(off)
|
26
27
|
#define git_offmap_free(h) kh_destroy(off, h), h = NULL
|
data/vendor/libgit2/src/oid.c
CHANGED
@@ -261,7 +261,7 @@ struct git_oid_shorten {
|
|
261
261
|
|
262
262
|
static int resize_trie(git_oid_shorten *self, size_t new_size)
|
263
263
|
{
|
264
|
-
self->nodes =
|
264
|
+
self->nodes = git__reallocarray(self->nodes, new_size, sizeof(trie_node));
|
265
265
|
GITERR_CHECK_ALLOC(self->nodes);
|
266
266
|
|
267
267
|
if (new_size > self->size) {
|
data/vendor/libgit2/src/oidmap.h
CHANGED
@@ -13,10 +13,11 @@
|
|
13
13
|
#define kmalloc git__malloc
|
14
14
|
#define kcalloc git__calloc
|
15
15
|
#define krealloc git__realloc
|
16
|
+
#define kreallocarray git__reallocarray
|
16
17
|
#define kfree git__free
|
17
18
|
#include "khash.h"
|
18
19
|
|
19
|
-
__KHASH_TYPE(oid, const git_oid *, void *)
|
20
|
+
__KHASH_TYPE(oid, const git_oid *, void *)
|
20
21
|
typedef khash_t(oid) git_oidmap;
|
21
22
|
|
22
23
|
GIT_INLINE(khint_t) git_oidmap_hash(const git_oid *oid)
|
@@ -8,9 +8,6 @@
|
|
8
8
|
#ifdef GIT_SSL
|
9
9
|
|
10
10
|
#include <ctype.h>
|
11
|
-
#include <sys/types.h>
|
12
|
-
#include <sys/socket.h>
|
13
|
-
#include <netinet/in.h>
|
14
11
|
|
15
12
|
#include "global.h"
|
16
13
|
#include "posix.h"
|
@@ -19,6 +16,12 @@
|
|
19
16
|
#include "netops.h"
|
20
17
|
#include "git2/transport.h"
|
21
18
|
|
19
|
+
#ifndef GIT_WIN32
|
20
|
+
# include <sys/types.h>
|
21
|
+
# include <sys/socket.h>
|
22
|
+
# include <netinet/in.h>
|
23
|
+
#endif
|
24
|
+
|
22
25
|
#include <openssl/ssl.h>
|
23
26
|
#include <openssl/err.h>
|
24
27
|
#include <openssl/x509v3.h>
|
@@ -15,6 +15,8 @@
|
|
15
15
|
#include "thread-utils.h"
|
16
16
|
#include "tree.h"
|
17
17
|
#include "util.h"
|
18
|
+
#include "revwalk.h"
|
19
|
+
#include "commit_list.h"
|
18
20
|
|
19
21
|
#include "git2/pack.h"
|
20
22
|
#include "git2/commit.h"
|
@@ -39,6 +41,8 @@ struct pack_write_context {
|
|
39
41
|
git_transfer_progress *stats;
|
40
42
|
};
|
41
43
|
|
44
|
+
GIT__USE_OIDMAP;
|
45
|
+
|
42
46
|
#ifdef GIT_THREADS
|
43
47
|
|
44
48
|
#define GIT_PACKBUILDER__MUTEX_OP(pb, mtx, op) do { \
|
@@ -124,10 +128,16 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo)
|
|
124
128
|
GITERR_CHECK_ALLOC(pb);
|
125
129
|
|
126
130
|
pb->object_ix = git_oidmap_alloc();
|
127
|
-
|
128
131
|
if (!pb->object_ix)
|
129
132
|
goto on_error;
|
130
133
|
|
134
|
+
pb->walk_objects = git_oidmap_alloc();
|
135
|
+
if (!pb->walk_objects)
|
136
|
+
goto on_error;
|
137
|
+
|
138
|
+
if (git_pool_init(&pb->object_pool, sizeof(git_walk_object), 0) < 0)
|
139
|
+
goto on_error;
|
140
|
+
|
131
141
|
pb->repo = repo;
|
132
142
|
pb->nr_threads = 1; /* do not spawn any thread by default */
|
133
143
|
|
@@ -190,6 +200,7 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
|
|
190
200
|
{
|
191
201
|
git_pobject *po;
|
192
202
|
khiter_t pos;
|
203
|
+
size_t newsize;
|
193
204
|
int ret;
|
194
205
|
|
195
206
|
assert(pb && oid);
|
@@ -201,9 +212,18 @@ int git_packbuilder_insert(git_packbuilder *pb, const git_oid *oid,
|
|
201
212
|
return 0;
|
202
213
|
|
203
214
|
if (pb->nr_objects >= pb->nr_alloc) {
|
204
|
-
|
205
|
-
|
206
|
-
|
215
|
+
GITERR_CHECK_ALLOC_ADD(&newsize, pb->nr_alloc, 1024);
|
216
|
+
GITERR_CHECK_ALLOC_MULTIPLY(&newsize, newsize, 3 / 2);
|
217
|
+
|
218
|
+
if (!git__is_uint32(newsize)) {
|
219
|
+
giterr_set(GITERR_NOMEMORY, "Packfile too large to fit in memory.");
|
220
|
+
return -1;
|
221
|
+
}
|
222
|
+
|
223
|
+
pb->nr_alloc = (uint32_t)newsize;
|
224
|
+
|
225
|
+
pb->object_list = git__reallocarray(pb->object_list,
|
226
|
+
pb->nr_alloc, sizeof(*po));
|
207
227
|
GITERR_CHECK_ALLOC(pb->object_list);
|
208
228
|
rehash(pb);
|
209
229
|
}
|
@@ -499,8 +519,10 @@ static int cb_tag_foreach(const char *name, git_oid *oid, void *data)
|
|
499
519
|
static git_pobject **compute_write_order(git_packbuilder *pb)
|
500
520
|
{
|
501
521
|
unsigned int i, wo_end, last_untagged;
|
522
|
+
git_pobject **wo;
|
502
523
|
|
503
|
-
|
524
|
+
if ((wo = git__mallocarray(pb->nr_objects, sizeof(*wo))) == NULL)
|
525
|
+
return NULL;
|
504
526
|
|
505
527
|
for (i = 0; i < pb->nr_objects; i++) {
|
506
528
|
git_pobject *po = pb->object_list + i;
|
@@ -770,10 +792,13 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
770
792
|
*mem_usage += sz;
|
771
793
|
}
|
772
794
|
if (!src->data) {
|
773
|
-
|
795
|
+
size_t obj_sz;
|
796
|
+
|
797
|
+
if (git_odb_read(&obj, pb->odb, &src_object->id) < 0 ||
|
798
|
+
!git__is_ulong(obj_sz = git_odb_object_size(obj)))
|
774
799
|
return -1;
|
775
800
|
|
776
|
-
sz = (unsigned long)
|
801
|
+
sz = (unsigned long)obj_sz;
|
777
802
|
src->data = git__malloc(sz);
|
778
803
|
GITERR_CHECK_ALLOC(src->data);
|
779
804
|
memcpy(src->data, git_odb_object_data(obj), sz);
|
@@ -817,11 +842,14 @@ static int try_delta(git_packbuilder *pb, struct unpacked *trg,
|
|
817
842
|
trg_object->delta_data = NULL;
|
818
843
|
}
|
819
844
|
if (delta_cacheable(pb, src_size, trg_size, delta_size)) {
|
820
|
-
|
845
|
+
bool overflow = git__add_uint64_overflow(
|
846
|
+
&pb->delta_cache_size, pb->delta_cache_size, delta_size);
|
847
|
+
|
821
848
|
git_packbuilder__cache_unlock(pb);
|
822
849
|
|
823
|
-
|
824
|
-
|
850
|
+
if (overflow ||
|
851
|
+
!(trg_object->delta_data = git__realloc(delta_buf, delta_size)))
|
852
|
+
return -1;
|
825
853
|
} else {
|
826
854
|
/* create delta when writing the pack */
|
827
855
|
git_packbuilder__cache_unlock(pb);
|
@@ -1088,7 +1116,7 @@ static int ll_find_deltas(git_packbuilder *pb, git_pobject **list,
|
|
1088
1116
|
return 0;
|
1089
1117
|
}
|
1090
1118
|
|
1091
|
-
p =
|
1119
|
+
p = git__mallocarray(pb->nr_threads, sizeof(*p));
|
1092
1120
|
GITERR_CHECK_ALLOC(p);
|
1093
1121
|
|
1094
1122
|
/* Partition the work among the threads */
|
@@ -1239,7 +1267,7 @@ static int prepare_pack(git_packbuilder *pb)
|
|
1239
1267
|
if (pb->progress_cb)
|
1240
1268
|
pb->progress_cb(GIT_PACKBUILDER_DELTAFICATION, 0, pb->nr_objects, pb->progress_cb_payload);
|
1241
1269
|
|
1242
|
-
delta_list =
|
1270
|
+
delta_list = git__mallocarray(pb->nr_objects, sizeof(*delta_list));
|
1243
1271
|
GITERR_CHECK_ALLOC(delta_list);
|
1244
1272
|
|
1245
1273
|
for (i = 0; i < pb->nr_objects; ++i) {
|
@@ -1327,6 +1355,7 @@ const git_oid *git_packbuilder_hash(git_packbuilder *pb)
|
|
1327
1355
|
return &pb->pack_oid;
|
1328
1356
|
}
|
1329
1357
|
|
1358
|
+
|
1330
1359
|
static int cb_tree_walk(
|
1331
1360
|
const char *root, const git_tree_entry *entry, void *payload)
|
1332
1361
|
{
|
@@ -1385,6 +1414,235 @@ uint32_t git_packbuilder_written(git_packbuilder *pb)
|
|
1385
1414
|
return pb->nr_written;
|
1386
1415
|
}
|
1387
1416
|
|
1417
|
+
int lookup_walk_object(git_walk_object **out, git_packbuilder *pb, const git_oid *id)
|
1418
|
+
{
|
1419
|
+
git_walk_object *obj;
|
1420
|
+
|
1421
|
+
obj = git_pool_mallocz(&pb->object_pool, 1);
|
1422
|
+
if (!obj) {
|
1423
|
+
giterr_set_oom();
|
1424
|
+
return -1;
|
1425
|
+
}
|
1426
|
+
|
1427
|
+
git_oid_cpy(&obj->id, id);
|
1428
|
+
|
1429
|
+
*out = obj;
|
1430
|
+
return 0;
|
1431
|
+
}
|
1432
|
+
|
1433
|
+
static int retrieve_object(git_walk_object **out, git_packbuilder *pb, const git_oid *id)
|
1434
|
+
{
|
1435
|
+
int error;
|
1436
|
+
khiter_t pos;
|
1437
|
+
git_walk_object *obj;
|
1438
|
+
|
1439
|
+
pos = git_oidmap_lookup_index(pb->walk_objects, id);
|
1440
|
+
if (git_oidmap_valid_index(pb->walk_objects, pos)) {
|
1441
|
+
obj = git_oidmap_value_at(pb->walk_objects, pos);
|
1442
|
+
} else {
|
1443
|
+
if ((error = lookup_walk_object(&obj, pb, id)) < 0)
|
1444
|
+
return error;
|
1445
|
+
|
1446
|
+
git_oidmap_insert(pb->walk_objects, &obj->id, obj, error);
|
1447
|
+
}
|
1448
|
+
|
1449
|
+
*out = obj;
|
1450
|
+
return 0;
|
1451
|
+
}
|
1452
|
+
|
1453
|
+
static int mark_blob_uninteresting(git_packbuilder *pb, const git_oid *id)
|
1454
|
+
{
|
1455
|
+
int error;
|
1456
|
+
git_walk_object *obj;
|
1457
|
+
|
1458
|
+
if ((error = retrieve_object(&obj, pb, id)) < 0)
|
1459
|
+
return error;
|
1460
|
+
|
1461
|
+
obj->uninteresting = 1;
|
1462
|
+
|
1463
|
+
return 0;
|
1464
|
+
}
|
1465
|
+
|
1466
|
+
static int mark_tree_uninteresting(git_packbuilder *pb, const git_oid *id)
|
1467
|
+
{
|
1468
|
+
git_walk_object *obj;
|
1469
|
+
git_tree *tree;
|
1470
|
+
int error;
|
1471
|
+
size_t i;
|
1472
|
+
|
1473
|
+
if ((error = retrieve_object(&obj, pb, id)) < 0)
|
1474
|
+
return error;
|
1475
|
+
|
1476
|
+
if (obj->uninteresting)
|
1477
|
+
return 0;
|
1478
|
+
|
1479
|
+
obj->uninteresting = 1;
|
1480
|
+
|
1481
|
+
if ((error = git_tree_lookup(&tree, pb->repo, id)) < 0)
|
1482
|
+
return error;
|
1483
|
+
|
1484
|
+
for (i = 0; i < git_tree_entrycount(tree); i++) {
|
1485
|
+
const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
|
1486
|
+
const git_oid *entry_id = git_tree_entry_id(entry);
|
1487
|
+
switch (git_tree_entry_type(entry)) {
|
1488
|
+
case GIT_OBJ_TREE:
|
1489
|
+
if ((error = mark_tree_uninteresting(pb, entry_id)) < 0)
|
1490
|
+
goto cleanup;
|
1491
|
+
break;
|
1492
|
+
case GIT_OBJ_BLOB:
|
1493
|
+
if ((error = mark_blob_uninteresting(pb, entry_id)) < 0)
|
1494
|
+
goto cleanup;
|
1495
|
+
break;
|
1496
|
+
default:
|
1497
|
+
/* it's a submodule or something unknown, we don't want it */
|
1498
|
+
;
|
1499
|
+
}
|
1500
|
+
}
|
1501
|
+
|
1502
|
+
cleanup:
|
1503
|
+
git_tree_free(tree);
|
1504
|
+
return error;
|
1505
|
+
}
|
1506
|
+
|
1507
|
+
/*
|
1508
|
+
* Mark the edges of the graph uninteresting. Since we start from a
|
1509
|
+
* git_revwalk, the commits are already uninteresting, but we need to
|
1510
|
+
* mark the trees and blobs.
|
1511
|
+
*/
|
1512
|
+
static int mark_edges_uninteresting(git_packbuilder *pb, git_commit_list *commits)
|
1513
|
+
{
|
1514
|
+
int error;
|
1515
|
+
git_commit_list *list;
|
1516
|
+
git_commit *commit;
|
1517
|
+
|
1518
|
+
for (list = commits; list; list = list->next) {
|
1519
|
+
if (!list->item->uninteresting)
|
1520
|
+
continue;
|
1521
|
+
|
1522
|
+
if ((error = git_commit_lookup(&commit, pb->repo, &list->item->oid)) < 0)
|
1523
|
+
return error;
|
1524
|
+
|
1525
|
+
error = mark_tree_uninteresting(pb, git_commit_tree_id(commit));
|
1526
|
+
git_commit_free(commit);
|
1527
|
+
|
1528
|
+
if (error < 0)
|
1529
|
+
return error;
|
1530
|
+
}
|
1531
|
+
|
1532
|
+
return 0;
|
1533
|
+
}
|
1534
|
+
|
1535
|
+
int insert_tree(git_packbuilder *pb, git_tree *tree)
|
1536
|
+
{
|
1537
|
+
size_t i;
|
1538
|
+
int error;
|
1539
|
+
git_tree *subtree;
|
1540
|
+
git_walk_object *obj;
|
1541
|
+
const char *name;
|
1542
|
+
|
1543
|
+
if ((error = retrieve_object(&obj, pb, git_tree_id(tree))) < 0)
|
1544
|
+
return error;
|
1545
|
+
|
1546
|
+
if (obj->seen)
|
1547
|
+
return 0;
|
1548
|
+
|
1549
|
+
obj->seen = 1;
|
1550
|
+
|
1551
|
+
if ((error = git_packbuilder_insert(pb, &obj->id, NULL)))
|
1552
|
+
return error;
|
1553
|
+
|
1554
|
+
for (i = 0; i < git_tree_entrycount(tree); i++) {
|
1555
|
+
const git_tree_entry *entry = git_tree_entry_byindex(tree, i);
|
1556
|
+
const git_oid *entry_id = git_tree_entry_id(entry);
|
1557
|
+
switch (git_tree_entry_type(entry)) {
|
1558
|
+
case GIT_OBJ_TREE:
|
1559
|
+
if ((error = git_tree_lookup(&subtree, pb->repo, entry_id)) < 0)
|
1560
|
+
return error;
|
1561
|
+
|
1562
|
+
error = insert_tree(pb, subtree);
|
1563
|
+
git_tree_free(subtree);
|
1564
|
+
|
1565
|
+
if (error < 0)
|
1566
|
+
return error;
|
1567
|
+
|
1568
|
+
break;
|
1569
|
+
case GIT_OBJ_BLOB:
|
1570
|
+
name = git_tree_entry_name(entry);
|
1571
|
+
if ((error = git_packbuilder_insert(pb, entry_id, name)) < 0)
|
1572
|
+
return error;
|
1573
|
+
break;
|
1574
|
+
default:
|
1575
|
+
/* it's a submodule or something unknown, we don't want it */
|
1576
|
+
;
|
1577
|
+
}
|
1578
|
+
}
|
1579
|
+
|
1580
|
+
|
1581
|
+
return error;
|
1582
|
+
}
|
1583
|
+
|
1584
|
+
int insert_commit(git_packbuilder *pb, git_walk_object *obj)
|
1585
|
+
{
|
1586
|
+
int error;
|
1587
|
+
git_commit *commit = NULL;
|
1588
|
+
git_tree *tree = NULL;
|
1589
|
+
|
1590
|
+
obj->seen = 1;
|
1591
|
+
|
1592
|
+
if ((error = git_packbuilder_insert(pb, &obj->id, NULL)) < 0)
|
1593
|
+
return error;
|
1594
|
+
|
1595
|
+
if ((error = git_commit_lookup(&commit, pb->repo, &obj->id)) < 0)
|
1596
|
+
return error;
|
1597
|
+
|
1598
|
+
if ((error = git_tree_lookup(&tree, pb->repo, git_commit_tree_id(commit))) < 0)
|
1599
|
+
goto cleanup;
|
1600
|
+
|
1601
|
+
if ((error = insert_tree(pb, tree)) < 0)
|
1602
|
+
goto cleanup;
|
1603
|
+
|
1604
|
+
cleanup:
|
1605
|
+
git_commit_free(commit);
|
1606
|
+
git_tree_free(tree);
|
1607
|
+
return error;
|
1608
|
+
}
|
1609
|
+
|
1610
|
+
int git_packbuilder_insert_walk(git_packbuilder *pb, git_revwalk *walk)
|
1611
|
+
{
|
1612
|
+
int error;
|
1613
|
+
git_oid id;
|
1614
|
+
git_walk_object *obj;
|
1615
|
+
|
1616
|
+
assert(pb && walk);
|
1617
|
+
|
1618
|
+
if ((error = mark_edges_uninteresting(pb, walk->user_input)) < 0)
|
1619
|
+
return error;
|
1620
|
+
|
1621
|
+
/*
|
1622
|
+
* TODO: git marks the parents of the edges
|
1623
|
+
* uninteresting. This may provide a speed advantage, but does
|
1624
|
+
* seem to assume the remote does not have a single-commit
|
1625
|
+
* history on the other end.
|
1626
|
+
*/
|
1627
|
+
|
1628
|
+
/* walk down each tree up to the blobs and insert them, stopping when uninteresting */
|
1629
|
+
while ((error = git_revwalk_next(&id, walk)) == 0) {
|
1630
|
+
if ((error = retrieve_object(&obj, pb, &id)) < 0)
|
1631
|
+
return error;
|
1632
|
+
|
1633
|
+
if (obj->seen || obj->uninteresting)
|
1634
|
+
continue;
|
1635
|
+
|
1636
|
+
if ((error = insert_commit(pb, obj)) < 0)
|
1637
|
+
return error;
|
1638
|
+
}
|
1639
|
+
|
1640
|
+
if (error == GIT_ITEROVER)
|
1641
|
+
error = 0;
|
1642
|
+
|
1643
|
+
return 0;
|
1644
|
+
}
|
1645
|
+
|
1388
1646
|
int git_packbuilder_set_callbacks(git_packbuilder *pb, git_packbuilder_progress progress_cb, void *progress_cb_payload)
|
1389
1647
|
{
|
1390
1648
|
if (!pb)
|
@@ -1418,6 +1676,9 @@ void git_packbuilder_free(git_packbuilder *pb)
|
|
1418
1676
|
if (pb->object_list)
|
1419
1677
|
git__free(pb->object_list);
|
1420
1678
|
|
1679
|
+
git_oidmap_free(pb->walk_objects);
|
1680
|
+
git_pool_clear(&pb->object_pool);
|
1681
|
+
|
1421
1682
|
git_hash_ctx_cleanup(&pb->ctx);
|
1422
1683
|
git_zstream_free(&pb->zstream);
|
1423
1684
|
|