rugged 0.23.0b1 → 0.23.0b2
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_note.c +7 -2
- data/ext/rugged/rugged_revwalk.c +321 -145
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/CMakeLists.txt +83 -8
- data/vendor/libgit2/cmake/Modules/FindCoreFoundation.cmake +9 -0
- data/vendor/libgit2/cmake/Modules/FindIconv.cmake +0 -3
- data/vendor/libgit2/cmake/Modules/FindSecurity.cmake +9 -0
- data/vendor/libgit2/deps/winhttp/urlmon.h +45 -0
- data/vendor/libgit2/deps/winhttp/winhttp.def +29 -0
- data/vendor/libgit2/deps/winhttp/winhttp.h +592 -0
- data/vendor/libgit2/deps/winhttp/winhttp64.def +29 -0
- data/vendor/libgit2/include/git2/diff.h +6 -1
- data/vendor/libgit2/include/git2/index.h +1 -1
- data/vendor/libgit2/include/git2/merge.h +2 -1
- data/vendor/libgit2/include/git2/notes.h +2 -2
- data/vendor/libgit2/include/git2/pack.h +12 -0
- data/vendor/libgit2/include/git2/push.h +30 -0
- data/vendor/libgit2/include/git2/rebase.h +36 -16
- data/vendor/libgit2/include/git2/remote.h +6 -0
- data/vendor/libgit2/include/git2/reset.h +2 -2
- data/vendor/libgit2/include/git2/revwalk.h +10 -8
- data/vendor/libgit2/include/git2/submodule.h +16 -0
- data/vendor/libgit2/include/git2/sys/transport.h +12 -4
- data/vendor/libgit2/include/git2/types.h +1 -0
- data/vendor/libgit2/src/attr.c +3 -3
- data/vendor/libgit2/src/attr_file.c +24 -3
- data/vendor/libgit2/src/attr_file.h +3 -1
- data/vendor/libgit2/src/checkout.c +31 -7
- data/vendor/libgit2/src/config.c +5 -6
- data/vendor/libgit2/src/config_file.c +533 -469
- data/vendor/libgit2/src/describe.c +1 -1
- data/vendor/libgit2/src/diff.c +20 -10
- data/vendor/libgit2/src/diff_driver.c +1 -1
- data/vendor/libgit2/src/diff_tform.c +8 -2
- data/vendor/libgit2/src/filter.c +6 -3
- data/vendor/libgit2/src/global.c +17 -15
- data/vendor/libgit2/src/global.h +3 -1
- data/vendor/libgit2/src/ignore.c +48 -8
- data/vendor/libgit2/src/ignore.h +1 -1
- data/vendor/libgit2/src/index.c +12 -8
- data/vendor/libgit2/src/iterator.c +133 -12
- data/vendor/libgit2/src/netops.h +2 -2
- data/vendor/libgit2/src/notes.c +40 -21
- data/vendor/libgit2/src/openssl_stream.c +5 -1
- data/vendor/libgit2/src/pack-objects.c +36 -0
- data/vendor/libgit2/src/path.c +277 -140
- data/vendor/libgit2/src/path.h +132 -60
- data/vendor/libgit2/src/posix.h +0 -1
- data/vendor/libgit2/src/push.c +43 -4
- data/vendor/libgit2/src/push.h +8 -1
- data/vendor/libgit2/src/rebase.c +139 -119
- data/vendor/libgit2/src/reflog.c +1 -1
- data/vendor/libgit2/src/refs.c +3 -5
- data/vendor/libgit2/src/remote.c +6 -5
- data/vendor/libgit2/src/repository.c +7 -3
- data/vendor/libgit2/src/reset.c +3 -3
- data/vendor/libgit2/src/revwalk.c +26 -2
- data/vendor/libgit2/src/settings.c +3 -3
- data/vendor/libgit2/src/stransport_stream.c +249 -0
- data/vendor/libgit2/src/stransport_stream.h +14 -0
- data/vendor/libgit2/src/submodule.c +26 -2
- data/vendor/libgit2/src/tls_stream.c +28 -0
- data/vendor/libgit2/src/tls_stream.h +21 -0
- data/vendor/libgit2/src/transport.c +4 -4
- data/vendor/libgit2/src/transports/git.c +4 -1
- data/vendor/libgit2/src/transports/http.c +6 -4
- data/vendor/libgit2/src/transports/local.c +2 -1
- data/vendor/libgit2/src/transports/smart.c +1 -1
- data/vendor/libgit2/src/transports/ssh.c +5 -1
- data/vendor/libgit2/src/transports/winhttp.c +30 -23
- data/vendor/libgit2/src/tree.c +2 -2
- data/vendor/libgit2/src/unix/posix.h +1 -0
- data/vendor/libgit2/src/util.h +117 -0
- data/vendor/libgit2/src/win32/buffer.c +55 -0
- data/vendor/libgit2/src/win32/buffer.h +18 -0
- data/vendor/libgit2/src/win32/path_w32.c +75 -0
- data/vendor/libgit2/src/win32/path_w32.h +3 -0
- data/vendor/libgit2/src/win32/posix.h +2 -2
- data/vendor/libgit2/src/win32/posix_w32.c +2 -118
- data/vendor/libgit2/src/win32/pthread.c +2 -0
- data/vendor/libgit2/src/win32/utf-conv.c +0 -4
- data/vendor/libgit2/src/win32/utf-conv.h +4 -0
- data/vendor/libgit2/src/win32/w32_util.h +72 -0
- metadata +14 -2
@@ -693,7 +693,7 @@ int git_describe_commit(
|
|
693
693
|
get_name, &data)) < 0)
|
694
694
|
goto cleanup;
|
695
695
|
|
696
|
-
if (git_oidmap_size(data.names) == 0) {
|
696
|
+
if (git_oidmap_size(data.names) == 0 && !opts->show_commit_oid_as_fallback) {
|
697
697
|
giterr_set(GITERR_DESCRIBE, "Cannot describe - "
|
698
698
|
"No reference found, cannot describe anything.");
|
699
699
|
error = -1;
|
data/vendor/libgit2/src/diff.c
CHANGED
@@ -621,7 +621,7 @@ int git_diff__oid_for_entry(
|
|
621
621
|
git_index *idx;
|
622
622
|
|
623
623
|
if (!(error = git_repository_index__weakptr(&idx, diff->repo))) {
|
624
|
-
|
624
|
+
git_oid_cpy(&entry.id, out);
|
625
625
|
error = git_index_add(idx, &entry);
|
626
626
|
}
|
627
627
|
}
|
@@ -806,15 +806,12 @@ static int maybe_modified(
|
|
806
806
|
* haven't calculated the OID of the new item, then calculate it now
|
807
807
|
*/
|
808
808
|
if (modified_uncertain && git_oid_iszero(&nitem->id)) {
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
&noid, diff, nitem, update_check)) < 0)
|
816
|
-
return error;
|
817
|
-
}
|
809
|
+
const git_oid *update_check =
|
810
|
+
DIFF_FLAG_IS_SET(diff, GIT_DIFF_UPDATE_INDEX) && omode == nmode ?
|
811
|
+
&oitem->id : NULL;
|
812
|
+
if ((error = git_diff__oid_for_entry(
|
813
|
+
&noid, diff, nitem, update_check)) < 0)
|
814
|
+
return error;
|
818
815
|
|
819
816
|
/* if oid matches, then mark unmodified (except submodules, where
|
820
817
|
* the filesystem content may be modified even if the oid still
|
@@ -825,6 +822,19 @@ static int maybe_modified(
|
|
825
822
|
status = GIT_DELTA_UNMODIFIED;
|
826
823
|
}
|
827
824
|
|
825
|
+
/* If we want case changes, then break this into a delete of the old
|
826
|
+
* and an add of the new so that consumers can act accordingly (eg,
|
827
|
+
* checkout will update the case on disk.)
|
828
|
+
*/
|
829
|
+
if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_CASE) &&
|
830
|
+
DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_CASECHANGE) &&
|
831
|
+
strcmp(oitem->path, nitem->path) != 0) {
|
832
|
+
|
833
|
+
if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem)))
|
834
|
+
error = diff_delta__from_one(diff, GIT_DELTA_ADDED, nitem);
|
835
|
+
return error;
|
836
|
+
}
|
837
|
+
|
828
838
|
return diff_delta__from_two(
|
829
839
|
diff, status, oitem, omode, nitem, nmode,
|
830
840
|
git_oid_iszero(&noid) ? NULL : &noid, matched_pathspec);
|
@@ -116,7 +116,7 @@ static int diff_driver_add_patterns(
|
|
116
116
|
if (error < 0)
|
117
117
|
break;
|
118
118
|
|
119
|
-
if ((error = regcomp(&pat->re, buf.ptr, regex_flags))
|
119
|
+
if ((error = regcomp(&pat->re, buf.ptr, regex_flags)) != 0) {
|
120
120
|
/* if regex fails to compile, warn? fail? */
|
121
121
|
error = giterr_set_regex(&pat->re, error);
|
122
122
|
regfree(&pat->re);
|
@@ -84,11 +84,14 @@ static git_diff_delta *diff_delta__merge_like_cgit(
|
|
84
84
|
* index (i.e. not in HEAD nor workdir) is given as empty.
|
85
85
|
*/
|
86
86
|
if (dup->status == GIT_DELTA_DELETED) {
|
87
|
-
if (a->status == GIT_DELTA_ADDED)
|
87
|
+
if (a->status == GIT_DELTA_ADDED) {
|
88
88
|
dup->status = GIT_DELTA_UNMODIFIED;
|
89
|
+
dup->nfiles = 2;
|
90
|
+
}
|
89
91
|
/* else don't overwrite DELETE status */
|
90
92
|
} else {
|
91
93
|
dup->status = a->status;
|
94
|
+
dup->nfiles = a->nfiles;
|
92
95
|
}
|
93
96
|
|
94
97
|
git_oid_cpy(&dup->old_file.id, &a->old_file.id);
|
@@ -118,10 +121,13 @@ static git_diff_delta *diff_delta__merge_like_cgit_reversed(
|
|
118
121
|
return dup;
|
119
122
|
|
120
123
|
if (dup->status == GIT_DELTA_DELETED) {
|
121
|
-
if (b->status == GIT_DELTA_ADDED)
|
124
|
+
if (b->status == GIT_DELTA_ADDED) {
|
122
125
|
dup->status = GIT_DELTA_UNMODIFIED;
|
126
|
+
dup->nfiles = 2;
|
127
|
+
}
|
123
128
|
} else {
|
124
129
|
dup->status = b->status;
|
130
|
+
dup->nfiles = b->nfiles;
|
125
131
|
}
|
126
132
|
|
127
133
|
git_oid_cpy(&dup->old_file.id, &b->old_file.id);
|
data/vendor/libgit2/src/filter.c
CHANGED
@@ -671,7 +671,7 @@ int git_filter_list_apply_to_data(
|
|
671
671
|
buf_stream_init(&writer, tgt);
|
672
672
|
|
673
673
|
if ((error = git_filter_list_stream_data(filters, src,
|
674
|
-
|
674
|
+
&writer.parent)) < 0)
|
675
675
|
return error;
|
676
676
|
|
677
677
|
assert(writer.complete);
|
@@ -690,7 +690,7 @@ int git_filter_list_apply_to_file(
|
|
690
690
|
buf_stream_init(&writer, out);
|
691
691
|
|
692
692
|
if ((error = git_filter_list_stream_file(
|
693
|
-
filters, repo, path,
|
693
|
+
filters, repo, path, &writer.parent)) < 0)
|
694
694
|
return error;
|
695
695
|
|
696
696
|
assert(writer.complete);
|
@@ -721,7 +721,7 @@ int git_filter_list_apply_to_blob(
|
|
721
721
|
buf_stream_init(&writer, out);
|
722
722
|
|
723
723
|
if ((error = git_filter_list_stream_blob(
|
724
|
-
filters, blob,
|
724
|
+
filters, blob, &writer.parent)) < 0)
|
725
725
|
return error;
|
726
726
|
|
727
727
|
assert(writer.complete);
|
@@ -809,6 +809,9 @@ static int proxy_stream_init(
|
|
809
809
|
proxy_stream->target = target;
|
810
810
|
proxy_stream->output = temp_buf ? temp_buf : &proxy_stream->temp_buf;
|
811
811
|
|
812
|
+
if (temp_buf)
|
813
|
+
git_buf_clear(temp_buf);
|
814
|
+
|
812
815
|
*out = (git_writestream *)proxy_stream;
|
813
816
|
return 0;
|
814
817
|
}
|
data/vendor/libgit2/src/global.c
CHANGED
@@ -17,7 +17,7 @@ git_mutex git__mwindow_mutex;
|
|
17
17
|
|
18
18
|
#define MAX_SHUTDOWN_CB 8
|
19
19
|
|
20
|
-
#ifdef
|
20
|
+
#ifdef GIT_OPENSSL
|
21
21
|
# include <openssl/ssl.h>
|
22
22
|
SSL_CTX *git__ssl_ctx;
|
23
23
|
# ifdef GIT_THREADS
|
@@ -57,7 +57,7 @@ static void git__shutdown(void)
|
|
57
57
|
}
|
58
58
|
}
|
59
59
|
|
60
|
-
#if defined(GIT_THREADS) && defined(
|
60
|
+
#if defined(GIT_THREADS) && defined(GIT_OPENSSL)
|
61
61
|
void openssl_locking_function(int mode, int n, const char *file, int line)
|
62
62
|
{
|
63
63
|
int lock;
|
@@ -89,7 +89,7 @@ static void shutdown_ssl_locking(void)
|
|
89
89
|
|
90
90
|
static void init_ssl(void)
|
91
91
|
{
|
92
|
-
#ifdef
|
92
|
+
#ifdef GIT_OPENSSL
|
93
93
|
long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
|
94
94
|
|
95
95
|
/* Older OpenSSL and MacOS OpenSSL doesn't have this */
|
@@ -118,7 +118,7 @@ static void init_ssl(void)
|
|
118
118
|
|
119
119
|
int git_openssl_set_locking(void)
|
120
120
|
{
|
121
|
-
#ifdef
|
121
|
+
#ifdef GIT_OPENSSL
|
122
122
|
# ifdef GIT_THREADS
|
123
123
|
int num_locks, i;
|
124
124
|
|
@@ -223,13 +223,10 @@ int git_libgit2_init(void)
|
|
223
223
|
|
224
224
|
static void synchronized_threads_shutdown(void)
|
225
225
|
{
|
226
|
-
void *ptr;
|
227
|
-
|
228
226
|
/* Shut down any subsystems that have global state */
|
229
227
|
git__shutdown();
|
230
228
|
|
231
|
-
|
232
|
-
git__global_state_cleanup(ptr);
|
229
|
+
git__free_tls_data();
|
233
230
|
|
234
231
|
TlsFree(_tls_index);
|
235
232
|
git_mutex_free(&git__mwindow_mutex);
|
@@ -270,15 +267,20 @@ git_global_st *git__global_state(void)
|
|
270
267
|
return ptr;
|
271
268
|
}
|
272
269
|
|
273
|
-
|
270
|
+
/**
|
271
|
+
* Free the TLS data associated with this thread.
|
272
|
+
* This should only be used by the thread as it
|
273
|
+
* is exiting.
|
274
|
+
*/
|
275
|
+
void git__free_tls_data(void)
|
274
276
|
{
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
git__free(ptr);
|
279
|
-
}
|
277
|
+
void *ptr = TlsGetValue(_tls_index);
|
278
|
+
if (!ptr)
|
279
|
+
return;
|
280
280
|
|
281
|
-
|
281
|
+
git__global_state_cleanup(ptr);
|
282
|
+
git__free(ptr);
|
283
|
+
TlsSetValue(_tls_index, NULL);
|
282
284
|
}
|
283
285
|
|
284
286
|
#elif defined(GIT_THREADS) && defined(_POSIX_THREADS)
|
data/vendor/libgit2/src/global.h
CHANGED
@@ -17,7 +17,7 @@ typedef struct {
|
|
17
17
|
char oid_fmt[GIT_OID_HEXSZ+1];
|
18
18
|
} git_global_st;
|
19
19
|
|
20
|
-
#ifdef
|
20
|
+
#ifdef GIT_OPENSSL
|
21
21
|
# include <openssl/ssl.h>
|
22
22
|
extern SSL_CTX *git__ssl_ctx;
|
23
23
|
#endif
|
@@ -32,4 +32,6 @@ typedef void (*git_global_shutdown_fn)(void);
|
|
32
32
|
|
33
33
|
extern void git__on_shutdown(git_global_shutdown_fn callback);
|
34
34
|
|
35
|
+
extern void git__free_tls_data(void);
|
36
|
+
|
35
37
|
#endif
|
data/vendor/libgit2/src/ignore.c
CHANGED
@@ -10,6 +10,41 @@
|
|
10
10
|
|
11
11
|
#define GIT_IGNORE_DEFAULT_RULES ".\n..\n.git\n"
|
12
12
|
|
13
|
+
/**
|
14
|
+
* A negative ignore pattern can match a positive one without
|
15
|
+
* wildcards if its pattern equals the tail of the positive
|
16
|
+
* pattern. Thus
|
17
|
+
*
|
18
|
+
* foo/bar
|
19
|
+
* !bar
|
20
|
+
*
|
21
|
+
* would result in foo/bar being unignored again.
|
22
|
+
*/
|
23
|
+
static int does_negate_pattern(git_attr_fnmatch *rule, git_attr_fnmatch *neg)
|
24
|
+
{
|
25
|
+
char *p;
|
26
|
+
|
27
|
+
if ((rule->flags & GIT_ATTR_FNMATCH_NEGATIVE) == 0
|
28
|
+
&& (neg->flags & GIT_ATTR_FNMATCH_NEGATIVE) != 0) {
|
29
|
+
/*
|
30
|
+
* no chance of matching if rule is shorter than
|
31
|
+
* the negated one
|
32
|
+
*/
|
33
|
+
if (rule->length < neg->length)
|
34
|
+
return false;
|
35
|
+
|
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;
|
43
|
+
}
|
44
|
+
|
45
|
+
return false;
|
46
|
+
}
|
47
|
+
|
13
48
|
/**
|
14
49
|
* A negative ignore can only unignore a file which is given explicitly before, thus
|
15
50
|
*
|
@@ -31,6 +66,8 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
|
|
31
66
|
char *path;
|
32
67
|
git_buf buf = GIT_BUF_INIT;
|
33
68
|
|
69
|
+
*out = 0;
|
70
|
+
|
34
71
|
/* path of the file relative to the workdir, so we match the rules in subdirs */
|
35
72
|
if (match->containing_dir) {
|
36
73
|
git_buf_puts(&buf, match->containing_dir);
|
@@ -41,9 +78,14 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
|
|
41
78
|
path = git_buf_detach(&buf);
|
42
79
|
|
43
80
|
git_vector_foreach(rules, i, rule) {
|
44
|
-
|
45
|
-
|
46
|
-
|
81
|
+
if (!(rule->flags & GIT_ATTR_FNMATCH_HASWILD)) {
|
82
|
+
if (does_negate_pattern(rule, match)) {
|
83
|
+
*out = 1;
|
84
|
+
goto out;
|
85
|
+
}
|
86
|
+
else
|
87
|
+
continue;
|
88
|
+
}
|
47
89
|
|
48
90
|
/*
|
49
91
|
* If we're dealing with a directory (which we know via the
|
@@ -62,7 +104,6 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
|
|
62
104
|
if (error < 0)
|
63
105
|
goto out;
|
64
106
|
|
65
|
-
|
66
107
|
if ((error = p_fnmatch(git_buf_cstr(&buf), path, FNM_PATHNAME)) < 0) {
|
67
108
|
giterr_set(GITERR_INVALID, "error matching pattern");
|
68
109
|
goto out;
|
@@ -76,7 +117,6 @@ static int does_negate_rule(int *out, git_vector *rules, git_attr_fnmatch *match
|
|
76
117
|
}
|
77
118
|
}
|
78
119
|
|
79
|
-
*out = 0;
|
80
120
|
error = 0;
|
81
121
|
|
82
122
|
out:
|
@@ -348,7 +388,7 @@ static bool ignore_lookup_in_rules(
|
|
348
388
|
}
|
349
389
|
|
350
390
|
int git_ignore__lookup(
|
351
|
-
int *out, git_ignores *ignores, const char *pathname)
|
391
|
+
int *out, git_ignores *ignores, const char *pathname, git_dir_flag dir_flag)
|
352
392
|
{
|
353
393
|
unsigned int i;
|
354
394
|
git_attr_file *file;
|
@@ -357,7 +397,7 @@ int git_ignore__lookup(
|
|
357
397
|
*out = GIT_IGNORE_NOTFOUND;
|
358
398
|
|
359
399
|
if (git_attr_path__init(
|
360
|
-
&path, pathname, git_repository_workdir(ignores->repo)) < 0)
|
400
|
+
&path, pathname, git_repository_workdir(ignores->repo), dir_flag) < 0)
|
361
401
|
return -1;
|
362
402
|
|
363
403
|
/* first process builtins - success means path was found */
|
@@ -430,7 +470,7 @@ int git_ignore_path_is_ignored(
|
|
430
470
|
memset(&path, 0, sizeof(path));
|
431
471
|
memset(&ignores, 0, sizeof(ignores));
|
432
472
|
|
433
|
-
if ((error = git_attr_path__init(&path, pathname, workdir)) < 0 ||
|
473
|
+
if ((error = git_attr_path__init(&path, pathname, workdir, GIT_DIR_FLAG_UNKNOWN)) < 0 ||
|
434
474
|
(error = git_ignore__for_path(repo, path.path, &ignores)) < 0)
|
435
475
|
goto cleanup;
|
436
476
|
|
data/vendor/libgit2/src/ignore.h
CHANGED
@@ -49,7 +49,7 @@ enum {
|
|
49
49
|
GIT_IGNORE_TRUE = 1,
|
50
50
|
};
|
51
51
|
|
52
|
-
extern int git_ignore__lookup(int *out, git_ignores *ign, const char *path);
|
52
|
+
extern int git_ignore__lookup(int *out, git_ignores *ign, const char *path, git_dir_flag dir_flag);
|
53
53
|
|
54
54
|
/* command line Git sometimes generates an error message if given a
|
55
55
|
* pathspec that contains an exact match to an ignored file (provided
|
data/vendor/libgit2/src/index.c
CHANGED
@@ -987,9 +987,10 @@ static int index_no_dups(void **old, void *new)
|
|
987
987
|
* it, then it will return an error **and also free the entry**. When
|
988
988
|
* it replaces an existing entry, it will update the entry_ptr with the
|
989
989
|
* actual entry in the index (and free the passed in one).
|
990
|
+
* trust_mode is whether we trust the mode in entry_ptr.
|
990
991
|
*/
|
991
992
|
static int index_insert(
|
992
|
-
git_index *index, git_index_entry **entry_ptr, int replace)
|
993
|
+
git_index *index, git_index_entry **entry_ptr, int replace, bool trust_mode)
|
993
994
|
{
|
994
995
|
int error = 0;
|
995
996
|
size_t path_length, position;
|
@@ -1021,7 +1022,10 @@ static int index_insert(
|
|
1021
1022
|
&position, index, entry->path, 0, GIT_IDXENTRY_STAGE(entry), false)) {
|
1022
1023
|
existing = index->entries.contents[position];
|
1023
1024
|
/* update filemode to existing values if stat is not trusted */
|
1024
|
-
|
1025
|
+
if (trust_mode)
|
1026
|
+
entry->mode = git_index__create_mode(entry->mode);
|
1027
|
+
else
|
1028
|
+
entry->mode = index_merge_mode(index, existing, entry->mode);
|
1025
1029
|
}
|
1026
1030
|
|
1027
1031
|
/* look for tree / blob name collisions, removing conflicts if requested */
|
@@ -1091,7 +1095,7 @@ static bool valid_filemode(const int filemode)
|
|
1091
1095
|
}
|
1092
1096
|
|
1093
1097
|
int git_index_add_frombuffer(
|
1094
|
-
git_index *index, git_index_entry *source_entry,
|
1098
|
+
git_index *index, const git_index_entry *source_entry,
|
1095
1099
|
const void *buffer, size_t len)
|
1096
1100
|
{
|
1097
1101
|
git_index_entry *entry = NULL;
|
@@ -1122,7 +1126,7 @@ int git_index_add_frombuffer(
|
|
1122
1126
|
git_oid_cpy(&entry->id, &id);
|
1123
1127
|
entry->file_size = len;
|
1124
1128
|
|
1125
|
-
if ((error = index_insert(index, &entry, 1)) < 0)
|
1129
|
+
if ((error = index_insert(index, &entry, 1, true)) < 0)
|
1126
1130
|
return error;
|
1127
1131
|
|
1128
1132
|
/* Adding implies conflict was resolved, move conflict entries to REUC */
|
@@ -1142,7 +1146,7 @@ int git_index_add_bypath(git_index *index, const char *path)
|
|
1142
1146
|
assert(index && path);
|
1143
1147
|
|
1144
1148
|
if ((ret = index_entry_init(&entry, index, path)) < 0 ||
|
1145
|
-
(ret = index_insert(index, &entry, 1)) < 0)
|
1149
|
+
(ret = index_insert(index, &entry, 1, false)) < 0)
|
1146
1150
|
return ret;
|
1147
1151
|
|
1148
1152
|
/* Adding implies conflict was resolved, move conflict entries to REUC */
|
@@ -1182,7 +1186,7 @@ int git_index_add(git_index *index, const git_index_entry *source_entry)
|
|
1182
1186
|
}
|
1183
1187
|
|
1184
1188
|
if ((ret = index_entry_dup(&entry, INDEX_OWNER(index), source_entry)) < 0 ||
|
1185
|
-
(ret = index_insert(index, &entry, 1)) < 0)
|
1189
|
+
(ret = index_insert(index, &entry, 1, true)) < 0)
|
1186
1190
|
return ret;
|
1187
1191
|
|
1188
1192
|
git_tree_cache_invalidate_path(index->tree, entry->path);
|
@@ -1313,7 +1317,7 @@ int git_index_conflict_add(git_index *index,
|
|
1313
1317
|
/* Make sure stage is correct */
|
1314
1318
|
GIT_IDXENTRY_STAGE_SET(entries[i], i + 1);
|
1315
1319
|
|
1316
|
-
if ((ret = index_insert(index, &entries[i], 1)) < 0)
|
1320
|
+
if ((ret = index_insert(index, &entries[i], 1, true)) < 0)
|
1317
1321
|
goto on_error;
|
1318
1322
|
|
1319
1323
|
entries[i] = NULL; /* don't free if later entry fails */
|
@@ -2537,7 +2541,7 @@ int git_index_add_all(
|
|
2537
2541
|
entry->id = blobid;
|
2538
2542
|
|
2539
2543
|
/* add working directory item to index */
|
2540
|
-
if ((error = index_insert(index, &entry, 1)) < 0)
|
2544
|
+
if ((error = index_insert(index, &entry, 1, false)) < 0)
|
2541
2545
|
break;
|
2542
2546
|
|
2543
2547
|
git_tree_cache_invalidate_path(index->tree, wd->path);
|
@@ -920,12 +920,31 @@ struct fs_iterator {
|
|
920
920
|
|
921
921
|
#define FS_MAX_DEPTH 100
|
922
922
|
|
923
|
+
typedef struct {
|
924
|
+
struct stat st;
|
925
|
+
size_t path_len;
|
926
|
+
char path[GIT_FLEX_ARRAY];
|
927
|
+
} fs_iterator_path_with_stat;
|
928
|
+
|
929
|
+
static int fs_iterator_path_with_stat_cmp(const void *a, const void *b)
|
930
|
+
{
|
931
|
+
const fs_iterator_path_with_stat *psa = a, *psb = b;
|
932
|
+
return strcmp(psa->path, psb->path);
|
933
|
+
}
|
934
|
+
|
935
|
+
static int fs_iterator_path_with_stat_cmp_icase(const void *a, const void *b)
|
936
|
+
{
|
937
|
+
const fs_iterator_path_with_stat *psa = a, *psb = b;
|
938
|
+
return strcasecmp(psa->path, psb->path);
|
939
|
+
}
|
940
|
+
|
923
941
|
static fs_iterator_frame *fs_iterator__alloc_frame(fs_iterator *fi)
|
924
942
|
{
|
925
943
|
fs_iterator_frame *ff = git__calloc(1, sizeof(fs_iterator_frame));
|
926
944
|
git_vector_cmp entry_compare = CASESELECT(
|
927
945
|
iterator__ignore_case(fi),
|
928
|
-
|
946
|
+
fs_iterator_path_with_stat_cmp_icase,
|
947
|
+
fs_iterator_path_with_stat_cmp);
|
929
948
|
|
930
949
|
if (ff && git_vector_init(&ff->entries, 0, entry_compare) < 0) {
|
931
950
|
git__free(ff);
|
@@ -967,7 +986,7 @@ static int fs_iterator__advance_over(
|
|
967
986
|
static int fs_iterator__entry_cmp(const void *i, const void *item)
|
968
987
|
{
|
969
988
|
const fs_iterator *fi = (const fs_iterator *)i;
|
970
|
-
const
|
989
|
+
const fs_iterator_path_with_stat *ps = item;
|
971
990
|
return fi->base.prefixcomp(fi->base.start, ps->path);
|
972
991
|
}
|
973
992
|
|
@@ -984,6 +1003,96 @@ static void fs_iterator__seek_frame_start(
|
|
984
1003
|
ff->index = 0;
|
985
1004
|
}
|
986
1005
|
|
1006
|
+
static int dirload_with_stat(
|
1007
|
+
const char *dirpath,
|
1008
|
+
size_t prefix_len,
|
1009
|
+
unsigned int flags,
|
1010
|
+
const char *start_stat,
|
1011
|
+
const char *end_stat,
|
1012
|
+
git_vector *contents)
|
1013
|
+
{
|
1014
|
+
git_path_diriter diriter = GIT_PATH_DIRITER_INIT;
|
1015
|
+
const char *path;
|
1016
|
+
int (*strncomp)(const char *a, const char *b, size_t sz);
|
1017
|
+
size_t start_len = start_stat ? strlen(start_stat) : 0;
|
1018
|
+
size_t end_len = end_stat ? strlen(end_stat) : 0;
|
1019
|
+
fs_iterator_path_with_stat *ps;
|
1020
|
+
size_t path_len, cmp_len, ps_size;
|
1021
|
+
int error;
|
1022
|
+
|
1023
|
+
strncomp = (flags & GIT_PATH_DIR_IGNORE_CASE) != 0 ?
|
1024
|
+
git__strncasecmp : git__strncmp;
|
1025
|
+
|
1026
|
+
if ((error = git_path_diriter_init(&diriter, dirpath, flags)) < 0)
|
1027
|
+
goto done;
|
1028
|
+
|
1029
|
+
while ((error = git_path_diriter_next(&diriter)) == 0) {
|
1030
|
+
if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0)
|
1031
|
+
goto done;
|
1032
|
+
|
1033
|
+
assert(path_len > prefix_len);
|
1034
|
+
|
1035
|
+
/* remove the prefix if requested */
|
1036
|
+
path += prefix_len;
|
1037
|
+
path_len -= prefix_len;
|
1038
|
+
|
1039
|
+
/* skip if before start_stat or after end_stat */
|
1040
|
+
cmp_len = min(start_len, path_len);
|
1041
|
+
if (cmp_len && strncomp(path, start_stat, cmp_len) < 0)
|
1042
|
+
continue;
|
1043
|
+
cmp_len = min(end_len, path_len);
|
1044
|
+
if (cmp_len && strncomp(path, end_stat, cmp_len) > 0)
|
1045
|
+
continue;
|
1046
|
+
|
1047
|
+
/* Make sure to append two bytes, one for the path's null
|
1048
|
+
* termination, one for a possible trailing '/' for folders.
|
1049
|
+
*/
|
1050
|
+
GITERR_CHECK_ALLOC_ADD(&ps_size, sizeof(fs_iterator_path_with_stat), path_len);
|
1051
|
+
GITERR_CHECK_ALLOC_ADD(&ps_size, ps_size, 2);
|
1052
|
+
|
1053
|
+
ps = git__calloc(1, ps_size);
|
1054
|
+
ps->path_len = path_len;
|
1055
|
+
|
1056
|
+
memcpy(ps->path, path, path_len);
|
1057
|
+
|
1058
|
+
if ((error = git_path_diriter_stat(&ps->st, &diriter)) < 0) {
|
1059
|
+
if (error == GIT_ENOTFOUND) {
|
1060
|
+
/* file was removed between readdir and lstat */
|
1061
|
+
git__free(ps);
|
1062
|
+
continue;
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
/* Treat the file as unreadable if we get any other error */
|
1066
|
+
memset(&ps->st, 0, sizeof(ps->st));
|
1067
|
+
ps->st.st_mode = GIT_FILEMODE_UNREADABLE;
|
1068
|
+
|
1069
|
+
giterr_clear();
|
1070
|
+
error = 0;
|
1071
|
+
} else if (S_ISDIR(ps->st.st_mode)) {
|
1072
|
+
/* Suffix directory paths with a '/' */
|
1073
|
+
ps->path[ps->path_len++] = '/';
|
1074
|
+
ps->path[ps->path_len] = '\0';
|
1075
|
+
} else if(!S_ISREG(ps->st.st_mode) && !S_ISLNK(ps->st.st_mode)) {
|
1076
|
+
/* Ignore wacky things in the filesystem */
|
1077
|
+
git__free(ps);
|
1078
|
+
continue;
|
1079
|
+
}
|
1080
|
+
|
1081
|
+
git_vector_insert(contents, ps);
|
1082
|
+
}
|
1083
|
+
|
1084
|
+
if (error == GIT_ITEROVER)
|
1085
|
+
error = 0;
|
1086
|
+
|
1087
|
+
/* sort now that directory suffix is added */
|
1088
|
+
git_vector_sort(contents);
|
1089
|
+
|
1090
|
+
done:
|
1091
|
+
git_path_diriter_free(&diriter);
|
1092
|
+
return error;
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
|
987
1096
|
static int fs_iterator__expand_dir(fs_iterator *fi)
|
988
1097
|
{
|
989
1098
|
int error;
|
@@ -998,7 +1107,7 @@ static int fs_iterator__expand_dir(fs_iterator *fi)
|
|
998
1107
|
ff = fs_iterator__alloc_frame(fi);
|
999
1108
|
GITERR_CHECK_ALLOC(ff);
|
1000
1109
|
|
1001
|
-
error =
|
1110
|
+
error = dirload_with_stat(
|
1002
1111
|
fi->path.ptr, fi->root_len, fi->dirload_flags,
|
1003
1112
|
fi->base.start, fi->base.end, &ff->entries);
|
1004
1113
|
|
@@ -1086,7 +1195,7 @@ static int fs_iterator__advance_over(
|
|
1086
1195
|
int error = 0;
|
1087
1196
|
fs_iterator *fi = (fs_iterator *)self;
|
1088
1197
|
fs_iterator_frame *ff;
|
1089
|
-
|
1198
|
+
fs_iterator_path_with_stat *next;
|
1090
1199
|
|
1091
1200
|
if (entry != NULL)
|
1092
1201
|
*entry = NULL;
|
@@ -1176,7 +1285,7 @@ static void fs_iterator__free(git_iterator *self)
|
|
1176
1285
|
|
1177
1286
|
static int fs_iterator__update_entry(fs_iterator *fi)
|
1178
1287
|
{
|
1179
|
-
|
1288
|
+
fs_iterator_path_with_stat *ps;
|
1180
1289
|
|
1181
1290
|
memset(&fi->entry, 0, sizeof(fi->entry));
|
1182
1291
|
|
@@ -1307,7 +1416,7 @@ GIT_INLINE(bool) workdir_path_is_dotgit(const git_buf *path)
|
|
1307
1416
|
* We consider it a submodule if the path is listed as a submodule in
|
1308
1417
|
* either the tree or the index.
|
1309
1418
|
*/
|
1310
|
-
static int is_submodule(workdir_iterator *wi,
|
1419
|
+
static int is_submodule(workdir_iterator *wi, fs_iterator_path_with_stat *ie)
|
1311
1420
|
{
|
1312
1421
|
int error, is_submodule = 0;
|
1313
1422
|
|
@@ -1344,17 +1453,29 @@ static int is_submodule(workdir_iterator *wi, git_path_with_stat *ie)
|
|
1344
1453
|
return is_submodule;
|
1345
1454
|
}
|
1346
1455
|
|
1456
|
+
GIT_INLINE(git_dir_flag) git_entry__dir_flag(git_index_entry *entry) {
|
1457
|
+
#if defined(GIT_WIN32) && !defined(__MINGW32__)
|
1458
|
+
return (entry && entry->mode)
|
1459
|
+
? S_ISDIR(entry->mode) ? GIT_DIR_FLAG_TRUE : GIT_DIR_FLAG_FALSE
|
1460
|
+
: GIT_DIR_FLAG_UNKNOWN;
|
1461
|
+
#else
|
1462
|
+
GIT_UNUSED(entry);
|
1463
|
+
return GIT_DIR_FLAG_UNKNOWN;
|
1464
|
+
#endif
|
1465
|
+
}
|
1466
|
+
|
1347
1467
|
static int workdir_iterator__enter_dir(fs_iterator *fi)
|
1348
1468
|
{
|
1349
1469
|
workdir_iterator *wi = (workdir_iterator *)fi;
|
1350
1470
|
fs_iterator_frame *ff = fi->stack;
|
1351
1471
|
size_t pos;
|
1352
|
-
|
1472
|
+
fs_iterator_path_with_stat *entry;
|
1353
1473
|
bool found_submodules = false;
|
1354
1474
|
|
1475
|
+
git_dir_flag dir_flag = git_entry__dir_flag(&fi->entry);
|
1476
|
+
|
1355
1477
|
/* check if this directory is ignored */
|
1356
|
-
if (git_ignore__lookup(
|
1357
|
-
&ff->is_ignored, &wi->ignores, fi->path.ptr + fi->root_len) < 0) {
|
1478
|
+
if (git_ignore__lookup(&ff->is_ignored, &wi->ignores, fi->path.ptr + fi->root_len, dir_flag) < 0) {
|
1358
1479
|
giterr_clear();
|
1359
1480
|
ff->is_ignored = GIT_IGNORE_NOTFOUND;
|
1360
1481
|
}
|
@@ -1483,7 +1604,6 @@ int git_iterator_for_workdir_ext(
|
|
1483
1604
|
return fs_iterator__initialize(out, &wi->fi, repo_workdir);
|
1484
1605
|
}
|
1485
1606
|
|
1486
|
-
|
1487
1607
|
void git_iterator_free(git_iterator *iter)
|
1488
1608
|
{
|
1489
1609
|
if (iter == NULL)
|
@@ -1574,8 +1694,9 @@ int git_iterator_current_parent_tree(
|
|
1574
1694
|
|
1575
1695
|
static void workdir_iterator_update_is_ignored(workdir_iterator *wi)
|
1576
1696
|
{
|
1577
|
-
|
1578
|
-
|
1697
|
+
git_dir_flag dir_flag = git_entry__dir_flag(&wi->fi.entry);
|
1698
|
+
|
1699
|
+
if (git_ignore__lookup(&wi->is_ignored, &wi->ignores, wi->fi.entry.path, dir_flag) < 0) {
|
1579
1700
|
giterr_clear();
|
1580
1701
|
wi->is_ignored = GIT_IGNORE_NOTFOUND;
|
1581
1702
|
}
|
data/vendor/libgit2/src/netops.h
CHANGED