rugged 0.23.0b2 → 0.23.0b4
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_blob.c +39 -0
- data/ext/rugged/rugged_diff.c +7 -3
- data/ext/rugged/rugged_index.c +2 -2
- data/ext/rugged/rugged_remote.c +27 -148
- data/ext/rugged/rugged_remote_collection.c +134 -12
- data/ext/rugged/rugged_repo.c +74 -5
- data/ext/rugged/rugged_submodule.c +18 -208
- data/ext/rugged/rugged_submodule_collection.c +148 -0
- data/lib/rugged/version.rb +1 -1
- data/vendor/libgit2/AUTHORS +1 -0
- data/vendor/libgit2/CMakeLists.txt +33 -25
- data/vendor/libgit2/deps/winhttp/winhttp.def +29 -29
- data/vendor/libgit2/include/git2.h +1 -1
- data/vendor/libgit2/include/git2/blob.h +4 -6
- data/vendor/libgit2/include/git2/checkout.h +10 -1
- data/vendor/libgit2/include/git2/clone.h +6 -7
- data/vendor/libgit2/include/git2/commit.h +11 -0
- data/vendor/libgit2/include/git2/cred_helpers.h +2 -2
- data/vendor/libgit2/include/git2/describe.h +1 -1
- data/vendor/libgit2/include/git2/diff.h +68 -11
- data/vendor/libgit2/include/git2/errors.h +4 -1
- data/vendor/libgit2/include/git2/filter.h +16 -0
- data/vendor/libgit2/include/git2/index.h +38 -11
- data/vendor/libgit2/include/git2/odb.h +1 -1
- data/vendor/libgit2/include/git2/odb_backend.h +2 -2
- data/vendor/libgit2/include/git2/remote.h +300 -207
- data/vendor/libgit2/include/git2/reset.h +1 -0
- data/vendor/libgit2/include/git2/stash.h +135 -4
- data/vendor/libgit2/include/git2/status.h +1 -0
- data/vendor/libgit2/include/git2/submodule.h +46 -75
- data/vendor/libgit2/include/git2/sys/odb_backend.h +1 -1
- data/vendor/libgit2/include/git2/sys/stream.h +2 -0
- data/vendor/libgit2/include/git2/sys/transport.h +1 -21
- data/vendor/libgit2/include/git2/transport.h +27 -0
- data/vendor/libgit2/include/git2/types.h +20 -10
- data/vendor/libgit2/include/git2/version.h +3 -3
- data/vendor/libgit2/libgit2.pc.in +4 -2
- data/vendor/libgit2/src/attr.c +2 -1
- data/vendor/libgit2/src/attr_file.c +18 -37
- data/vendor/libgit2/src/blame.c +2 -2
- data/vendor/libgit2/src/blob.c +4 -3
- data/vendor/libgit2/src/branch.c +6 -3
- data/vendor/libgit2/src/buf_text.c +4 -6
- data/vendor/libgit2/src/buf_text.h +1 -2
- data/vendor/libgit2/src/buffer.c +8 -6
- data/vendor/libgit2/src/buffer.h +1 -1
- data/vendor/libgit2/src/cache.c +1 -0
- data/vendor/libgit2/src/checkout.c +34 -20
- data/vendor/libgit2/src/clone.c +29 -29
- data/vendor/libgit2/src/commit.c +65 -0
- data/vendor/libgit2/src/common.h +5 -0
- data/vendor/libgit2/src/config.c +20 -0
- data/vendor/libgit2/src/config.h +6 -0
- data/vendor/libgit2/src/config_file.c +2 -2
- data/vendor/libgit2/src/crlf.c +39 -17
- data/vendor/libgit2/src/curl_stream.c +257 -0
- data/vendor/libgit2/src/curl_stream.h +14 -0
- data/vendor/libgit2/src/diff.c +223 -88
- data/vendor/libgit2/src/diff.h +21 -1
- data/vendor/libgit2/src/diff_file.c +23 -13
- data/vendor/libgit2/src/diff_file.h +4 -2
- data/vendor/libgit2/src/diff_patch.c +266 -71
- data/vendor/libgit2/src/diff_patch.h +36 -0
- data/vendor/libgit2/src/diff_print.c +156 -126
- data/vendor/libgit2/src/diff_tform.c +32 -54
- data/vendor/libgit2/src/fetch.c +27 -10
- data/vendor/libgit2/src/fetch.h +2 -2
- data/vendor/libgit2/src/filebuf.c +1 -1
- data/vendor/libgit2/src/fileops.c +6 -2
- data/vendor/libgit2/src/filter.c +28 -7
- data/vendor/libgit2/src/fnmatch.c +5 -5
- data/vendor/libgit2/src/global.c +16 -0
- data/vendor/libgit2/src/ident.c +2 -2
- data/vendor/libgit2/src/ignore.c +1 -0
- data/vendor/libgit2/src/index.c +338 -80
- data/vendor/libgit2/src/index.h +4 -1
- data/vendor/libgit2/src/indexer.c +19 -5
- data/vendor/libgit2/src/iterator.c +118 -11
- data/vendor/libgit2/src/iterator.h +25 -0
- data/vendor/libgit2/src/merge.c +96 -106
- data/vendor/libgit2/src/merge.h +14 -4
- data/vendor/libgit2/src/netops.c +3 -3
- data/vendor/libgit2/src/odb.c +17 -9
- data/vendor/libgit2/src/odb.h +1 -1
- data/vendor/libgit2/src/odb_loose.c +2 -2
- data/vendor/libgit2/src/odb_pack.c +1 -1
- data/vendor/libgit2/src/openssl_stream.c +118 -27
- data/vendor/libgit2/src/pack-objects.c +28 -0
- data/vendor/libgit2/src/pack-objects.h +1 -0
- data/vendor/libgit2/src/pack.c +18 -10
- data/vendor/libgit2/src/path.c +16 -11
- data/vendor/libgit2/src/path.h +1 -1
- data/vendor/libgit2/src/push.c +26 -42
- data/vendor/libgit2/src/push.h +2 -34
- data/vendor/libgit2/src/rebase.c +1 -1
- data/vendor/libgit2/src/refs.c +1 -1
- data/vendor/libgit2/src/refspec.c +6 -0
- data/vendor/libgit2/src/remote.c +381 -274
- data/vendor/libgit2/src/remote.h +0 -4
- data/vendor/libgit2/src/repository.c +33 -12
- data/vendor/libgit2/src/repository.h +0 -1
- data/vendor/libgit2/src/reset.c +1 -0
- data/vendor/libgit2/src/stash.c +439 -17
- data/vendor/libgit2/src/status.c +6 -0
- data/vendor/libgit2/src/stransport_stream.c +58 -21
- data/vendor/libgit2/src/stream.h +15 -0
- data/vendor/libgit2/src/submodule.c +410 -664
- data/vendor/libgit2/src/submodule.h +0 -24
- data/vendor/libgit2/src/transaction.c +1 -0
- data/vendor/libgit2/src/transports/cred.c +55 -1
- data/vendor/libgit2/src/transports/http.c +18 -2
- data/vendor/libgit2/src/transports/local.c +60 -59
- data/vendor/libgit2/src/transports/smart.h +1 -1
- data/vendor/libgit2/src/transports/smart_protocol.c +11 -11
- data/vendor/libgit2/src/transports/ssh.c +46 -7
- data/vendor/libgit2/src/unix/posix.h +4 -0
- data/vendor/libgit2/src/util.c +9 -9
- data/vendor/libgit2/src/util.h +9 -0
- data/vendor/libgit2/src/win32/posix.h +3 -0
- data/vendor/libgit2/src/win32/posix_w32.c +38 -0
- data/vendor/libgit2/src/win32/w32_util.h +10 -0
- metadata +4 -3
- data/vendor/libgit2/include/git2/push.h +0 -94
@@ -0,0 +1,257 @@
|
|
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
|
+
|
8
|
+
#ifdef GIT_CURL
|
9
|
+
|
10
|
+
#include <curl/curl.h>
|
11
|
+
|
12
|
+
#include "stream.h"
|
13
|
+
#include "git2/transport.h"
|
14
|
+
#include "buffer.h"
|
15
|
+
#include "vector.h"
|
16
|
+
|
17
|
+
typedef struct {
|
18
|
+
git_stream parent;
|
19
|
+
CURL *handle;
|
20
|
+
curl_socket_t socket;
|
21
|
+
char curl_error[CURL_ERROR_SIZE + 1];
|
22
|
+
git_cert_x509 cert_info;
|
23
|
+
git_strarray cert_info_strings;
|
24
|
+
} curl_stream;
|
25
|
+
|
26
|
+
static int seterr_curl(curl_stream *s)
|
27
|
+
{
|
28
|
+
giterr_set(GITERR_NET, "curl error: %s\n", s->curl_error);
|
29
|
+
return -1;
|
30
|
+
}
|
31
|
+
|
32
|
+
static int curls_connect(git_stream *stream)
|
33
|
+
{
|
34
|
+
curl_stream *s = (curl_stream *) stream;
|
35
|
+
long sockextr;
|
36
|
+
int failed_cert = 0;
|
37
|
+
CURLcode res;
|
38
|
+
res = curl_easy_perform(s->handle);
|
39
|
+
|
40
|
+
if (res != CURLE_OK && res != CURLE_PEER_FAILED_VERIFICATION)
|
41
|
+
return seterr_curl(s);
|
42
|
+
if (res == CURLE_PEER_FAILED_VERIFICATION)
|
43
|
+
failed_cert = 1;
|
44
|
+
|
45
|
+
if ((res = curl_easy_getinfo(s->handle, CURLINFO_LASTSOCKET, &sockextr)) != CURLE_OK)
|
46
|
+
return seterr_curl(s);
|
47
|
+
|
48
|
+
s->socket = sockextr;
|
49
|
+
|
50
|
+
if (s->parent.encrypted && failed_cert)
|
51
|
+
return GIT_ECERTIFICATE;
|
52
|
+
|
53
|
+
return 0;
|
54
|
+
}
|
55
|
+
|
56
|
+
static int curls_certificate(git_cert **out, git_stream *stream)
|
57
|
+
{
|
58
|
+
int error;
|
59
|
+
CURLcode res;
|
60
|
+
struct curl_slist *slist;
|
61
|
+
struct curl_certinfo *certinfo;
|
62
|
+
git_vector strings = GIT_VECTOR_INIT;
|
63
|
+
curl_stream *s = (curl_stream *) stream;
|
64
|
+
|
65
|
+
if ((res = curl_easy_getinfo(s->handle, CURLINFO_CERTINFO, &certinfo)) != CURLE_OK)
|
66
|
+
return seterr_curl(s);
|
67
|
+
|
68
|
+
/* No information is available, can happen with SecureTransport */
|
69
|
+
if (certinfo->num_of_certs == 0) {
|
70
|
+
s->cert_info.cert_type = GIT_CERT_NONE;
|
71
|
+
s->cert_info.data = NULL;
|
72
|
+
s->cert_info.len = 0;
|
73
|
+
return 0;
|
74
|
+
}
|
75
|
+
|
76
|
+
if ((error = git_vector_init(&strings, 8, NULL)) < 0)
|
77
|
+
return error;
|
78
|
+
|
79
|
+
for (slist = certinfo->certinfo[0]; slist; slist = slist->next) {
|
80
|
+
char *str = git__strdup(slist->data);
|
81
|
+
GITERR_CHECK_ALLOC(str);
|
82
|
+
}
|
83
|
+
|
84
|
+
/* Copy the contents of the vector into a strarray so we can expose them */
|
85
|
+
s->cert_info_strings.strings = (char **) strings.contents;
|
86
|
+
s->cert_info_strings.count = strings.length;
|
87
|
+
|
88
|
+
s->cert_info.cert_type = GIT_CERT_STRARRAY;
|
89
|
+
s->cert_info.data = &s->cert_info_strings;
|
90
|
+
s->cert_info.len = strings.length;
|
91
|
+
|
92
|
+
*out = (git_cert *) &s->cert_info;
|
93
|
+
|
94
|
+
return 0;
|
95
|
+
}
|
96
|
+
|
97
|
+
static int curls_set_proxy(git_stream *stream, const char *proxy_url)
|
98
|
+
{
|
99
|
+
CURLcode res;
|
100
|
+
curl_stream *s = (curl_stream *) stream;
|
101
|
+
|
102
|
+
if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXY, proxy_url)) != CURLE_OK)
|
103
|
+
return seterr_curl(s);
|
104
|
+
|
105
|
+
return 0;
|
106
|
+
}
|
107
|
+
|
108
|
+
static int wait_for(curl_socket_t fd, bool reading)
|
109
|
+
{
|
110
|
+
int ret;
|
111
|
+
fd_set infd, outfd, errfd;
|
112
|
+
|
113
|
+
FD_ZERO(&infd);
|
114
|
+
FD_ZERO(&outfd);
|
115
|
+
FD_ZERO(&errfd);
|
116
|
+
|
117
|
+
FD_SET(fd, &errfd);
|
118
|
+
if (reading)
|
119
|
+
FD_SET(fd, &infd);
|
120
|
+
else
|
121
|
+
FD_SET(fd, &outfd);
|
122
|
+
|
123
|
+
if ((ret = select(fd + 1, &infd, &outfd, &errfd, NULL)) < 0) {
|
124
|
+
giterr_set(GITERR_OS, "error in select");
|
125
|
+
return -1;
|
126
|
+
}
|
127
|
+
|
128
|
+
return 0;
|
129
|
+
}
|
130
|
+
|
131
|
+
static ssize_t curls_write(git_stream *stream, const char *data, size_t len, int flags)
|
132
|
+
{
|
133
|
+
int error;
|
134
|
+
size_t off = 0, sent;
|
135
|
+
CURLcode res;
|
136
|
+
curl_stream *s = (curl_stream *) stream;
|
137
|
+
|
138
|
+
GIT_UNUSED(flags);
|
139
|
+
|
140
|
+
do {
|
141
|
+
if ((error = wait_for(s->socket, false)) < 0)
|
142
|
+
return error;
|
143
|
+
|
144
|
+
res = curl_easy_send(s->handle, data + off, len - off, &sent);
|
145
|
+
if (res == CURLE_OK)
|
146
|
+
off += sent;
|
147
|
+
} while ((res == CURLE_OK || res == CURLE_AGAIN) && off < len);
|
148
|
+
|
149
|
+
if (res != CURLE_OK)
|
150
|
+
return seterr_curl(s);
|
151
|
+
|
152
|
+
return len;
|
153
|
+
}
|
154
|
+
|
155
|
+
static ssize_t curls_read(git_stream *stream, void *data, size_t len)
|
156
|
+
{
|
157
|
+
int error;
|
158
|
+
size_t read;
|
159
|
+
CURLcode res;
|
160
|
+
curl_stream *s = (curl_stream *) stream;
|
161
|
+
|
162
|
+
do {
|
163
|
+
if ((error = wait_for(s->socket, true)) < 0)
|
164
|
+
return error;
|
165
|
+
|
166
|
+
res = curl_easy_recv(s->handle, data, len, &read);
|
167
|
+
} while (res == CURLE_AGAIN);
|
168
|
+
|
169
|
+
if (res != CURLE_OK)
|
170
|
+
return seterr_curl(s);
|
171
|
+
|
172
|
+
return read;
|
173
|
+
}
|
174
|
+
|
175
|
+
static int curls_close(git_stream *stream)
|
176
|
+
{
|
177
|
+
curl_stream *s = (curl_stream *) stream;
|
178
|
+
|
179
|
+
if (!s->handle)
|
180
|
+
return 0;
|
181
|
+
|
182
|
+
curl_easy_cleanup(s->handle);
|
183
|
+
s->handle = NULL;
|
184
|
+
s->socket = 0;
|
185
|
+
|
186
|
+
return 0;
|
187
|
+
}
|
188
|
+
|
189
|
+
static void curls_free(git_stream *stream)
|
190
|
+
{
|
191
|
+
curl_stream *s = (curl_stream *) stream;
|
192
|
+
|
193
|
+
curls_close(stream);
|
194
|
+
git_strarray_free(&s->cert_info_strings);
|
195
|
+
git__free(s);
|
196
|
+
}
|
197
|
+
|
198
|
+
int git_curl_stream_new(git_stream **out, const char *host, const char *port)
|
199
|
+
{
|
200
|
+
curl_stream *st;
|
201
|
+
CURL *handle;
|
202
|
+
int iport = 0, error;
|
203
|
+
|
204
|
+
st = git__calloc(1, sizeof(curl_stream));
|
205
|
+
GITERR_CHECK_ALLOC(st);
|
206
|
+
|
207
|
+
handle = curl_easy_init();
|
208
|
+
if (handle == NULL) {
|
209
|
+
giterr_set(GITERR_NET, "failed to create curl handle");
|
210
|
+
return -1;
|
211
|
+
}
|
212
|
+
|
213
|
+
if ((error = git__strtol32(&iport, port, NULL, 10)) < 0)
|
214
|
+
return error;
|
215
|
+
|
216
|
+
curl_easy_setopt(handle, CURLOPT_URL, host);
|
217
|
+
curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, st->curl_error);
|
218
|
+
curl_easy_setopt(handle, CURLOPT_PORT, iport);
|
219
|
+
curl_easy_setopt(handle, CURLOPT_CONNECT_ONLY, 1);
|
220
|
+
curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 1);
|
221
|
+
curl_easy_setopt(handle, CURLOPT_CERTINFO, 1);
|
222
|
+
curl_easy_setopt(handle, CURLOPT_HTTPPROXYTUNNEL, 1);
|
223
|
+
|
224
|
+
/* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); */
|
225
|
+
|
226
|
+
st->parent.version = GIT_STREAM_VERSION;
|
227
|
+
st->parent.encrypted = 0; /* we don't encrypt ourselves */
|
228
|
+
st->parent.proxy_support = 1;
|
229
|
+
st->parent.connect = curls_connect;
|
230
|
+
st->parent.certificate = curls_certificate;
|
231
|
+
st->parent.set_proxy = curls_set_proxy;
|
232
|
+
st->parent.read = curls_read;
|
233
|
+
st->parent.write = curls_write;
|
234
|
+
st->parent.close = curls_close;
|
235
|
+
st->parent.free = curls_free;
|
236
|
+
st->handle = handle;
|
237
|
+
|
238
|
+
*out = (git_stream *) st;
|
239
|
+
return 0;
|
240
|
+
}
|
241
|
+
|
242
|
+
#else
|
243
|
+
|
244
|
+
#include "stream.h"
|
245
|
+
|
246
|
+
int git_curl_stream_new(git_stream **out, const char *host, const char *port)
|
247
|
+
{
|
248
|
+
GIT_UNUSED(out);
|
249
|
+
GIT_UNUSED(host);
|
250
|
+
GIT_UNUSED(port);
|
251
|
+
|
252
|
+
giterr_set(GITERR_NET, "curl is not supported in this version");
|
253
|
+
return -1;
|
254
|
+
}
|
255
|
+
|
256
|
+
|
257
|
+
#endif
|
@@ -0,0 +1,14 @@
|
|
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_curl_stream_h__
|
8
|
+
#define INCLUDE_curl_stream_h__
|
9
|
+
|
10
|
+
#include "git2/sys/stream.h"
|
11
|
+
|
12
|
+
extern int git_curl_stream_new(git_stream **out, const char *host, const char *port);
|
13
|
+
|
14
|
+
#endif
|
data/vendor/libgit2/src/diff.c
CHANGED
@@ -77,11 +77,24 @@ static int diff_insert_delta(
|
|
77
77
|
static int diff_delta__from_one(
|
78
78
|
git_diff *diff,
|
79
79
|
git_delta_t status,
|
80
|
-
const git_index_entry *
|
80
|
+
const git_index_entry *oitem,
|
81
|
+
const git_index_entry *nitem)
|
81
82
|
{
|
83
|
+
const git_index_entry *entry = nitem;
|
84
|
+
bool has_old = false;
|
82
85
|
git_diff_delta *delta;
|
83
86
|
const char *matched_pathspec;
|
84
87
|
|
88
|
+
assert((oitem != NULL) ^ (nitem != NULL));
|
89
|
+
|
90
|
+
if (oitem) {
|
91
|
+
entry = oitem;
|
92
|
+
has_old = true;
|
93
|
+
}
|
94
|
+
|
95
|
+
if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_REVERSE))
|
96
|
+
has_old = !has_old;
|
97
|
+
|
85
98
|
if ((entry->flags & GIT_IDXENTRY_VALID) != 0)
|
86
99
|
return 0;
|
87
100
|
|
@@ -111,20 +124,21 @@ static int diff_delta__from_one(
|
|
111
124
|
assert(status != GIT_DELTA_MODIFIED);
|
112
125
|
delta->nfiles = 1;
|
113
126
|
|
114
|
-
if (
|
127
|
+
if (has_old) {
|
115
128
|
delta->old_file.mode = entry->mode;
|
116
129
|
delta->old_file.size = entry->file_size;
|
130
|
+
delta->old_file.flags |= GIT_DIFF_FLAG_EXISTS;
|
117
131
|
git_oid_cpy(&delta->old_file.id, &entry->id);
|
118
132
|
} else /* ADDED, IGNORED, UNTRACKED */ {
|
119
133
|
delta->new_file.mode = entry->mode;
|
120
134
|
delta->new_file.size = entry->file_size;
|
135
|
+
delta->new_file.flags |= GIT_DIFF_FLAG_EXISTS;
|
121
136
|
git_oid_cpy(&delta->new_file.id, &entry->id);
|
122
137
|
}
|
123
138
|
|
124
139
|
delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID;
|
125
140
|
|
126
|
-
if (delta->
|
127
|
-
!git_oid_iszero(&delta->new_file.id))
|
141
|
+
if (has_old || !git_oid_iszero(&delta->new_file.id))
|
128
142
|
delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
|
129
143
|
|
130
144
|
return diff_insert_delta(diff, delta, matched_pathspec);
|
@@ -137,9 +151,10 @@ static int diff_delta__from_two(
|
|
137
151
|
uint32_t old_mode,
|
138
152
|
const git_index_entry *new_entry,
|
139
153
|
uint32_t new_mode,
|
140
|
-
git_oid *
|
154
|
+
const git_oid *new_id,
|
141
155
|
const char *matched_pathspec)
|
142
156
|
{
|
157
|
+
const git_oid *old_id = &old_entry->id;
|
143
158
|
git_diff_delta *delta;
|
144
159
|
const char *canonical_path = old_entry->path;
|
145
160
|
|
@@ -147,38 +162,45 @@ static int diff_delta__from_two(
|
|
147
162
|
DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_INCLUDE_UNMODIFIED))
|
148
163
|
return 0;
|
149
164
|
|
165
|
+
if (!new_id)
|
166
|
+
new_id = &new_entry->id;
|
167
|
+
|
150
168
|
if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_REVERSE)) {
|
151
169
|
uint32_t temp_mode = old_mode;
|
152
170
|
const git_index_entry *temp_entry = old_entry;
|
171
|
+
const git_oid *temp_id = old_id;
|
172
|
+
|
153
173
|
old_entry = new_entry;
|
154
174
|
new_entry = temp_entry;
|
155
175
|
old_mode = new_mode;
|
156
176
|
new_mode = temp_mode;
|
177
|
+
old_id = new_id;
|
178
|
+
new_id = temp_id;
|
157
179
|
}
|
158
180
|
|
159
181
|
delta = diff_delta__alloc(diff, status, canonical_path);
|
160
182
|
GITERR_CHECK_ALLOC(delta);
|
161
183
|
delta->nfiles = 2;
|
162
184
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
185
|
+
if (!git_index_entry_is_conflict(old_entry)) {
|
186
|
+
delta->old_file.size = old_entry->file_size;
|
187
|
+
delta->old_file.mode = old_mode;
|
188
|
+
git_oid_cpy(&delta->old_file.id, old_id);
|
189
|
+
delta->old_file.flags |= GIT_DIFF_FLAG_VALID_ID |
|
190
|
+
GIT_DIFF_FLAG_EXISTS;
|
191
|
+
}
|
167
192
|
|
168
|
-
|
169
|
-
|
170
|
-
|
193
|
+
if (!git_index_entry_is_conflict(new_entry)) {
|
194
|
+
git_oid_cpy(&delta->new_file.id, new_id);
|
195
|
+
delta->new_file.size = new_entry->file_size;
|
196
|
+
delta->new_file.mode = new_mode;
|
197
|
+
delta->old_file.flags |= GIT_DIFF_FLAG_EXISTS;
|
198
|
+
delta->new_file.flags |= GIT_DIFF_FLAG_EXISTS;
|
171
199
|
|
172
|
-
|
173
|
-
|
174
|
-
git_oid_cpy(&delta->old_file.id, new_oid);
|
175
|
-
else
|
176
|
-
git_oid_cpy(&delta->new_file.id, new_oid);
|
200
|
+
if (!git_oid_iszero(&new_entry->id))
|
201
|
+
delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
|
177
202
|
}
|
178
203
|
|
179
|
-
if (new_oid || !git_oid_iszero(&new_entry->id))
|
180
|
-
delta->new_file.flags |= GIT_DIFF_FLAG_VALID_ID;
|
181
|
-
|
182
204
|
return diff_insert_delta(diff, delta, matched_pathspec);
|
183
205
|
}
|
184
206
|
|
@@ -327,6 +349,22 @@ static const char *diff_mnemonic_prefix(
|
|
327
349
|
return pfx;
|
328
350
|
}
|
329
351
|
|
352
|
+
static int diff_entry_cmp(const void *a, const void *b)
|
353
|
+
{
|
354
|
+
const git_index_entry *entry_a = a;
|
355
|
+
const git_index_entry *entry_b = b;
|
356
|
+
|
357
|
+
return strcmp(entry_a->path, entry_b->path);
|
358
|
+
}
|
359
|
+
|
360
|
+
static int diff_entry_icmp(const void *a, const void *b)
|
361
|
+
{
|
362
|
+
const git_index_entry *entry_a = a;
|
363
|
+
const git_index_entry *entry_b = b;
|
364
|
+
|
365
|
+
return strcasecmp(entry_a->path, entry_b->path);
|
366
|
+
}
|
367
|
+
|
330
368
|
static void diff_set_ignore_case(git_diff *diff, bool ignore_case)
|
331
369
|
{
|
332
370
|
if (!ignore_case) {
|
@@ -335,7 +373,7 @@ static void diff_set_ignore_case(git_diff *diff, bool ignore_case)
|
|
335
373
|
diff->strcomp = git__strcmp;
|
336
374
|
diff->strncomp = git__strncmp;
|
337
375
|
diff->pfxcomp = git__prefixcmp;
|
338
|
-
diff->entrycomp =
|
376
|
+
diff->entrycomp = diff_entry_cmp;
|
339
377
|
|
340
378
|
git_vector_set_cmp(&diff->deltas, git_diff_delta__cmp);
|
341
379
|
} else {
|
@@ -344,7 +382,7 @@ static void diff_set_ignore_case(git_diff *diff, bool ignore_case)
|
|
344
382
|
diff->strcomp = git__strcasecmp;
|
345
383
|
diff->strncomp = git__strncasecmp;
|
346
384
|
diff->pfxcomp = git__prefixcmp_icase;
|
347
|
-
diff->entrycomp =
|
385
|
+
diff->entrycomp = diff_entry_icmp;
|
348
386
|
|
349
387
|
git_vector_set_cmp(&diff->deltas, git_diff_delta__casecmp);
|
350
388
|
}
|
@@ -532,7 +570,7 @@ int git_diff__oid_for_file(
|
|
532
570
|
git_oid *out,
|
533
571
|
git_diff *diff,
|
534
572
|
const char *path,
|
535
|
-
uint16_t
|
573
|
+
uint16_t mode,
|
536
574
|
git_off_t size)
|
537
575
|
{
|
538
576
|
git_index_entry entry;
|
@@ -542,13 +580,14 @@ int git_diff__oid_for_file(
|
|
542
580
|
entry.file_size = size;
|
543
581
|
entry.path = (char *)path;
|
544
582
|
|
545
|
-
return git_diff__oid_for_entry(out, diff, &entry, NULL);
|
583
|
+
return git_diff__oid_for_entry(out, diff, &entry, mode, NULL);
|
546
584
|
}
|
547
585
|
|
548
586
|
int git_diff__oid_for_entry(
|
549
587
|
git_oid *out,
|
550
588
|
git_diff *diff,
|
551
589
|
const git_index_entry *src,
|
590
|
+
uint16_t mode,
|
552
591
|
const git_oid *update_match)
|
553
592
|
{
|
554
593
|
int error = 0;
|
@@ -562,7 +601,7 @@ int git_diff__oid_for_entry(
|
|
562
601
|
&full_path, git_repository_workdir(diff->repo), entry.path) < 0)
|
563
602
|
return -1;
|
564
603
|
|
565
|
-
if (!
|
604
|
+
if (!mode) {
|
566
605
|
struct stat st;
|
567
606
|
|
568
607
|
diff->perf.stat_calls++;
|
@@ -578,7 +617,7 @@ int git_diff__oid_for_entry(
|
|
578
617
|
}
|
579
618
|
|
580
619
|
/* calculate OID for file if possible */
|
581
|
-
if (S_ISGITLINK(
|
620
|
+
if (S_ISGITLINK(mode)) {
|
582
621
|
git_submodule *sm;
|
583
622
|
|
584
623
|
if (!git_submodule_lookup(&sm, diff->repo, entry.path)) {
|
@@ -592,7 +631,7 @@ int git_diff__oid_for_entry(
|
|
592
631
|
*/
|
593
632
|
giterr_clear();
|
594
633
|
}
|
595
|
-
} else if (S_ISLNK(
|
634
|
+
} else if (S_ISLNK(mode)) {
|
596
635
|
error = git_odb__hashlink(out, full_path.ptr);
|
597
636
|
diff->perf.oid_calculations++;
|
598
637
|
} else if (!git__is_sizet(entry.file_size)) {
|
@@ -619,10 +658,15 @@ int git_diff__oid_for_entry(
|
|
619
658
|
/* update index for entry if requested */
|
620
659
|
if (!error && update_match && git_oid_equal(out, update_match)) {
|
621
660
|
git_index *idx;
|
661
|
+
git_index_entry updated_entry;
|
662
|
+
|
663
|
+
memcpy(&updated_entry, &entry, sizeof(git_index_entry));
|
664
|
+
updated_entry.mode = mode;
|
665
|
+
git_oid_cpy(&updated_entry.id, out);
|
622
666
|
|
623
667
|
if (!(error = git_repository_index__weakptr(&idx, diff->repo))) {
|
624
|
-
|
625
|
-
|
668
|
+
error = git_index_add(idx, &updated_entry);
|
669
|
+
diff->index_updated = true;
|
626
670
|
}
|
627
671
|
}
|
628
672
|
|
@@ -731,47 +775,54 @@ static int maybe_modified(
|
|
731
775
|
new_is_workdir)
|
732
776
|
nmode = (nmode & ~MODE_BITS_MASK) | (omode & MODE_BITS_MASK);
|
733
777
|
|
778
|
+
/* if one side is a conflict, mark the whole delta as conflicted */
|
779
|
+
if (git_index_entry_is_conflict(oitem) ||
|
780
|
+
git_index_entry_is_conflict(nitem)) {
|
781
|
+
status = GIT_DELTA_CONFLICTED;
|
782
|
+
|
734
783
|
/* support "assume unchanged" (poorly, b/c we still stat everything) */
|
735
|
-
if ((oitem->flags & GIT_IDXENTRY_VALID) != 0)
|
784
|
+
} else if ((oitem->flags & GIT_IDXENTRY_VALID) != 0) {
|
736
785
|
status = GIT_DELTA_UNMODIFIED;
|
737
786
|
|
738
787
|
/* support "skip worktree" index bit */
|
739
|
-
else if ((oitem->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE) != 0)
|
788
|
+
} else if ((oitem->flags_extended & GIT_IDXENTRY_SKIP_WORKTREE) != 0) {
|
740
789
|
status = GIT_DELTA_UNMODIFIED;
|
741
790
|
|
742
791
|
/* if basic type of file changed, then split into delete and add */
|
743
|
-
else if (GIT_MODE_TYPE(omode) != GIT_MODE_TYPE(nmode)) {
|
744
|
-
if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE))
|
792
|
+
} else if (GIT_MODE_TYPE(omode) != GIT_MODE_TYPE(nmode)) {
|
793
|
+
if (DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_TYPECHANGE)) {
|
745
794
|
status = GIT_DELTA_TYPECHANGE;
|
795
|
+
}
|
796
|
+
|
746
797
|
else if (nmode == GIT_FILEMODE_UNREADABLE) {
|
747
|
-
if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem)))
|
748
|
-
error = diff_delta__from_one(diff, GIT_DELTA_UNREADABLE, nitem);
|
798
|
+
if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem, NULL)))
|
799
|
+
error = diff_delta__from_one(diff, GIT_DELTA_UNREADABLE, NULL, nitem);
|
749
800
|
return error;
|
750
801
|
}
|
802
|
+
|
751
803
|
else {
|
752
|
-
if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem)))
|
753
|
-
error = diff_delta__from_one(diff, GIT_DELTA_ADDED, nitem);
|
804
|
+
if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem, NULL)))
|
805
|
+
error = diff_delta__from_one(diff, GIT_DELTA_ADDED, NULL, nitem);
|
754
806
|
return error;
|
755
807
|
}
|
756
|
-
}
|
757
808
|
|
758
809
|
/* if oids and modes match (and are valid), then file is unmodified */
|
759
|
-
else if (git_oid_equal(&oitem->id, &nitem->id) &&
|
810
|
+
} else if (git_oid_equal(&oitem->id, &nitem->id) &&
|
760
811
|
omode == nmode &&
|
761
|
-
!git_oid_iszero(&oitem->id))
|
812
|
+
!git_oid_iszero(&oitem->id)) {
|
762
813
|
status = GIT_DELTA_UNMODIFIED;
|
763
814
|
|
764
815
|
/* if we have an unknown OID and a workdir iterator, then check some
|
765
816
|
* circumstances that can accelerate things or need special handling
|
766
817
|
*/
|
767
|
-
else if (git_oid_iszero(&nitem->id) && new_is_workdir) {
|
818
|
+
} else if (git_oid_iszero(&nitem->id) && new_is_workdir) {
|
768
819
|
bool use_ctime = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_CTIME) != 0);
|
769
820
|
bool use_nanos = ((diff->diffcaps & GIT_DIFFCAPS_TRUST_NANOSECS) != 0);
|
821
|
+
git_index *index;
|
822
|
+
git_iterator_index(&index, info->new_iter);
|
770
823
|
|
771
824
|
status = GIT_DELTA_UNMODIFIED;
|
772
825
|
|
773
|
-
/* TODO: add check against index file st_mtime to avoid racy-git */
|
774
|
-
|
775
826
|
if (S_ISGITLINK(nmode)) {
|
776
827
|
if ((error = maybe_modified_submodule(&status, &noid, diff, info)) < 0)
|
777
828
|
return error;
|
@@ -790,17 +841,18 @@ static int maybe_modified(
|
|
790
841
|
!diff_time_eq(&oitem->ctime, &nitem->ctime, use_nanos)) ||
|
791
842
|
oitem->ino != nitem->ino ||
|
792
843
|
oitem->uid != nitem->uid ||
|
793
|
-
oitem->gid != nitem->gid
|
844
|
+
oitem->gid != nitem->gid ||
|
845
|
+
(index && nitem->mtime.seconds >= index->stamp.mtime))
|
794
846
|
{
|
795
847
|
status = GIT_DELTA_MODIFIED;
|
796
848
|
modified_uncertain = true;
|
797
849
|
}
|
798
|
-
}
|
799
850
|
|
800
851
|
/* if mode is GITLINK and submodules are ignored, then skip */
|
801
|
-
else if (S_ISGITLINK(nmode) &&
|
802
|
-
DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_SUBMODULES))
|
852
|
+
} else if (S_ISGITLINK(nmode) &&
|
853
|
+
DIFF_FLAG_IS_SET(diff, GIT_DIFF_IGNORE_SUBMODULES)) {
|
803
854
|
status = GIT_DELTA_UNMODIFIED;
|
855
|
+
}
|
804
856
|
|
805
857
|
/* if we got here and decided that the files are modified, but we
|
806
858
|
* haven't calculated the OID of the new item, then calculate it now
|
@@ -809,8 +861,9 @@ static int maybe_modified(
|
|
809
861
|
const git_oid *update_check =
|
810
862
|
DIFF_FLAG_IS_SET(diff, GIT_DIFF_UPDATE_INDEX) && omode == nmode ?
|
811
863
|
&oitem->id : NULL;
|
864
|
+
|
812
865
|
if ((error = git_diff__oid_for_entry(
|
813
|
-
&noid, diff, nitem, update_check)) < 0)
|
866
|
+
&noid, diff, nitem, nmode, update_check)) < 0)
|
814
867
|
return error;
|
815
868
|
|
816
869
|
/* if oid matches, then mark unmodified (except submodules, where
|
@@ -830,8 +883,9 @@ static int maybe_modified(
|
|
830
883
|
DIFF_FLAG_IS_SET(diff, GIT_DIFF_INCLUDE_CASECHANGE) &&
|
831
884
|
strcmp(oitem->path, nitem->path) != 0) {
|
832
885
|
|
833
|
-
if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem)))
|
834
|
-
error = diff_delta__from_one(diff, GIT_DELTA_ADDED, nitem);
|
886
|
+
if (!(error = diff_delta__from_one(diff, GIT_DELTA_DELETED, oitem, NULL)))
|
887
|
+
error = diff_delta__from_one(diff, GIT_DELTA_ADDED, NULL, nitem);
|
888
|
+
|
835
889
|
return error;
|
836
890
|
}
|
837
891
|
|
@@ -857,6 +911,84 @@ static bool entry_is_prefixed(
|
|
857
911
|
item->path[pathlen] == '/');
|
858
912
|
}
|
859
913
|
|
914
|
+
static int iterator_current(
|
915
|
+
const git_index_entry **entry,
|
916
|
+
git_iterator *iterator)
|
917
|
+
{
|
918
|
+
int error;
|
919
|
+
|
920
|
+
if ((error = git_iterator_current(entry, iterator)) == GIT_ITEROVER) {
|
921
|
+
*entry = NULL;
|
922
|
+
error = 0;
|
923
|
+
}
|
924
|
+
|
925
|
+
return error;
|
926
|
+
}
|
927
|
+
|
928
|
+
static int iterator_advance(
|
929
|
+
const git_index_entry **entry,
|
930
|
+
git_iterator *iterator)
|
931
|
+
{
|
932
|
+
const git_index_entry *prev_entry = *entry;
|
933
|
+
int cmp, error;
|
934
|
+
|
935
|
+
/* if we're looking for conflicts, we only want to report
|
936
|
+
* one conflict for each file, instead of all three sides.
|
937
|
+
* so if this entry is a conflict for this file, and the
|
938
|
+
* previous one was a conflict for the same file, skip it.
|
939
|
+
*/
|
940
|
+
while ((error = git_iterator_advance(entry, iterator)) == 0) {
|
941
|
+
if (!(iterator->flags & GIT_ITERATOR_INCLUDE_CONFLICTS) ||
|
942
|
+
!git_index_entry_is_conflict(prev_entry) ||
|
943
|
+
!git_index_entry_is_conflict(*entry))
|
944
|
+
break;
|
945
|
+
|
946
|
+
cmp = (iterator->flags & GIT_ITERATOR_IGNORE_CASE) ?
|
947
|
+
strcasecmp(prev_entry->path, (*entry)->path) :
|
948
|
+
strcmp(prev_entry->path, (*entry)->path);
|
949
|
+
|
950
|
+
if (cmp)
|
951
|
+
break;
|
952
|
+
}
|
953
|
+
|
954
|
+
if (error == GIT_ITEROVER) {
|
955
|
+
*entry = NULL;
|
956
|
+
error = 0;
|
957
|
+
}
|
958
|
+
|
959
|
+
return error;
|
960
|
+
}
|
961
|
+
|
962
|
+
static int iterator_advance_into(
|
963
|
+
const git_index_entry **entry,
|
964
|
+
git_iterator *iterator)
|
965
|
+
{
|
966
|
+
int error;
|
967
|
+
|
968
|
+
if ((error = git_iterator_advance_into(entry, iterator)) == GIT_ITEROVER) {
|
969
|
+
*entry = NULL;
|
970
|
+
error = 0;
|
971
|
+
}
|
972
|
+
|
973
|
+
return error;
|
974
|
+
}
|
975
|
+
|
976
|
+
static int iterator_advance_over_with_status(
|
977
|
+
const git_index_entry **entry,
|
978
|
+
git_iterator_status_t *status,
|
979
|
+
git_iterator *iterator)
|
980
|
+
{
|
981
|
+
int error;
|
982
|
+
|
983
|
+
if ((error = git_iterator_advance_over_with_status(
|
984
|
+
entry, status, iterator)) == GIT_ITEROVER) {
|
985
|
+
*entry = NULL;
|
986
|
+
error = 0;
|
987
|
+
}
|
988
|
+
|
989
|
+
return error;
|
990
|
+
}
|
991
|
+
|
860
992
|
static int handle_unmatched_new_item(
|
861
993
|
git_diff *diff, diff_in_progress *info)
|
862
994
|
{
|
@@ -868,8 +1000,12 @@ static int handle_unmatched_new_item(
|
|
868
1000
|
/* check if this is a prefix of the other side */
|
869
1001
|
contains_oitem = entry_is_prefixed(diff, info->oitem, nitem);
|
870
1002
|
|
1003
|
+
/* update delta_type if this item is conflicted */
|
1004
|
+
if (git_index_entry_is_conflict(nitem))
|
1005
|
+
delta_type = GIT_DELTA_CONFLICTED;
|
1006
|
+
|
871
1007
|
/* update delta_type if this item is ignored */
|
872
|
-
if (git_iterator_current_is_ignored(info->new_iter))
|
1008
|
+
else if (git_iterator_current_is_ignored(info->new_iter))
|
873
1009
|
delta_type = GIT_DELTA_IGNORED;
|
874
1010
|
|
875
1011
|
if (nitem->mode == GIT_FILEMODE_TREE) {
|
@@ -904,18 +1040,17 @@ static int handle_unmatched_new_item(
|
|
904
1040
|
git_iterator_status_t untracked_state;
|
905
1041
|
|
906
1042
|
/* attempt to insert record for this directory */
|
907
|
-
if ((error = diff_delta__from_one(diff, delta_type, nitem)) != 0)
|
1043
|
+
if ((error = diff_delta__from_one(diff, delta_type, NULL, nitem)) != 0)
|
908
1044
|
return error;
|
909
1045
|
|
910
1046
|
/* if delta wasn't created (because of rules), just skip ahead */
|
911
1047
|
last = diff_delta__last_for_item(diff, nitem);
|
912
1048
|
if (!last)
|
913
|
-
return
|
1049
|
+
return iterator_advance(&info->nitem, info->new_iter);
|
914
1050
|
|
915
1051
|
/* iterate into dir looking for an actual untracked file */
|
916
|
-
if ((error =
|
917
|
-
&info->nitem, &untracked_state, info->new_iter)) < 0
|
918
|
-
error != GIT_ITEROVER)
|
1052
|
+
if ((error = iterator_advance_over_with_status(
|
1053
|
+
&info->nitem, &untracked_state, info->new_iter)) < 0)
|
919
1054
|
return error;
|
920
1055
|
|
921
1056
|
/* if we found nothing or just ignored items, update the record */
|
@@ -935,7 +1070,7 @@ static int handle_unmatched_new_item(
|
|
935
1070
|
|
936
1071
|
/* try to advance into directory if necessary */
|
937
1072
|
if (recurse_into_dir) {
|
938
|
-
error =
|
1073
|
+
error = iterator_advance_into(&info->nitem, info->new_iter);
|
939
1074
|
|
940
1075
|
/* if real error or no error, proceed with iteration */
|
941
1076
|
if (error != GIT_ENOTFOUND)
|
@@ -946,7 +1081,7 @@ static int handle_unmatched_new_item(
|
|
946
1081
|
* it or ignore it
|
947
1082
|
*/
|
948
1083
|
if (contains_oitem)
|
949
|
-
return
|
1084
|
+
return iterator_advance(&info->nitem, info->new_iter);
|
950
1085
|
delta_type = GIT_DELTA_IGNORED;
|
951
1086
|
}
|
952
1087
|
}
|
@@ -955,10 +1090,12 @@ static int handle_unmatched_new_item(
|
|
955
1090
|
DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_RECURSE_IGNORED_DIRS) &&
|
956
1091
|
git_iterator_current_tree_is_ignored(info->new_iter))
|
957
1092
|
/* item contained in ignored directory, so skip over it */
|
958
|
-
return
|
1093
|
+
return iterator_advance(&info->nitem, info->new_iter);
|
959
1094
|
|
960
|
-
else if (info->new_iter->type != GIT_ITERATOR_TYPE_WORKDIR)
|
961
|
-
delta_type
|
1095
|
+
else if (info->new_iter->type != GIT_ITERATOR_TYPE_WORKDIR) {
|
1096
|
+
if (delta_type != GIT_DELTA_CONFLICTED)
|
1097
|
+
delta_type = GIT_DELTA_ADDED;
|
1098
|
+
}
|
962
1099
|
|
963
1100
|
else if (nitem->mode == GIT_FILEMODE_COMMIT) {
|
964
1101
|
/* ignore things that are not actual submodules */
|
@@ -968,12 +1105,12 @@ static int handle_unmatched_new_item(
|
|
968
1105
|
|
969
1106
|
/* if this contains a tracked item, treat as normal TREE */
|
970
1107
|
if (contains_oitem) {
|
971
|
-
error =
|
1108
|
+
error = iterator_advance_into(&info->nitem, info->new_iter);
|
972
1109
|
if (error != GIT_ENOTFOUND)
|
973
1110
|
return error;
|
974
1111
|
|
975
1112
|
giterr_clear();
|
976
|
-
return
|
1113
|
+
return iterator_advance(&info->nitem, info->new_iter);
|
977
1114
|
}
|
978
1115
|
}
|
979
1116
|
}
|
@@ -986,7 +1123,7 @@ static int handle_unmatched_new_item(
|
|
986
1123
|
}
|
987
1124
|
|
988
1125
|
/* Actually create the record for this item if necessary */
|
989
|
-
if ((error = diff_delta__from_one(diff, delta_type, nitem)) != 0)
|
1126
|
+
if ((error = diff_delta__from_one(diff, delta_type, NULL, nitem)) != 0)
|
990
1127
|
return error;
|
991
1128
|
|
992
1129
|
/* If user requested TYPECHANGE records, then check for that instead of
|
@@ -1004,14 +1141,20 @@ static int handle_unmatched_new_item(
|
|
1004
1141
|
}
|
1005
1142
|
}
|
1006
1143
|
|
1007
|
-
return
|
1144
|
+
return iterator_advance(&info->nitem, info->new_iter);
|
1008
1145
|
}
|
1009
1146
|
|
1010
1147
|
static int handle_unmatched_old_item(
|
1011
1148
|
git_diff *diff, diff_in_progress *info)
|
1012
1149
|
{
|
1013
|
-
|
1014
|
-
|
1150
|
+
git_delta_t delta_type = GIT_DELTA_DELETED;
|
1151
|
+
int error;
|
1152
|
+
|
1153
|
+
/* update delta_type if this item is conflicted */
|
1154
|
+
if (git_index_entry_is_conflict(info->oitem))
|
1155
|
+
delta_type = GIT_DELTA_CONFLICTED;
|
1156
|
+
|
1157
|
+
if ((error = diff_delta__from_one(diff, delta_type, info->oitem, NULL)) < 0)
|
1015
1158
|
return error;
|
1016
1159
|
|
1017
1160
|
/* if we are generating TYPECHANGE records then check for that
|
@@ -1033,10 +1176,10 @@ static int handle_unmatched_old_item(
|
|
1033
1176
|
*/
|
1034
1177
|
if (S_ISDIR(info->nitem->mode) &&
|
1035
1178
|
DIFF_FLAG_ISNT_SET(diff, GIT_DIFF_RECURSE_UNTRACKED_DIRS))
|
1036
|
-
return
|
1179
|
+
return iterator_advance(&info->nitem, info->new_iter);
|
1037
1180
|
}
|
1038
1181
|
|
1039
|
-
return
|
1182
|
+
return iterator_advance(&info->oitem, info->old_iter);
|
1040
1183
|
}
|
1041
1184
|
|
1042
1185
|
static int handle_matched_item(
|
@@ -1047,9 +1190,8 @@ static int handle_matched_item(
|
|
1047
1190
|
if ((error = maybe_modified(diff, info)) < 0)
|
1048
1191
|
return error;
|
1049
1192
|
|
1050
|
-
if (!(error =
|
1051
|
-
error
|
1052
|
-
error = git_iterator_advance(&info->nitem, info->new_iter);
|
1193
|
+
if (!(error = iterator_advance(&info->oitem, info->old_iter)))
|
1194
|
+
error = iterator_advance(&info->nitem, info->new_iter);
|
1053
1195
|
|
1054
1196
|
return error;
|
1055
1197
|
}
|
@@ -1085,13 +1227,9 @@ int git_diff__from_iterators(
|
|
1085
1227
|
if ((error = diff_list_apply_options(diff, opts)) < 0)
|
1086
1228
|
goto cleanup;
|
1087
1229
|
|
1088
|
-
if ((error =
|
1089
|
-
error
|
1230
|
+
if ((error = iterator_current(&info.oitem, old_iter)) < 0 ||
|
1231
|
+
(error = iterator_current(&info.nitem, new_iter)) < 0)
|
1090
1232
|
goto cleanup;
|
1091
|
-
if ((error = git_iterator_current(&info.nitem, new_iter)) < 0 &&
|
1092
|
-
error != GIT_ITEROVER)
|
1093
|
-
goto cleanup;
|
1094
|
-
error = 0;
|
1095
1233
|
|
1096
1234
|
/* run iterators building diffs */
|
1097
1235
|
while (!error && (info.oitem || info.nitem)) {
|
@@ -1113,10 +1251,6 @@ int git_diff__from_iterators(
|
|
1113
1251
|
*/
|
1114
1252
|
else
|
1115
1253
|
error = handle_matched_item(diff, &info);
|
1116
|
-
|
1117
|
-
/* because we are iterating over two lists, ignore ITEROVER */
|
1118
|
-
if (error == GIT_ITEROVER)
|
1119
|
-
error = 0;
|
1120
1254
|
}
|
1121
1255
|
|
1122
1256
|
diff->perf.stat_calls += old_iter->stat_calls + new_iter->stat_calls;
|
@@ -1186,6 +1320,8 @@ int git_diff_tree_to_index(
|
|
1186
1320
|
{
|
1187
1321
|
int error = 0;
|
1188
1322
|
bool index_ignore_case = false;
|
1323
|
+
git_iterator_flag_t iflag = GIT_ITERATOR_DONT_IGNORE_CASE |
|
1324
|
+
GIT_ITERATOR_INCLUDE_CONFLICTS;
|
1189
1325
|
|
1190
1326
|
assert(diff && repo);
|
1191
1327
|
|
@@ -1195,10 +1331,8 @@ int git_diff_tree_to_index(
|
|
1195
1331
|
index_ignore_case = index->ignore_case;
|
1196
1332
|
|
1197
1333
|
DIFF_FROM_ITERATORS(
|
1198
|
-
git_iterator_for_tree(
|
1199
|
-
|
1200
|
-
git_iterator_for_index(
|
1201
|
-
&b, index, GIT_ITERATOR_DONT_IGNORE_CASE, pfx, pfx)
|
1334
|
+
git_iterator_for_tree(&a, old_tree, iflag, pfx, pfx),
|
1335
|
+
git_iterator_for_index(&b, index, iflag, pfx, pfx)
|
1202
1336
|
);
|
1203
1337
|
|
1204
1338
|
/* if index is in case-insensitive order, re-sort deltas to match */
|
@@ -1222,12 +1356,13 @@ int git_diff_index_to_workdir(
|
|
1222
1356
|
return error;
|
1223
1357
|
|
1224
1358
|
DIFF_FROM_ITERATORS(
|
1225
|
-
git_iterator_for_index(
|
1359
|
+
git_iterator_for_index(
|
1360
|
+
&a, index, GIT_ITERATOR_INCLUDE_CONFLICTS, pfx, pfx),
|
1226
1361
|
git_iterator_for_workdir(
|
1227
1362
|
&b, repo, index, NULL, GIT_ITERATOR_DONT_AUTOEXPAND, pfx, pfx)
|
1228
1363
|
);
|
1229
1364
|
|
1230
|
-
if (!error && DIFF_FLAG_IS_SET(*diff, GIT_DIFF_UPDATE_INDEX))
|
1365
|
+
if (!error && DIFF_FLAG_IS_SET(*diff, GIT_DIFF_UPDATE_INDEX) && (*diff)->index_updated)
|
1231
1366
|
error = git_index_write(index);
|
1232
1367
|
|
1233
1368
|
return error;
|