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
@@ -7,7 +7,7 @@
|
|
7
7
|
#include "common.h"
|
8
8
|
#include "vector.h"
|
9
9
|
#include "diff.h"
|
10
|
-
#include "
|
10
|
+
#include "patch_generate.h"
|
11
11
|
|
12
12
|
#define DIFF_RENAME_FILE_SEPARATOR " => "
|
13
13
|
#define STATS_FULL_MIN_SCALE 7
|
@@ -190,8 +190,9 @@ int git_diff_get_stats(
|
|
190
190
|
break;
|
191
191
|
|
192
192
|
/* keep a count of renames because it will affect formatting */
|
193
|
-
delta =
|
193
|
+
delta = patch->delta;
|
194
194
|
|
195
|
+
/* TODO ugh */
|
195
196
|
namelen = strlen(delta->new_file.path);
|
196
197
|
if (strcmp(delta->old_file.path, delta->new_file.path) != 0) {
|
197
198
|
namelen += strlen(delta->old_file.path);
|
@@ -0,0 +1,22 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) the libgit2 contributors. All rights reserved.
|
3
|
+
*
|
4
|
+
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
5
|
+
* a Linking Exception. For full terms see the included COPYING file.
|
6
|
+
*/
|
7
|
+
#ifndef INCLUDE_diff_tform_h__
|
8
|
+
#define INCLUDE_diff_tform_h__
|
9
|
+
|
10
|
+
extern int git_diff_find_similar__hashsig_for_file(
|
11
|
+
void **out, const git_diff_file *f, const char *path, void *p);
|
12
|
+
|
13
|
+
extern int git_diff_find_similar__hashsig_for_buf(
|
14
|
+
void **out, const git_diff_file *f, const char *buf, size_t len, void *p);
|
15
|
+
|
16
|
+
extern void git_diff_find_similar__hashsig_free(void *sig, void *payload);
|
17
|
+
|
18
|
+
extern int git_diff_find_similar__calc_similarity(
|
19
|
+
int *score, void *siga, void *sigb, void *payload);
|
20
|
+
|
21
|
+
#endif
|
22
|
+
|
@@ -8,8 +8,8 @@
|
|
8
8
|
#include "common.h"
|
9
9
|
#include "diff.h"
|
10
10
|
#include "diff_driver.h"
|
11
|
-
#include "diff_patch.h"
|
12
11
|
#include "diff_xdiff.h"
|
12
|
+
#include "patch_generate.h"
|
13
13
|
|
14
14
|
static int git_xdiff_scan_int(const char **str, int *value)
|
15
15
|
{
|
@@ -56,7 +56,7 @@ fail:
|
|
56
56
|
|
57
57
|
typedef struct {
|
58
58
|
git_xdiff_output *xo;
|
59
|
-
|
59
|
+
git_patch_generated *patch;
|
60
60
|
git_diff_hunk hunk;
|
61
61
|
int old_lineno, new_lineno;
|
62
62
|
mmfile_t xd_old_data, xd_new_data;
|
@@ -110,9 +110,9 @@ static int diff_update_lines(
|
|
110
110
|
static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
|
111
111
|
{
|
112
112
|
git_xdiff_info *info = priv;
|
113
|
-
|
114
|
-
const git_diff_delta *delta =
|
115
|
-
|
113
|
+
git_patch_generated *patch = info->patch;
|
114
|
+
const git_diff_delta *delta = patch->base.delta;
|
115
|
+
git_patch_generated_output *output = &info->xo->output;
|
116
116
|
git_diff_line line;
|
117
117
|
|
118
118
|
if (len == 1) {
|
@@ -181,7 +181,7 @@ static int git_xdiff_cb(void *priv, mmbuffer_t *bufs, int len)
|
|
181
181
|
return output->error;
|
182
182
|
}
|
183
183
|
|
184
|
-
static int git_xdiff(
|
184
|
+
static int git_xdiff(git_patch_generated_output *output, git_patch_generated *patch)
|
185
185
|
{
|
186
186
|
git_xdiff_output *xo = (git_xdiff_output *)output;
|
187
187
|
git_xdiff_info info;
|
@@ -194,7 +194,7 @@ static int git_xdiff(git_diff_output *output, git_patch *patch)
|
|
194
194
|
xo->callback.priv = &info;
|
195
195
|
|
196
196
|
git_diff_find_context_init(
|
197
|
-
&xo->config.find_func, &findctxt,
|
197
|
+
&xo->config.find_func, &findctxt, git_patch_generated_driver(patch));
|
198
198
|
xo->config.find_func_priv = &findctxt;
|
199
199
|
|
200
200
|
if (xo->config.find_func != NULL)
|
@@ -206,8 +206,8 @@ static int git_xdiff(git_diff_output *output, git_patch *patch)
|
|
206
206
|
* updates are needed to xo->params.flags
|
207
207
|
*/
|
208
208
|
|
209
|
-
|
210
|
-
|
209
|
+
git_patch_generated_old_data(&info.xd_old_data.ptr, &info.xd_old_data.size, patch);
|
210
|
+
git_patch_generated_new_data(&info.xd_new_data.ptr, &info.xd_new_data.size, patch);
|
211
211
|
|
212
212
|
if (info.xd_old_data.size > GIT_XDIFF_MAX_SIZE ||
|
213
213
|
info.xd_new_data.size > GIT_XDIFF_MAX_SIZE) {
|
@@ -8,20 +8,20 @@
|
|
8
8
|
#define INCLUDE_diff_xdiff_h__
|
9
9
|
|
10
10
|
#include "diff.h"
|
11
|
-
#include "diff_patch.h"
|
12
11
|
#include "xdiff/xdiff.h"
|
12
|
+
#include "patch_generate.h"
|
13
13
|
|
14
14
|
/* xdiff cannot cope with large files. these files should not be passed to
|
15
15
|
* xdiff. callers should treat these large files as binary.
|
16
16
|
*/
|
17
17
|
#define GIT_XDIFF_MAX_SIZE (1024LL * 1024 * 1023)
|
18
18
|
|
19
|
-
/* A git_xdiff_output is a
|
20
|
-
* to use libxdiff. Calling git_xdiff_init() will set the diff_cb
|
21
|
-
* of the output to use xdiff to generate the diffs.
|
19
|
+
/* A git_xdiff_output is a git_patch_generate_output with extra fields
|
20
|
+
* necessary to use libxdiff. Calling git_xdiff_init() will set the diff_cb
|
21
|
+
* field of the output to use xdiff to generate the diffs.
|
22
22
|
*/
|
23
23
|
typedef struct {
|
24
|
-
|
24
|
+
git_patch_generated_output output;
|
25
25
|
|
26
26
|
xdemitconf_t config;
|
27
27
|
xpparam_t params;
|
@@ -837,6 +837,19 @@ int git_futils_cp(const char *from, const char *to, mode_t filemode)
|
|
837
837
|
return cp_by_fd(ifd, ofd, true);
|
838
838
|
}
|
839
839
|
|
840
|
+
int git_futils_touch(const char *path, time_t *when)
|
841
|
+
{
|
842
|
+
struct p_timeval times[2];
|
843
|
+
int ret;
|
844
|
+
|
845
|
+
times[0].tv_sec = times[1].tv_sec = when ? *when : time(NULL);
|
846
|
+
times[0].tv_usec = times[1].tv_usec = 0;
|
847
|
+
|
848
|
+
ret = p_utimes(path, times);
|
849
|
+
|
850
|
+
return (ret < 0) ? git_path_set_error(errno, path, "touch") : 0;
|
851
|
+
}
|
852
|
+
|
840
853
|
static int cp_link(const char *from, const char *to, size_t link_size)
|
841
854
|
{
|
842
855
|
int error = 0;
|
@@ -184,6 +184,12 @@ extern int git_futils_cp(
|
|
184
184
|
const char *to,
|
185
185
|
mode_t filemode);
|
186
186
|
|
187
|
+
/**
|
188
|
+
* Set the files atime and mtime to the given time, or the current time
|
189
|
+
* if `ts` is NULL.
|
190
|
+
*/
|
191
|
+
extern int git_futils_touch(const char *path, time_t *when);
|
192
|
+
|
187
193
|
/**
|
188
194
|
* Flags that can be passed to `git_futils_cp_r`.
|
189
195
|
*
|
data/vendor/libgit2/src/global.c
CHANGED
@@ -61,8 +61,9 @@ static int init_common(void)
|
|
61
61
|
(ret = git_sysdir_global_init()) == 0 &&
|
62
62
|
(ret = git_filter_global_init()) == 0 &&
|
63
63
|
(ret = git_merge_driver_global_init()) == 0 &&
|
64
|
-
(ret = git_transport_ssh_global_init()) == 0
|
65
|
-
ret = git_openssl_stream_global_init()
|
64
|
+
(ret = git_transport_ssh_global_init()) == 0 &&
|
65
|
+
(ret = git_openssl_stream_global_init()) == 0)
|
66
|
+
ret = git_mwindow_global_init();
|
66
67
|
|
67
68
|
GIT_MEMORY_BARRIER;
|
68
69
|
|
@@ -87,11 +88,6 @@ static void shutdown_common(void)
|
|
87
88
|
|
88
89
|
git__free(git__user_agent);
|
89
90
|
git__free(git__ssl_ciphers);
|
90
|
-
|
91
|
-
#if defined(GIT_MSVC_CRTDBG)
|
92
|
-
git_win32__crtdbg_stacktrace_cleanup();
|
93
|
-
git_win32__stack_cleanup();
|
94
|
-
#endif
|
95
91
|
}
|
96
92
|
|
97
93
|
/**
|
@@ -139,7 +135,7 @@ static int synchronized_threads_init(void)
|
|
139
135
|
|
140
136
|
_tls_index = TlsAlloc();
|
141
137
|
|
142
|
-
|
138
|
+
git_threads_init();
|
143
139
|
|
144
140
|
if (git_mutex_init(&git__mwindow_mutex))
|
145
141
|
return -1;
|
@@ -183,6 +179,11 @@ int git_libgit2_shutdown(void)
|
|
183
179
|
|
184
180
|
TlsFree(_tls_index);
|
185
181
|
git_mutex_free(&git__mwindow_mutex);
|
182
|
+
|
183
|
+
#if defined(GIT_MSVC_CRTDBG)
|
184
|
+
git_win32__crtdbg_stacktrace_cleanup();
|
185
|
+
git_win32__stack_cleanup();
|
186
|
+
#endif
|
186
187
|
}
|
187
188
|
|
188
189
|
/* Exit the lock */
|
data/vendor/libgit2/src/ignore.c
CHANGED
@@ -11,35 +11,64 @@
|
|
11
11
|
#define GIT_IGNORE_DEFAULT_RULES ".\n..\n.git\n"
|
12
12
|
|
13
13
|
/**
|
14
|
-
* A negative ignore pattern can
|
15
|
-
* wildcards if
|
16
|
-
* pattern. Thus
|
14
|
+
* A negative ignore pattern can negate a positive one without
|
15
|
+
* wildcards if it is a basename only and equals the basename of
|
16
|
+
* the positive pattern. Thus
|
17
17
|
*
|
18
18
|
* foo/bar
|
19
19
|
* !bar
|
20
20
|
*
|
21
|
-
* would result in foo/bar being unignored again
|
21
|
+
* would result in foo/bar being unignored again while
|
22
|
+
*
|
23
|
+
* moo/foo/bar
|
24
|
+
* !foo/bar
|
25
|
+
*
|
26
|
+
* would do nothing. The reverse also holds true: a positive
|
27
|
+
* basename pattern can be negated by unignoring the basename in
|
28
|
+
* subdirectories. Thus
|
29
|
+
*
|
30
|
+
* bar
|
31
|
+
* !foo/bar
|
32
|
+
*
|
33
|
+
* would result in foo/bar being unignored again. As with the
|
34
|
+
* first case,
|
35
|
+
*
|
36
|
+
* foo/bar
|
37
|
+
* !moo/foo/bar
|
38
|
+
*
|
39
|
+
* would do nothing, again.
|
22
40
|
*/
|
23
41
|
static int does_negate_pattern(git_attr_fnmatch *rule, git_attr_fnmatch *neg)
|
24
42
|
{
|
43
|
+
git_attr_fnmatch *longer, *shorter;
|
25
44
|
char *p;
|
26
45
|
|
27
46
|
if ((rule->flags & GIT_ATTR_FNMATCH_NEGATIVE) == 0
|
28
47
|
&& (neg->flags & GIT_ATTR_FNMATCH_NEGATIVE) != 0) {
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
if (rule->length < neg->length)
|
48
|
+
|
49
|
+
/* If lengths match we need to have an exact match */
|
50
|
+
if (rule->length == neg->length) {
|
51
|
+
return strcmp(rule->pattern, neg->pattern) == 0;
|
52
|
+
} else if (rule->length < neg->length) {
|
53
|
+
shorter = rule;
|
54
|
+
longer = neg;
|
55
|
+
} else {
|
56
|
+
shorter = neg;
|
57
|
+
longer = rule;
|
58
|
+
}
|
59
|
+
|
60
|
+
/* Otherwise, we need to check if the shorter
|
61
|
+
* rule is a basename only (that is, it contains
|
62
|
+
* no path separator) and, if so, if it
|
63
|
+
* matches the tail of the longer rule */
|
64
|
+
p = longer->pattern + longer->length - shorter->length;
|
65
|
+
|
66
|
+
if (p[-1] != '/')
|
67
|
+
return false;
|
68
|
+
if (memchr(shorter->pattern, '/', shorter->length) != NULL)
|
34
69
|
return false;
|
35
70
|
|
36
|
-
|
37
|
-
* shift pattern so its tail aligns with the
|
38
|
-
* negated pattern
|
39
|
-
*/
|
40
|
-
p = rule->pattern + rule->length - neg->length;
|
41
|
-
if (strcmp(p, neg->pattern) == 0)
|
42
|
-
return true;
|
71
|
+
return memcmp(p, shorter->pattern, shorter->length) == 0;
|
43
72
|
}
|
44
73
|
|
45
74
|
return false;
|
data/vendor/libgit2/src/index.c
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
#include "blob.h"
|
20
20
|
#include "idxmap.h"
|
21
21
|
#include "diff.h"
|
22
|
+
#include "varint.h"
|
22
23
|
|
23
24
|
#include "git2/odb.h"
|
24
25
|
#include "git2/oid.h"
|
@@ -65,8 +66,11 @@ static int index_apply_to_wd_diff(git_index *index, int action, const git_strarr
|
|
65
66
|
static const size_t INDEX_FOOTER_SIZE = GIT_OID_RAWSZ;
|
66
67
|
static const size_t INDEX_HEADER_SIZE = 12;
|
67
68
|
|
68
|
-
static const unsigned int
|
69
|
+
static const unsigned int INDEX_VERSION_NUMBER_DEFAULT = 2;
|
70
|
+
static const unsigned int INDEX_VERSION_NUMBER_LB = 2;
|
69
71
|
static const unsigned int INDEX_VERSION_NUMBER_EXT = 3;
|
72
|
+
static const unsigned int INDEX_VERSION_NUMBER_COMP = 4;
|
73
|
+
static const unsigned int INDEX_VERSION_NUMBER_UB = 4;
|
70
74
|
|
71
75
|
static const unsigned int INDEX_HEADER_SIG = 0x44495243;
|
72
76
|
static const char INDEX_EXT_TREECACHE_SIG[] = {'T', 'R', 'E', 'E'};
|
@@ -434,6 +438,7 @@ int git_index_open(git_index **index_out, const char *index_path)
|
|
434
438
|
index->entries_search = git_index_entry_srch;
|
435
439
|
index->entries_search_path = index_entry_srch_path;
|
436
440
|
index->reuc_search = reuc_srch;
|
441
|
+
index->version = INDEX_VERSION_NUMBER_DEFAULT;
|
437
442
|
|
438
443
|
if (index_path != NULL && (error = git_index_read(index, true)) < 0)
|
439
444
|
goto fail;
|
@@ -505,10 +510,11 @@ static int index_remove_entry(git_index *index, size_t pos)
|
|
505
510
|
int error = 0;
|
506
511
|
git_index_entry *entry = git_vector_get(&index->entries, pos);
|
507
512
|
|
508
|
-
if (entry != NULL)
|
513
|
+
if (entry != NULL) {
|
509
514
|
git_tree_cache_invalidate_path(index->tree, entry->path);
|
515
|
+
DELETE_IN_MAP(index, entry);
|
516
|
+
}
|
510
517
|
|
511
|
-
DELETE_IN_MAP(index, entry);
|
512
518
|
error = git_vector_remove(&index->entries, pos);
|
513
519
|
|
514
520
|
if (!error) {
|
@@ -746,6 +752,28 @@ done:
|
|
746
752
|
return 0;
|
747
753
|
}
|
748
754
|
|
755
|
+
unsigned git_index_version(git_index *index)
|
756
|
+
{
|
757
|
+
assert(index);
|
758
|
+
|
759
|
+
return index->version;
|
760
|
+
}
|
761
|
+
|
762
|
+
int git_index_set_version(git_index *index, unsigned int version)
|
763
|
+
{
|
764
|
+
assert(index);
|
765
|
+
|
766
|
+
if (version < INDEX_VERSION_NUMBER_LB ||
|
767
|
+
version > INDEX_VERSION_NUMBER_UB) {
|
768
|
+
giterr_set(GITERR_INDEX, "Invalid version number");
|
769
|
+
return -1;
|
770
|
+
}
|
771
|
+
|
772
|
+
index->version = version;
|
773
|
+
|
774
|
+
return 0;
|
775
|
+
}
|
776
|
+
|
749
777
|
int git_index_write(git_index *index)
|
750
778
|
{
|
751
779
|
git_indexwriter writer = GIT_INDEXWRITER_INIT;
|
@@ -2159,12 +2187,12 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
|
|
2159
2187
|
|
2160
2188
|
if (git__strtol64(&tmp, buffer, &endptr, 8) < 0 ||
|
2161
2189
|
!endptr || endptr == buffer || *endptr ||
|
2162
|
-
tmp < 0) {
|
2190
|
+
tmp < 0 || tmp > UINT32_MAX) {
|
2163
2191
|
index_entry_reuc_free(lost);
|
2164
2192
|
return index_error_invalid("reading reuc entry stage");
|
2165
2193
|
}
|
2166
2194
|
|
2167
|
-
lost->mode[i] = tmp;
|
2195
|
+
lost->mode[i] = (uint32_t)tmp;
|
2168
2196
|
|
2169
2197
|
len = (endptr + 1) - buffer;
|
2170
2198
|
if (size <= len) {
|
@@ -2261,12 +2289,15 @@ static size_t read_entry(
|
|
2261
2289
|
git_index_entry **out,
|
2262
2290
|
git_index *index,
|
2263
2291
|
const void *buffer,
|
2264
|
-
size_t buffer_size
|
2292
|
+
size_t buffer_size,
|
2293
|
+
const char **last)
|
2265
2294
|
{
|
2266
2295
|
size_t path_length, entry_size;
|
2267
2296
|
const char *path_ptr;
|
2268
2297
|
struct entry_short source;
|
2269
2298
|
git_index_entry entry = {{0}};
|
2299
|
+
bool compressed = index->version >= INDEX_VERSION_NUMBER_COMP;
|
2300
|
+
char *tmp_path = NULL;
|
2270
2301
|
|
2271
2302
|
if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size)
|
2272
2303
|
return 0;
|
@@ -2301,33 +2332,56 @@ static size_t read_entry(
|
|
2301
2332
|
} else
|
2302
2333
|
path_ptr = (const char *) buffer + offsetof(struct entry_short, path);
|
2303
2334
|
|
2304
|
-
|
2335
|
+
if (!compressed) {
|
2336
|
+
path_length = entry.flags & GIT_IDXENTRY_NAMEMASK;
|
2305
2337
|
|
2306
|
-
|
2307
|
-
|
2308
|
-
|
2309
|
-
|
2338
|
+
/* if this is a very long string, we must find its
|
2339
|
+
* real length without overflowing */
|
2340
|
+
if (path_length == 0xFFF) {
|
2341
|
+
const char *path_end;
|
2310
2342
|
|
2311
|
-
|
2312
|
-
|
2313
|
-
|
2314
|
-
|
2315
|
-
path_length = path_end - path_ptr;
|
2316
|
-
}
|
2343
|
+
path_end = memchr(path_ptr, '\0', buffer_size);
|
2344
|
+
if (path_end == NULL)
|
2345
|
+
return 0;
|
2317
2346
|
|
2318
|
-
|
2319
|
-
|
2320
|
-
else
|
2321
|
-
entry_size = short_entry_size(path_length);
|
2347
|
+
path_length = path_end - path_ptr;
|
2348
|
+
}
|
2322
2349
|
|
2323
|
-
|
2324
|
-
|
2350
|
+
if (entry.flags & GIT_IDXENTRY_EXTENDED)
|
2351
|
+
entry_size = long_entry_size(path_length);
|
2352
|
+
else
|
2353
|
+
entry_size = short_entry_size(path_length);
|
2325
2354
|
|
2326
|
-
|
2355
|
+
if (INDEX_FOOTER_SIZE + entry_size > buffer_size)
|
2356
|
+
return 0;
|
2327
2357
|
|
2328
|
-
|
2358
|
+
entry.path = (char *)path_ptr;
|
2359
|
+
} else {
|
2360
|
+
size_t varint_len;
|
2361
|
+
size_t shared = git_decode_varint((const unsigned char *)path_ptr,
|
2362
|
+
&varint_len);
|
2363
|
+
size_t len = strlen(path_ptr + varint_len);
|
2364
|
+
size_t last_len = strlen(*last);
|
2365
|
+
size_t tmp_path_len;
|
2366
|
+
|
2367
|
+
if (varint_len == 0)
|
2368
|
+
return index_error_invalid("incorrect prefix length");
|
2369
|
+
|
2370
|
+
GITERR_CHECK_ALLOC_ADD(&tmp_path_len, shared, len + 1);
|
2371
|
+
tmp_path = git__malloc(tmp_path_len);
|
2372
|
+
GITERR_CHECK_ALLOC(tmp_path);
|
2373
|
+
memcpy(tmp_path, last, last_len);
|
2374
|
+
memcpy(tmp_path + last_len, path_ptr + varint_len, len);
|
2375
|
+
entry_size = long_entry_size(shared + len);
|
2376
|
+
entry.path = tmp_path;
|
2377
|
+
}
|
2378
|
+
|
2379
|
+
if (index_entry_dup(out, index, &entry) < 0) {
|
2380
|
+
git__free(tmp_path);
|
2329
2381
|
return 0;
|
2382
|
+
}
|
2330
2383
|
|
2384
|
+
git__free(tmp_path);
|
2331
2385
|
return entry_size;
|
2332
2386
|
}
|
2333
2387
|
|
@@ -2340,8 +2394,8 @@ static int read_header(struct index_header *dest, const void *buffer)
|
|
2340
2394
|
return index_error_invalid("incorrect header signature");
|
2341
2395
|
|
2342
2396
|
dest->version = ntohl(source->version);
|
2343
|
-
if (dest->version
|
2344
|
-
dest->version
|
2397
|
+
if (dest->version < INDEX_VERSION_NUMBER_LB ||
|
2398
|
+
dest->version > INDEX_VERSION_NUMBER_UB)
|
2345
2399
|
return index_error_invalid("incorrect header version");
|
2346
2400
|
|
2347
2401
|
dest->entry_count = ntohl(source->entry_count);
|
@@ -2394,6 +2448,8 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
|
2394
2448
|
unsigned int i;
|
2395
2449
|
struct index_header header = { 0 };
|
2396
2450
|
git_oid checksum_calculated, checksum_expected;
|
2451
|
+
const char **last = NULL;
|
2452
|
+
const char *empty = "";
|
2397
2453
|
|
2398
2454
|
#define seek_forward(_increase) { \
|
2399
2455
|
if (_increase >= buffer_size) { \
|
@@ -2414,6 +2470,10 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
|
2414
2470
|
if ((error = read_header(&header, buffer)) < 0)
|
2415
2471
|
return error;
|
2416
2472
|
|
2473
|
+
index->version = header.version;
|
2474
|
+
if (index->version >= INDEX_VERSION_NUMBER_COMP)
|
2475
|
+
last = ∅
|
2476
|
+
|
2417
2477
|
seek_forward(INDEX_HEADER_SIZE);
|
2418
2478
|
|
2419
2479
|
assert(!index->entries.length);
|
@@ -2426,7 +2486,7 @@ static int parse_index(git_index *index, const char *buffer, size_t buffer_size)
|
|
2426
2486
|
/* Parse all the entries */
|
2427
2487
|
for (i = 0; i < header.entry_count && buffer_size > INDEX_FOOTER_SIZE; ++i) {
|
2428
2488
|
git_index_entry *entry;
|
2429
|
-
size_t entry_size = read_entry(&entry, index, buffer, buffer_size);
|
2489
|
+
size_t entry_size = read_entry(&entry, index, buffer, buffer_size, last);
|
2430
2490
|
|
2431
2491
|
/* 0 bytes read means an object corruption */
|
2432
2492
|
if (entry_size == 0) {
|
@@ -2517,15 +2577,31 @@ static bool is_index_extended(git_index *index)
|
|
2517
2577
|
return (extended > 0);
|
2518
2578
|
}
|
2519
2579
|
|
2520
|
-
static int write_disk_entry(git_filebuf *file, git_index_entry *entry)
|
2580
|
+
static int write_disk_entry(git_filebuf *file, git_index_entry *entry, const char **last)
|
2521
2581
|
{
|
2522
2582
|
void *mem = NULL;
|
2523
2583
|
struct entry_short *ondisk;
|
2524
2584
|
size_t path_len, disk_size;
|
2525
2585
|
char *path;
|
2586
|
+
const char *path_start = entry->path;
|
2587
|
+
size_t same_len = 0;
|
2526
2588
|
|
2527
2589
|
path_len = ((struct entry_internal *)entry)->pathlen;
|
2528
2590
|
|
2591
|
+
if (last) {
|
2592
|
+
const char *last_c = *last;
|
2593
|
+
|
2594
|
+
while (*path_start == *last_c) {
|
2595
|
+
if (!*path_start || !*last_c)
|
2596
|
+
break;
|
2597
|
+
++path_start;
|
2598
|
+
++last_c;
|
2599
|
+
++same_len;
|
2600
|
+
}
|
2601
|
+
path_len -= same_len;
|
2602
|
+
*last = entry->path;
|
2603
|
+
}
|
2604
|
+
|
2529
2605
|
if (entry->flags & GIT_IDXENTRY_EXTENDED)
|
2530
2606
|
disk_size = long_entry_size(path_len);
|
2531
2607
|
else
|
@@ -2573,7 +2649,12 @@ static int write_disk_entry(git_filebuf *file, git_index_entry *entry)
|
|
2573
2649
|
else
|
2574
2650
|
path = ondisk->path;
|
2575
2651
|
|
2576
|
-
|
2652
|
+
if (last) {
|
2653
|
+
path += git_encode_varint((unsigned char *) path,
|
2654
|
+
disk_size,
|
2655
|
+
path_len - same_len);
|
2656
|
+
}
|
2657
|
+
memcpy(path, path_start, path_len);
|
2577
2658
|
|
2578
2659
|
return 0;
|
2579
2660
|
}
|
@@ -2584,6 +2665,8 @@ static int write_entries(git_index *index, git_filebuf *file)
|
|
2584
2665
|
size_t i;
|
2585
2666
|
git_vector case_sorted, *entries;
|
2586
2667
|
git_index_entry *entry;
|
2668
|
+
const char **last = NULL;
|
2669
|
+
const char *empty = "";
|
2587
2670
|
|
2588
2671
|
/* If index->entries is sorted case-insensitively, then we need
|
2589
2672
|
* to re-sort it case-sensitively before writing */
|
@@ -2595,8 +2678,11 @@ static int write_entries(git_index *index, git_filebuf *file)
|
|
2595
2678
|
entries = &index->entries;
|
2596
2679
|
}
|
2597
2680
|
|
2681
|
+
if (index->version >= INDEX_VERSION_NUMBER_COMP)
|
2682
|
+
last = ∅
|
2683
|
+
|
2598
2684
|
git_vector_foreach(entries, i, entry)
|
2599
|
-
if ((error = write_disk_entry(file, entry)) < 0)
|
2685
|
+
if ((error = write_disk_entry(file, entry, last)) < 0)
|
2600
2686
|
break;
|
2601
2687
|
|
2602
2688
|
if (index->ignore_case)
|
@@ -2761,8 +2847,12 @@ static int write_index(git_oid *checksum, git_index *index, git_filebuf *file)
|
|
2761
2847
|
|
2762
2848
|
assert(index && file);
|
2763
2849
|
|
2764
|
-
|
2765
|
-
|
2850
|
+
if (index->version <= INDEX_VERSION_NUMBER_EXT) {
|
2851
|
+
is_extended = is_index_extended(index);
|
2852
|
+
index_version_number = is_extended ? INDEX_VERSION_NUMBER_EXT : INDEX_VERSION_NUMBER_LB;
|
2853
|
+
} else {
|
2854
|
+
index_version_number = index->version;
|
2855
|
+
}
|
2766
2856
|
|
2767
2857
|
header.signature = htonl(INDEX_HEADER_SIG);
|
2768
2858
|
header.version = htonl(index_version_number);
|
@@ -2924,38 +3014,39 @@ cleanup:
|
|
2924
3014
|
return error;
|
2925
3015
|
}
|
2926
3016
|
|
2927
|
-
int
|
3017
|
+
static int git_index_read_iterator(
|
2928
3018
|
git_index *index,
|
2929
|
-
|
3019
|
+
git_iterator *new_iterator,
|
3020
|
+
size_t new_length_hint)
|
2930
3021
|
{
|
2931
3022
|
git_vector new_entries = GIT_VECTOR_INIT,
|
2932
3023
|
remove_entries = GIT_VECTOR_INIT;
|
2933
3024
|
git_idxmap *new_entries_map = NULL;
|
2934
3025
|
git_iterator *index_iterator = NULL;
|
2935
|
-
git_iterator *new_iterator = NULL;
|
2936
3026
|
git_iterator_options opts = GIT_ITERATOR_OPTIONS_INIT;
|
2937
3027
|
const git_index_entry *old_entry, *new_entry;
|
2938
3028
|
git_index_entry *entry;
|
2939
3029
|
size_t i;
|
2940
3030
|
int error;
|
2941
3031
|
|
2942
|
-
|
3032
|
+
assert((new_iterator->flags & GIT_ITERATOR_DONT_IGNORE_CASE));
|
3033
|
+
|
3034
|
+
if ((error = git_vector_init(&new_entries, new_length_hint, index->entries._cmp)) < 0 ||
|
2943
3035
|
(error = git_vector_init(&remove_entries, index->entries.length, NULL)) < 0 ||
|
2944
3036
|
(error = git_idxmap_alloc(&new_entries_map)) < 0)
|
2945
3037
|
goto done;
|
2946
3038
|
|
2947
|
-
if (index->ignore_case)
|
2948
|
-
kh_resize(idxicase, (khash_t(idxicase) *) new_entries_map,
|
2949
|
-
else
|
2950
|
-
kh_resize(idx, new_entries_map,
|
2951
|
-
|
2952
|
-
opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE;
|
3039
|
+
if (index->ignore_case && new_length_hint)
|
3040
|
+
kh_resize(idxicase, (khash_t(idxicase) *) new_entries_map, new_length_hint);
|
3041
|
+
else if (new_length_hint)
|
3042
|
+
kh_resize(idx, new_entries_map, new_length_hint);
|
2953
3043
|
|
2954
|
-
|
2955
|
-
|
2956
|
-
goto done;
|
3044
|
+
opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE |
|
3045
|
+
GIT_ITERATOR_INCLUDE_CONFLICTS;
|
2957
3046
|
|
2958
|
-
if ((
|
3047
|
+
if ((error = git_iterator_for_index(&index_iterator,
|
3048
|
+
git_index_owner(index), index, &opts)) < 0 ||
|
3049
|
+
((error = git_iterator_current(&old_entry, index_iterator)) < 0 &&
|
2959
3050
|
error != GIT_ITEROVER) ||
|
2960
3051
|
((error = git_iterator_current(&new_entry, new_iterator)) < 0 &&
|
2961
3052
|
error != GIT_ITEROVER))
|
@@ -3049,6 +3140,8 @@ int git_index_read_index(
|
|
3049
3140
|
index_entry_free(entry);
|
3050
3141
|
}
|
3051
3142
|
|
3143
|
+
clear_uptodate(index);
|
3144
|
+
|
3052
3145
|
error = 0;
|
3053
3146
|
|
3054
3147
|
done:
|
@@ -3056,6 +3149,27 @@ done:
|
|
3056
3149
|
git_vector_free(&new_entries);
|
3057
3150
|
git_vector_free(&remove_entries);
|
3058
3151
|
git_iterator_free(index_iterator);
|
3152
|
+
return error;
|
3153
|
+
}
|
3154
|
+
|
3155
|
+
int git_index_read_index(
|
3156
|
+
git_index *index,
|
3157
|
+
const git_index *new_index)
|
3158
|
+
{
|
3159
|
+
git_iterator *new_iterator = NULL;
|
3160
|
+
git_iterator_options opts = GIT_ITERATOR_OPTIONS_INIT;
|
3161
|
+
int error;
|
3162
|
+
|
3163
|
+
opts.flags = GIT_ITERATOR_DONT_IGNORE_CASE |
|
3164
|
+
GIT_ITERATOR_INCLUDE_CONFLICTS;
|
3165
|
+
|
3166
|
+
if ((error = git_iterator_for_index(&new_iterator,
|
3167
|
+
git_index_owner(new_index), (git_index *)new_index, &opts)) < 0 ||
|
3168
|
+
(error = git_index_read_iterator(index, new_iterator,
|
3169
|
+
new_index->entries.length)) < 0)
|
3170
|
+
goto done;
|
3171
|
+
|
3172
|
+
done:
|
3059
3173
|
git_iterator_free(new_iterator);
|
3060
3174
|
return error;
|
3061
3175
|
}
|