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
@@ -292,7 +292,7 @@ GIT_EXTERN(int) git_cred_username_new(git_cred **cred, const char *username);
|
|
292
292
|
*
|
293
293
|
* - cred: The newly created credential object.
|
294
294
|
* - url: The resource for which we are demanding a credential.
|
295
|
-
* - username_from_url: The username that was embedded in a "user
|
295
|
+
* - username_from_url: The username that was embedded in a "user\@host"
|
296
296
|
* remote url, or NULL if not included.
|
297
297
|
* - allowed_types: A bitmask stating which cred types are OK to return.
|
298
298
|
* - payload: The payload provided when specifying this callback.
|
@@ -302,9 +302,7 @@ typedef struct {
|
|
302
302
|
/**
|
303
303
|
* Callback for the user's custom certificate checks.
|
304
304
|
*
|
305
|
-
* @param
|
306
|
-
* @param data The data for the certificate or host info
|
307
|
-
* @param len The size of the certificate or host info
|
305
|
+
* @param cert The host certificate
|
308
306
|
* @param valid Whether the libgit2 checks (OpenSSL or WinHTTP) think
|
309
307
|
* this certificate is valid
|
310
308
|
* @param host Hostname of the host libgit2 connected to
|
@@ -412,6 +410,15 @@ typedef enum {
|
|
412
410
|
GIT_SUBMODULE_RECURSE_ONDEMAND = 2,
|
413
411
|
} git_submodule_recurse_t;
|
414
412
|
|
413
|
+
/** A type to write in a streaming fashion, for example, for filters. */
|
414
|
+
typedef struct git_writestream git_writestream;
|
415
|
+
|
416
|
+
struct git_writestream {
|
417
|
+
int (*write)(git_writestream *stream, const char *buffer, size_t len);
|
418
|
+
int (*close)(git_writestream *stream);
|
419
|
+
void (*free)(git_writestream *stream);
|
420
|
+
};
|
421
|
+
|
415
422
|
/** @} */
|
416
423
|
GIT_END_DECL
|
417
424
|
|
@@ -7,10 +7,11 @@
|
|
7
7
|
#ifndef INCLUDE_git_version_h__
|
8
8
|
#define INCLUDE_git_version_h__
|
9
9
|
|
10
|
-
#define LIBGIT2_VERSION "0.22.
|
10
|
+
#define LIBGIT2_VERSION "0.22.0"
|
11
11
|
#define LIBGIT2_VER_MAJOR 0
|
12
12
|
#define LIBGIT2_VER_MINOR 22
|
13
|
-
#define LIBGIT2_VER_REVISION
|
13
|
+
#define LIBGIT2_VER_REVISION 0
|
14
|
+
#define LIBGIT2_VER_PATCH 0
|
14
15
|
|
15
16
|
#define LIBGIT2_SOVERSION 22
|
16
17
|
|
@@ -12,6 +12,7 @@
|
|
12
12
|
#include "git2/refs.h"
|
13
13
|
#include "git2/repository.h"
|
14
14
|
#include "git2/annotated_commit.h"
|
15
|
+
#include "git2/revparse.h"
|
15
16
|
|
16
17
|
static int annotated_commit_init(
|
17
18
|
git_annotated_commit **out,
|
@@ -96,6 +97,33 @@ int git_annotated_commit_from_fetchhead(
|
|
96
97
|
return annotated_commit_init(out, repo, id, branch_name, remote_url);
|
97
98
|
}
|
98
99
|
|
100
|
+
int git_annotated_commit_from_revspec(
|
101
|
+
git_annotated_commit **out,
|
102
|
+
git_repository *repo,
|
103
|
+
const char *revspec)
|
104
|
+
{
|
105
|
+
git_object *obj, *commit;
|
106
|
+
int error;
|
107
|
+
|
108
|
+
assert(out && repo && revspec);
|
109
|
+
|
110
|
+
if ((error = git_revparse_single(&obj, repo, revspec)) < 0)
|
111
|
+
return error;
|
112
|
+
|
113
|
+
if ((error = git_object_peel(&commit, obj, GIT_OBJ_COMMIT))) {
|
114
|
+
git_object_free(obj);
|
115
|
+
return error;
|
116
|
+
}
|
117
|
+
|
118
|
+
error = annotated_commit_init(out, repo, git_object_id(commit), revspec, NULL);
|
119
|
+
|
120
|
+
git_object_free(obj);
|
121
|
+
git_object_free(commit);
|
122
|
+
|
123
|
+
return error;
|
124
|
+
}
|
125
|
+
|
126
|
+
|
99
127
|
const git_oid *git_annotated_commit_id(
|
100
128
|
const git_annotated_commit *annotated_commit)
|
101
129
|
{
|
data/vendor/libgit2/src/array.h
CHANGED
@@ -23,7 +23,7 @@
|
|
23
23
|
*
|
24
24
|
* typedef git_array_t(my_struct) my_struct_array_t;
|
25
25
|
*/
|
26
|
-
#define git_array_t(type) struct { type *ptr;
|
26
|
+
#define git_array_t(type) struct { type *ptr; size_t size, asize; }
|
27
27
|
|
28
28
|
#define GIT_ARRAY_INIT { NULL, 0, 0 }
|
29
29
|
|
@@ -45,15 +45,26 @@ typedef git_array_t(char) git_array_generic_t;
|
|
45
45
|
GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size)
|
46
46
|
{
|
47
47
|
volatile git_array_generic_t *a = _a;
|
48
|
-
|
49
|
-
char *new_array
|
50
|
-
|
51
|
-
|
52
|
-
|
48
|
+
size_t new_size;
|
49
|
+
char *new_array;
|
50
|
+
|
51
|
+
if (a->size < 8) {
|
52
|
+
new_size = 8;
|
53
53
|
} else {
|
54
|
-
|
55
|
-
|
54
|
+
if (GIT_MULTIPLY_SIZET_OVERFLOW(&new_size, a->size, 3))
|
55
|
+
goto on_oom;
|
56
|
+
new_size /= 2;
|
56
57
|
}
|
58
|
+
|
59
|
+
if ((new_array = git__reallocarray(a->ptr, new_size, item_size)) == NULL)
|
60
|
+
goto on_oom;
|
61
|
+
|
62
|
+
a->ptr = new_array; a->asize = new_size; a->size++;
|
63
|
+
return a->ptr + (a->size - 1) * item_size;
|
64
|
+
|
65
|
+
on_oom:
|
66
|
+
git_array_clear(*a);
|
67
|
+
return NULL;
|
57
68
|
}
|
58
69
|
|
59
70
|
#define git_array_alloc(a) \
|
data/vendor/libgit2/src/attr.c
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
#include "git2/oid.h"
|
8
8
|
#include <ctype.h>
|
9
9
|
|
10
|
-
GIT__USE_STRMAP
|
10
|
+
GIT__USE_STRMAP
|
11
11
|
|
12
12
|
const char *git_attr__true = "[internal]__TRUE__";
|
13
13
|
const char *git_attr__false = "[internal]__FALSE__";
|
@@ -29,6 +29,7 @@ git_attr_t git_attr_value(const char *attr)
|
|
29
29
|
|
30
30
|
static int collect_attr_files(
|
31
31
|
git_repository *repo,
|
32
|
+
git_attr_session *attr_session,
|
32
33
|
uint32_t flags,
|
33
34
|
const char *path,
|
34
35
|
git_vector *files);
|
@@ -57,7 +58,7 @@ int git_attr_get(
|
|
57
58
|
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo)) < 0)
|
58
59
|
return -1;
|
59
60
|
|
60
|
-
if ((error = collect_attr_files(repo, flags, pathname, &files)) < 0)
|
61
|
+
if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0)
|
61
62
|
goto cleanup;
|
62
63
|
|
63
64
|
memset(&attr, 0, sizeof(attr));
|
@@ -90,9 +91,10 @@ typedef struct {
|
|
90
91
|
git_attr_assignment *found;
|
91
92
|
} attr_get_many_info;
|
92
93
|
|
93
|
-
int
|
94
|
+
int git_attr_get_many_with_session(
|
94
95
|
const char **values,
|
95
96
|
git_repository *repo,
|
97
|
+
git_attr_session *attr_session,
|
96
98
|
uint32_t flags,
|
97
99
|
const char *pathname,
|
98
100
|
size_t num_attr,
|
@@ -115,7 +117,7 @@ int git_attr_get_many(
|
|
115
117
|
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo)) < 0)
|
116
118
|
return -1;
|
117
119
|
|
118
|
-
if ((error = collect_attr_files(repo, flags, pathname, &files)) < 0)
|
120
|
+
if ((error = collect_attr_files(repo, attr_session, flags, pathname, &files)) < 0)
|
119
121
|
goto cleanup;
|
120
122
|
|
121
123
|
info = git__calloc(num_attr, sizeof(attr_get_many_info));
|
@@ -161,6 +163,17 @@ cleanup:
|
|
161
163
|
return error;
|
162
164
|
}
|
163
165
|
|
166
|
+
int git_attr_get_many(
|
167
|
+
const char **values,
|
168
|
+
git_repository *repo,
|
169
|
+
uint32_t flags,
|
170
|
+
const char *pathname,
|
171
|
+
size_t num_attr,
|
172
|
+
const char **names)
|
173
|
+
{
|
174
|
+
return git_attr_get_many_with_session(
|
175
|
+
values, repo, NULL, flags, pathname, num_attr, names);
|
176
|
+
}
|
164
177
|
|
165
178
|
int git_attr_foreach(
|
166
179
|
git_repository *repo,
|
@@ -183,7 +196,7 @@ int git_attr_foreach(
|
|
183
196
|
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo)) < 0)
|
184
197
|
return -1;
|
185
198
|
|
186
|
-
if ((error = collect_attr_files(repo, flags, pathname, &files)) < 0 ||
|
199
|
+
if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0 ||
|
187
200
|
(error = git_strmap_alloc(&seen)) < 0)
|
188
201
|
goto cleanup;
|
189
202
|
|
@@ -219,6 +232,7 @@ cleanup:
|
|
219
232
|
|
220
233
|
static int preload_attr_file(
|
221
234
|
git_repository *repo,
|
235
|
+
git_attr_session *attr_session,
|
222
236
|
git_attr_file_source source,
|
223
237
|
const char *base,
|
224
238
|
const char *file)
|
@@ -229,19 +243,60 @@ static int preload_attr_file(
|
|
229
243
|
if (!file)
|
230
244
|
return 0;
|
231
245
|
if (!(error = git_attr_cache__get(
|
232
|
-
&preload, repo, source, base, file, git_attr_file__parse_buffer)))
|
246
|
+
&preload, repo, attr_session, source, base, file, git_attr_file__parse_buffer)))
|
233
247
|
git_attr_file__free(preload);
|
234
248
|
|
235
249
|
return error;
|
236
250
|
}
|
237
251
|
|
238
|
-
static int
|
252
|
+
static int system_attr_file(
|
253
|
+
git_buf *out,
|
254
|
+
git_attr_session *attr_session)
|
255
|
+
{
|
256
|
+
int error;
|
257
|
+
|
258
|
+
if (!attr_session) {
|
259
|
+
error = git_sysdir_find_system_file(out, GIT_ATTR_FILE_SYSTEM);
|
260
|
+
|
261
|
+
if (error == GIT_ENOTFOUND)
|
262
|
+
giterr_clear();
|
263
|
+
|
264
|
+
return error;
|
265
|
+
}
|
266
|
+
|
267
|
+
if (!attr_session->init_sysdir) {
|
268
|
+
error = git_sysdir_find_system_file(&attr_session->sysdir, GIT_ATTR_FILE_SYSTEM);
|
269
|
+
|
270
|
+
if (error == GIT_ENOTFOUND)
|
271
|
+
giterr_clear();
|
272
|
+
else if (error)
|
273
|
+
return error;
|
274
|
+
|
275
|
+
attr_session->init_sysdir = 1;
|
276
|
+
}
|
277
|
+
|
278
|
+
if (attr_session->sysdir.size == 0)
|
279
|
+
return GIT_ENOTFOUND;
|
280
|
+
|
281
|
+
/* We can safely provide a git_buf with no allocation (asize == 0) to
|
282
|
+
* a consumer. This allows them to treat this as a regular `git_buf`,
|
283
|
+
* but their call to `git_buf_free` will not attempt to free it.
|
284
|
+
*/
|
285
|
+
git_buf_attach_notowned(
|
286
|
+
out, attr_session->sysdir.ptr, attr_session->sysdir.size);
|
287
|
+
return 0;
|
288
|
+
}
|
289
|
+
|
290
|
+
static int attr_setup(git_repository *repo, git_attr_session *attr_session)
|
239
291
|
{
|
240
292
|
int error = 0;
|
241
293
|
const char *workdir = git_repository_workdir(repo);
|
242
294
|
git_index *idx = NULL;
|
243
295
|
git_buf sys = GIT_BUF_INIT;
|
244
296
|
|
297
|
+
if (attr_session && attr_session->init_setup)
|
298
|
+
return 0;
|
299
|
+
|
245
300
|
if ((error = git_attr_cache__init(repo)) < 0)
|
246
301
|
return error;
|
247
302
|
|
@@ -249,39 +304,39 @@ static int attr_setup(git_repository *repo)
|
|
249
304
|
* definitions will be available for later file parsing
|
250
305
|
*/
|
251
306
|
|
252
|
-
|
307
|
+
error = system_attr_file(&sys, attr_session);
|
308
|
+
|
309
|
+
if (error == 0)
|
253
310
|
error = preload_attr_file(
|
254
|
-
repo, GIT_ATTR_FILE__FROM_FILE, NULL, sys.ptr);
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
giterr_clear();
|
260
|
-
error = 0;
|
261
|
-
} else
|
262
|
-
return error;
|
263
|
-
}
|
311
|
+
repo, attr_session, GIT_ATTR_FILE__FROM_FILE, NULL, sys.ptr);
|
312
|
+
else if (error != GIT_ENOTFOUND)
|
313
|
+
return error;
|
314
|
+
|
315
|
+
git_buf_free(&sys);
|
264
316
|
|
265
317
|
if ((error = preload_attr_file(
|
266
|
-
repo, GIT_ATTR_FILE__FROM_FILE,
|
318
|
+
repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
|
267
319
|
NULL, git_repository_attr_cache(repo)->cfg_attr_file)) < 0)
|
268
320
|
return error;
|
269
321
|
|
270
322
|
if ((error = preload_attr_file(
|
271
|
-
repo, GIT_ATTR_FILE__FROM_FILE,
|
323
|
+
repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
|
272
324
|
git_repository_path(repo), GIT_ATTR_FILE_INREPO)) < 0)
|
273
325
|
return error;
|
274
326
|
|
275
327
|
if (workdir != NULL &&
|
276
328
|
(error = preload_attr_file(
|
277
|
-
repo, GIT_ATTR_FILE__FROM_FILE, workdir, GIT_ATTR_FILE)) < 0)
|
329
|
+
repo, attr_session, GIT_ATTR_FILE__FROM_FILE, workdir, GIT_ATTR_FILE)) < 0)
|
278
330
|
return error;
|
279
331
|
|
280
332
|
if ((error = git_repository_index__weakptr(&idx, repo)) < 0 ||
|
281
333
|
(error = preload_attr_file(
|
282
|
-
repo, GIT_ATTR_FILE__FROM_INDEX, NULL, GIT_ATTR_FILE)) < 0)
|
334
|
+
repo, attr_session, GIT_ATTR_FILE__FROM_INDEX, NULL, GIT_ATTR_FILE)) < 0)
|
283
335
|
return error;
|
284
336
|
|
337
|
+
if (attr_session)
|
338
|
+
attr_session->init_setup = 1;
|
339
|
+
|
285
340
|
return error;
|
286
341
|
}
|
287
342
|
|
@@ -321,6 +376,7 @@ int git_attr_add_macro(
|
|
321
376
|
|
322
377
|
typedef struct {
|
323
378
|
git_repository *repo;
|
379
|
+
git_attr_session *attr_session;
|
324
380
|
uint32_t flags;
|
325
381
|
const char *workdir;
|
326
382
|
git_index *index;
|
@@ -356,6 +412,7 @@ static int attr_decide_sources(
|
|
356
412
|
|
357
413
|
static int push_attr_file(
|
358
414
|
git_repository *repo,
|
415
|
+
git_attr_session *attr_session,
|
359
416
|
git_vector *list,
|
360
417
|
git_attr_file_source source,
|
361
418
|
const char *base,
|
@@ -364,8 +421,9 @@ static int push_attr_file(
|
|
364
421
|
int error = 0;
|
365
422
|
git_attr_file *file = NULL;
|
366
423
|
|
367
|
-
error = git_attr_cache__get(
|
368
|
-
|
424
|
+
error = git_attr_cache__get(&file, repo, attr_session,
|
425
|
+
source, base, filename, git_attr_file__parse_buffer);
|
426
|
+
|
369
427
|
if (error < 0)
|
370
428
|
return error;
|
371
429
|
|
@@ -387,8 +445,8 @@ static int push_one_attr(void *ref, const char *path)
|
|
387
445
|
info->flags, info->workdir != NULL, info->index != NULL, src);
|
388
446
|
|
389
447
|
for (i = 0; !error && i < n_src; ++i)
|
390
|
-
error = push_attr_file(
|
391
|
-
info->
|
448
|
+
error = push_attr_file(info->repo, info->attr_session,
|
449
|
+
info->files, src[i], path, GIT_ATTR_FILE);
|
392
450
|
|
393
451
|
return error;
|
394
452
|
}
|
@@ -407,6 +465,7 @@ static void release_attr_files(git_vector *files)
|
|
407
465
|
|
408
466
|
static int collect_attr_files(
|
409
467
|
git_repository *repo,
|
468
|
+
git_attr_session *attr_session,
|
410
469
|
uint32_t flags,
|
411
470
|
const char *path,
|
412
471
|
git_vector *files)
|
@@ -416,7 +475,7 @@ static int collect_attr_files(
|
|
416
475
|
const char *workdir = git_repository_workdir(repo);
|
417
476
|
attr_walk_up_info info = { NULL };
|
418
477
|
|
419
|
-
if ((error = attr_setup(repo)) < 0)
|
478
|
+
if ((error = attr_setup(repo, attr_session)) < 0)
|
420
479
|
return error;
|
421
480
|
|
422
481
|
/* Resolve path in a non-bare repo */
|
@@ -435,12 +494,13 @@ static int collect_attr_files(
|
|
435
494
|
*/
|
436
495
|
|
437
496
|
error = push_attr_file(
|
438
|
-
repo, files, GIT_ATTR_FILE__FROM_FILE,
|
497
|
+
repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
|
439
498
|
git_repository_path(repo), GIT_ATTR_FILE_INREPO);
|
440
499
|
if (error < 0)
|
441
500
|
goto cleanup;
|
442
501
|
|
443
|
-
info.repo
|
502
|
+
info.repo = repo;
|
503
|
+
info.attr_session = attr_session;
|
444
504
|
info.flags = flags;
|
445
505
|
info.workdir = workdir;
|
446
506
|
if (git_repository_index__weakptr(&info.index, repo) < 0)
|
@@ -457,21 +517,21 @@ static int collect_attr_files(
|
|
457
517
|
|
458
518
|
if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) {
|
459
519
|
error = push_attr_file(
|
460
|
-
repo, files, GIT_ATTR_FILE__FROM_FILE,
|
520
|
+
repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
|
461
521
|
NULL, git_repository_attr_cache(repo)->cfg_attr_file);
|
462
522
|
if (error < 0)
|
463
523
|
goto cleanup;
|
464
524
|
}
|
465
525
|
|
466
526
|
if ((flags & GIT_ATTR_CHECK_NO_SYSTEM) == 0) {
|
467
|
-
error =
|
527
|
+
error = system_attr_file(&dir, attr_session);
|
528
|
+
|
468
529
|
if (!error)
|
469
530
|
error = push_attr_file(
|
470
|
-
repo, files, GIT_ATTR_FILE__FROM_FILE,
|
471
|
-
|
472
|
-
|
531
|
+
repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
|
532
|
+
NULL, dir.ptr);
|
533
|
+
else if (error == GIT_ENOTFOUND)
|
473
534
|
error = 0;
|
474
|
-
}
|
475
535
|
}
|
476
536
|
|
477
537
|
cleanup:
|
@@ -96,6 +96,7 @@ static int attr_file_oid_from_index(
|
|
96
96
|
int git_attr_file__load(
|
97
97
|
git_attr_file **out,
|
98
98
|
git_repository *repo,
|
99
|
+
git_attr_session *attr_session,
|
99
100
|
git_attr_file_entry *entry,
|
100
101
|
git_attr_file_source source,
|
101
102
|
git_attr_file_parser parser)
|
@@ -105,6 +106,7 @@ int git_attr_file__load(
|
|
105
106
|
git_buf content = GIT_BUF_INIT;
|
106
107
|
git_attr_file *file;
|
107
108
|
struct stat st;
|
109
|
+
bool nonexistent = false;
|
108
110
|
|
109
111
|
*out = NULL;
|
110
112
|
|
@@ -127,22 +129,16 @@ int git_attr_file__load(
|
|
127
129
|
case GIT_ATTR_FILE__FROM_FILE: {
|
128
130
|
int fd;
|
129
131
|
|
130
|
-
|
131
|
-
return git_path_set_error(errno, entry->fullpath, "stat");
|
132
|
-
if (S_ISDIR(st.st_mode))
|
133
|
-
return GIT_ENOTFOUND;
|
134
|
-
|
135
|
-
/* For open or read errors, return ENOTFOUND to skip item */
|
132
|
+
/* For open or read errors, pretend that we got ENOTFOUND. */
|
136
133
|
/* TODO: issue warning when warning API is available */
|
137
134
|
|
138
|
-
if ((
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
return GIT_ENOTFOUND;
|
135
|
+
if (p_stat(entry->fullpath, &st) < 0 ||
|
136
|
+
S_ISDIR(st.st_mode) ||
|
137
|
+
(fd = git_futils_open_ro(entry->fullpath)) < 0 ||
|
138
|
+
(error = git_futils_readbuffer_fd(&content, fd, (size_t)st.st_size)) < 0)
|
139
|
+
nonexistent = true;
|
140
|
+
else
|
141
|
+
p_close(fd);
|
146
142
|
|
147
143
|
break;
|
148
144
|
}
|
@@ -154,13 +150,21 @@ int git_attr_file__load(
|
|
154
150
|
if ((error = git_attr_file__new(&file, entry, source)) < 0)
|
155
151
|
goto cleanup;
|
156
152
|
|
153
|
+
/* store the key of the attr_reader; don't bother with cache
|
154
|
+
* invalidation during the same attr reader session.
|
155
|
+
*/
|
156
|
+
if (attr_session)
|
157
|
+
file->session_key = attr_session->key;
|
158
|
+
|
157
159
|
if (parser && (error = parser(repo, file, git_buf_cstr(&content))) < 0) {
|
158
160
|
git_attr_file__free(file);
|
159
161
|
goto cleanup;
|
160
162
|
}
|
161
163
|
|
162
|
-
/* write cache
|
163
|
-
if (
|
164
|
+
/* write cache breakers */
|
165
|
+
if (nonexistent)
|
166
|
+
file->nonexistent = 1;
|
167
|
+
else if (source == GIT_ATTR_FILE__FROM_INDEX)
|
164
168
|
git_oid_cpy(&file->cache_data.oid, git_blob_id(blob));
|
165
169
|
else if (source == GIT_ATTR_FILE__FROM_FILE)
|
166
170
|
git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st);
|
@@ -175,11 +179,22 @@ cleanup:
|
|
175
179
|
return error;
|
176
180
|
}
|
177
181
|
|
178
|
-
int git_attr_file__out_of_date(
|
182
|
+
int git_attr_file__out_of_date(
|
183
|
+
git_repository *repo,
|
184
|
+
git_attr_session *attr_session,
|
185
|
+
git_attr_file *file)
|
179
186
|
{
|
180
187
|
if (!file)
|
181
188
|
return 1;
|
182
189
|
|
190
|
+
/* we are never out of date if we just created this data in the same
|
191
|
+
* attr_session; otherwise, nonexistent files must be invalidated
|
192
|
+
*/
|
193
|
+
if (attr_session && attr_session->key == file->session_key)
|
194
|
+
return 0;
|
195
|
+
else if (file->nonexistent)
|
196
|
+
return 1;
|
197
|
+
|
183
198
|
switch (file->source) {
|
184
199
|
case GIT_ATTR_FILE__IN_MEMORY:
|
185
200
|
return 0;
|
@@ -831,3 +846,22 @@ void git_attr_rule__free(git_attr_rule *rule)
|
|
831
846
|
git__free(rule);
|
832
847
|
}
|
833
848
|
|
849
|
+
int git_attr_session__init(git_attr_session *session, git_repository *repo)
|
850
|
+
{
|
851
|
+
assert(repo);
|
852
|
+
|
853
|
+
session->key = git_atomic_inc(&repo->attr_session_key);
|
854
|
+
|
855
|
+
return 0;
|
856
|
+
}
|
857
|
+
|
858
|
+
void git_attr_session__free(git_attr_session *session)
|
859
|
+
{
|
860
|
+
if (!session)
|
861
|
+
return;
|
862
|
+
|
863
|
+
git_buf_free(&session->sysdir);
|
864
|
+
git_buf_free(&session->tmp);
|
865
|
+
|
866
|
+
memset(session, 0, sizeof(git_attr_session));
|
867
|
+
}
|