rugged 0.24.6.1 → 0.25.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/ext/rugged/extconf.rb +9 -2
- data/ext/rugged/rugged.c +85 -21
- data/ext/rugged/rugged.h +7 -21
- data/ext/rugged/rugged_backend.c +3 -20
- data/ext/rugged/rugged_blame.c +7 -24
- data/ext/rugged/rugged_blob.c +136 -59
- data/ext/rugged/rugged_branch.c +3 -20
- data/ext/rugged/rugged_branch_collection.c +3 -20
- data/ext/rugged/rugged_commit.c +251 -101
- data/ext/rugged/rugged_config.c +3 -20
- data/ext/rugged/rugged_cred.c +3 -20
- data/ext/rugged/rugged_diff.c +3 -20
- data/ext/rugged/rugged_diff_delta.c +3 -20
- data/ext/rugged/rugged_diff_hunk.c +3 -20
- data/ext/rugged/rugged_diff_line.c +3 -20
- data/ext/rugged/rugged_index.c +46 -229
- data/ext/rugged/rugged_note.c +3 -20
- data/ext/rugged/rugged_object.c +3 -20
- data/ext/rugged/rugged_patch.c +192 -34
- data/ext/rugged/rugged_rebase.c +90 -48
- data/ext/rugged/rugged_reference.c +4 -21
- data/ext/rugged/rugged_reference_collection.c +3 -20
- data/ext/rugged/rugged_remote.c +70 -42
- data/ext/rugged/rugged_remote_collection.c +3 -20
- data/ext/rugged/rugged_repo.c +50 -59
- data/ext/rugged/rugged_revwalk.c +4 -21
- data/ext/rugged/rugged_settings.c +3 -20
- data/ext/rugged/rugged_signature.c +3 -20
- data/ext/rugged/rugged_submodule.c +4 -21
- data/ext/rugged/rugged_submodule_collection.c +3 -20
- data/ext/rugged/rugged_tag.c +3 -20
- data/ext/rugged/rugged_tag_collection.c +3 -20
- data/ext/rugged/rugged_tree.c +189 -184
- data/lib/rugged/attributes.rb +5 -0
- data/lib/rugged/blob.rb +5 -0
- data/lib/rugged/branch.rb +6 -1
- data/lib/rugged/commit.rb +5 -0
- data/lib/rugged/console.rb +5 -0
- data/lib/rugged/credentials.rb +5 -0
- data/lib/rugged/diff/delta.rb +5 -0
- data/lib/rugged/diff/hunk.rb +5 -0
- data/lib/rugged/diff/line.rb +5 -0
- data/lib/rugged/diff.rb +5 -0
- data/lib/rugged/index.rb +120 -0
- data/lib/rugged/object.rb +5 -0
- data/lib/rugged/patch.rb +5 -0
- data/lib/rugged/reference.rb +5 -0
- data/lib/rugged/remote.rb +5 -0
- data/lib/rugged/repository.rb +9 -4
- data/lib/rugged/submodule_collection.rb +5 -0
- data/lib/rugged/tag.rb +5 -0
- data/lib/rugged/tree.rb +156 -1
- data/lib/rugged/version.rb +6 -1
- data/lib/rugged/walker.rb +5 -0
- data/lib/rugged.rb +5 -0
- data/vendor/libgit2/CMakeLists.txt +12 -2
- data/vendor/libgit2/include/git2/blob.h +39 -28
- data/vendor/libgit2/include/git2/commit.h +76 -0
- data/vendor/libgit2/include/git2/common.h +21 -1
- data/vendor/libgit2/include/git2/describe.h +5 -2
- data/vendor/libgit2/include/git2/diff.h +62 -7
- data/vendor/libgit2/include/git2/errors.h +2 -1
- data/vendor/libgit2/include/git2/index.h +25 -0
- data/vendor/libgit2/include/git2/merge.h +10 -1
- data/vendor/libgit2/include/git2/odb.h +47 -1
- data/vendor/libgit2/include/git2/pack.h +4 -4
- data/vendor/libgit2/include/git2/patch.h +1 -1
- data/vendor/libgit2/include/git2/proxy.h +92 -0
- data/vendor/libgit2/include/git2/refs.h +11 -0
- data/vendor/libgit2/include/git2/remote.h +21 -8
- data/vendor/libgit2/include/git2/repository.h +20 -1
- data/vendor/libgit2/include/git2/revwalk.h +4 -6
- data/vendor/libgit2/include/git2/signature.h +13 -0
- data/vendor/libgit2/include/git2/submodule.h +11 -3
- data/vendor/libgit2/include/git2/sys/merge.h +177 -0
- data/vendor/libgit2/include/git2/sys/odb_backend.h +11 -0
- data/vendor/libgit2/include/git2/sys/remote.h +16 -0
- data/vendor/libgit2/include/git2/sys/stream.h +2 -1
- data/vendor/libgit2/include/git2/sys/time.h +31 -0
- data/vendor/libgit2/include/git2/sys/transport.h +3 -1
- data/vendor/libgit2/include/git2/tag.h +9 -0
- data/vendor/libgit2/include/git2/transaction.h +9 -0
- data/vendor/libgit2/include/git2/tree.h +55 -0
- data/vendor/libgit2/include/git2/version.h +4 -4
- data/vendor/libgit2/include/git2.h +1 -0
- data/vendor/libgit2/src/annotated_commit.c +99 -80
- data/vendor/libgit2/src/annotated_commit.h +5 -2
- data/vendor/libgit2/src/apply.c +377 -0
- data/vendor/libgit2/src/apply.h +21 -0
- data/vendor/libgit2/src/array.h +0 -1
- data/vendor/libgit2/src/blob.c +71 -39
- data/vendor/libgit2/src/branch.c +7 -5
- data/vendor/libgit2/src/buffer.c +252 -20
- data/vendor/libgit2/src/buffer.h +8 -0
- data/vendor/libgit2/src/checkout.c +69 -42
- data/vendor/libgit2/src/clone.c +0 -8
- data/vendor/libgit2/src/commit.c +193 -49
- data/vendor/libgit2/src/commit_list.c +8 -3
- data/vendor/libgit2/src/commit_list.h +1 -0
- data/vendor/libgit2/src/common.h +2 -1
- data/vendor/libgit2/src/config.c +3 -3
- data/vendor/libgit2/src/config_file.c +20 -10
- data/vendor/libgit2/src/crlf.c +1 -0
- data/vendor/libgit2/src/curl_stream.c +106 -6
- data/vendor/libgit2/src/delta.c +238 -62
- data/vendor/libgit2/src/delta.h +79 -58
- data/vendor/libgit2/src/describe.c +1 -1
- data/vendor/libgit2/src/diff.c +32 -1554
- data/vendor/libgit2/src/diff.h +14 -122
- data/vendor/libgit2/src/diff_driver.c +4 -6
- data/vendor/libgit2/src/diff_file.c +3 -0
- data/vendor/libgit2/src/diff_generate.c +1613 -0
- data/vendor/libgit2/src/diff_generate.h +123 -0
- data/vendor/libgit2/src/diff_parse.c +101 -0
- data/vendor/libgit2/src/diff_parse.h +18 -0
- data/vendor/libgit2/src/diff_print.c +263 -144
- data/vendor/libgit2/src/diff_stats.c +21 -12
- data/vendor/libgit2/src/diff_tform.c +1 -0
- data/vendor/libgit2/src/diff_tform.h +22 -0
- data/vendor/libgit2/src/diff_xdiff.c +9 -9
- data/vendor/libgit2/src/diff_xdiff.h +5 -5
- data/vendor/libgit2/src/fetchhead.c +8 -8
- data/vendor/libgit2/src/filebuf.c +6 -1
- data/vendor/libgit2/src/filebuf.h +1 -0
- data/vendor/libgit2/src/fileops.c +22 -1
- data/vendor/libgit2/src/fileops.h +8 -2
- data/vendor/libgit2/src/fnmatch.c +18 -5
- data/vendor/libgit2/src/global.c +21 -4
- data/vendor/libgit2/src/global.h +6 -0
- data/vendor/libgit2/src/graph.c +1 -1
- data/vendor/libgit2/src/index.c +159 -46
- data/vendor/libgit2/src/index.h +2 -0
- data/vendor/libgit2/src/iterator.c +1573 -1468
- data/vendor/libgit2/src/iterator.h +52 -69
- data/vendor/libgit2/src/merge.c +163 -64
- data/vendor/libgit2/src/merge.h +61 -2
- data/vendor/libgit2/src/merge_driver.c +397 -0
- data/vendor/libgit2/src/merge_driver.h +60 -0
- data/vendor/libgit2/src/merge_file.c +11 -49
- data/vendor/libgit2/src/netops.c +12 -10
- data/vendor/libgit2/src/object_api.c +19 -1
- data/vendor/libgit2/src/odb.c +228 -52
- data/vendor/libgit2/src/odb_loose.c +19 -1
- data/vendor/libgit2/src/odb_mempack.c +1 -1
- data/vendor/libgit2/src/odb_pack.c +27 -1
- data/vendor/libgit2/src/openssl_stream.c +4 -5
- data/vendor/libgit2/src/pack-objects.c +105 -76
- data/vendor/libgit2/src/pack-objects.h +13 -12
- data/vendor/libgit2/src/pack.c +16 -10
- data/vendor/libgit2/src/pack.h +2 -0
- data/vendor/libgit2/src/patch.c +216 -0
- data/vendor/libgit2/src/patch.h +66 -0
- data/vendor/libgit2/src/{diff_patch.c → patch_generate.c} +203 -376
- data/vendor/libgit2/src/patch_generate.h +68 -0
- data/vendor/libgit2/src/patch_parse.c +1159 -0
- data/vendor/libgit2/src/patch_parse.h +56 -0
- data/vendor/libgit2/src/path.c +38 -2
- data/vendor/libgit2/src/path.h +18 -0
- data/vendor/libgit2/src/pathspec.c +1 -1
- data/vendor/libgit2/src/pool.h +5 -0
- data/vendor/libgit2/src/pqueue.c +12 -5
- data/vendor/libgit2/src/pqueue.h +1 -0
- data/vendor/libgit2/src/proxy.c +32 -0
- data/vendor/libgit2/src/proxy.h +14 -0
- data/vendor/libgit2/src/push.c +1 -1
- data/vendor/libgit2/src/rebase.c +63 -36
- data/vendor/libgit2/src/refdb.c +4 -2
- data/vendor/libgit2/src/refdb_fs.c +82 -54
- data/vendor/libgit2/src/refs.c +13 -1
- data/vendor/libgit2/src/remote.c +20 -81
- data/vendor/libgit2/src/repository.c +212 -29
- data/vendor/libgit2/src/reset.c +1 -1
- data/vendor/libgit2/src/revparse.c +1 -1
- data/vendor/libgit2/src/revwalk.c +260 -184
- data/vendor/libgit2/src/settings.c +11 -3
- data/vendor/libgit2/src/signature.c +27 -2
- data/vendor/libgit2/src/sortedcache.c +14 -5
- data/vendor/libgit2/src/stash.c +1 -0
- data/vendor/libgit2/src/status.c +1 -0
- data/vendor/libgit2/src/stransport_stream.c +4 -2
- data/vendor/libgit2/src/stream.h +2 -2
- data/vendor/libgit2/src/submodule.c +16 -4
- data/vendor/libgit2/src/sysdir.c +1 -1
- data/vendor/libgit2/src/transport.c +3 -5
- data/vendor/libgit2/src/transports/http.c +38 -13
- data/vendor/libgit2/src/transports/local.c +4 -1
- data/vendor/libgit2/src/transports/smart.c +6 -0
- data/vendor/libgit2/src/transports/smart.h +1 -0
- data/vendor/libgit2/src/transports/smart_pkt.c +5 -13
- data/vendor/libgit2/src/transports/smart_protocol.c +22 -7
- data/vendor/libgit2/src/transports/winhttp.c +144 -11
- data/vendor/libgit2/src/tree.c +267 -2
- data/vendor/libgit2/src/unix/posix.h +10 -0
- data/vendor/libgit2/src/unix/pthread.h +2 -0
- data/vendor/libgit2/src/util.c +25 -2
- data/vendor/libgit2/src/util.h +10 -0
- data/vendor/libgit2/src/varint.c +44 -0
- data/vendor/libgit2/src/varint.h +15 -0
- data/vendor/libgit2/src/vector.c +58 -0
- data/vendor/libgit2/src/vector.h +8 -0
- data/vendor/libgit2/src/win32/posix.h +3 -0
- data/vendor/libgit2/src/win32/thread.c +18 -0
- data/vendor/libgit2/src/win32/thread.h +2 -0
- data/vendor/libgit2/src/win32/w32_util.h +1 -1
- data/vendor/libgit2/src/zstream.c +37 -8
- data/vendor/libgit2/src/zstream.h +8 -1
- metadata +100 -82
- data/vendor/libgit2/Makefile.embed +0 -60
- data/vendor/libgit2/src/delta-apply.c +0 -166
- data/vendor/libgit2/src/delta-apply.h +0 -62
- data/vendor/libgit2/src/diff_patch.h +0 -83
@@ -34,10 +34,19 @@ typedef enum {
|
|
34
34
|
GIT_ITERATOR_DONT_AUTOEXPAND = (1u << 3),
|
35
35
|
/** convert precomposed unicode to decomposed unicode */
|
36
36
|
GIT_ITERATOR_PRECOMPOSE_UNICODE = (1u << 4),
|
37
|
+
/** never convert precomposed unicode to decomposed unicode */
|
38
|
+
GIT_ITERATOR_DONT_PRECOMPOSE_UNICODE = (1u << 5),
|
37
39
|
/** include conflicts */
|
38
|
-
GIT_ITERATOR_INCLUDE_CONFLICTS = (1u <<
|
40
|
+
GIT_ITERATOR_INCLUDE_CONFLICTS = (1u << 6),
|
39
41
|
} git_iterator_flag_t;
|
40
42
|
|
43
|
+
typedef enum {
|
44
|
+
GIT_ITERATOR_STATUS_NORMAL = 0,
|
45
|
+
GIT_ITERATOR_STATUS_IGNORED = 1,
|
46
|
+
GIT_ITERATOR_STATUS_EMPTY = 2,
|
47
|
+
GIT_ITERATOR_STATUS_FILTERED = 3
|
48
|
+
} git_iterator_status_t;
|
49
|
+
|
41
50
|
typedef struct {
|
42
51
|
const char *start;
|
43
52
|
const char *end;
|
@@ -57,23 +66,33 @@ typedef struct {
|
|
57
66
|
int (*current)(const git_index_entry **, git_iterator *);
|
58
67
|
int (*advance)(const git_index_entry **, git_iterator *);
|
59
68
|
int (*advance_into)(const git_index_entry **, git_iterator *);
|
60
|
-
int (*
|
61
|
-
|
62
|
-
int (*
|
69
|
+
int (*advance_over)(
|
70
|
+
const git_index_entry **, git_iterator_status_t *, git_iterator *);
|
71
|
+
int (*reset)(git_iterator *);
|
63
72
|
void (*free)(git_iterator *);
|
64
73
|
} git_iterator_callbacks;
|
65
74
|
|
66
75
|
struct git_iterator {
|
67
76
|
git_iterator_type_t type;
|
68
77
|
git_iterator_callbacks *cb;
|
78
|
+
|
69
79
|
git_repository *repo;
|
80
|
+
git_index *index;
|
81
|
+
|
70
82
|
char *start;
|
83
|
+
size_t start_len;
|
84
|
+
|
71
85
|
char *end;
|
86
|
+
size_t end_len;
|
87
|
+
|
88
|
+
bool started;
|
89
|
+
bool ended;
|
72
90
|
git_vector pathlist;
|
73
91
|
size_t pathlist_walk_idx;
|
74
92
|
int (*strcomp)(const char *a, const char *b);
|
75
93
|
int (*strncomp)(const char *a, const char *b, size_t n);
|
76
94
|
int (*prefixcomp)(const char *str, const char *prefix);
|
95
|
+
int (*entry_srch)(const void *key, const void *array_member);
|
77
96
|
size_t stat_calls;
|
78
97
|
unsigned int flags;
|
79
98
|
};
|
@@ -181,54 +200,38 @@ GIT_INLINE(int) git_iterator_advance_into(
|
|
181
200
|
return iter->cb->advance_into(entry, iter);
|
182
201
|
}
|
183
202
|
|
184
|
-
|
185
|
-
*
|
203
|
+
/* Advance over a directory and check if it contains no files or just
|
204
|
+
* ignored files.
|
186
205
|
*
|
187
|
-
*
|
188
|
-
* directory is
|
189
|
-
*
|
190
|
-
*
|
206
|
+
* In a tree or the index, all directories will contain files, but in the
|
207
|
+
* working directory it is possible to have an empty directory tree or a
|
208
|
+
* tree that only contains ignored files. Many Git operations treat these
|
209
|
+
* cases specially. This advances over a directory (presumably an
|
210
|
+
* untracked directory) but checks during the scan if there are any files
|
211
|
+
* and any non-ignored files.
|
191
212
|
*/
|
192
|
-
GIT_INLINE(int)
|
193
|
-
const git_index_entry **entry,
|
194
|
-
|
195
|
-
|
196
|
-
if (error == GIT_ENOTFOUND) {
|
197
|
-
giterr_clear();
|
198
|
-
error = iter->cb->advance(entry, iter);
|
199
|
-
}
|
200
|
-
return error;
|
201
|
-
}
|
202
|
-
|
203
|
-
/* Seek is currently unimplemented */
|
204
|
-
GIT_INLINE(int) git_iterator_seek(
|
205
|
-
git_iterator *iter, const char *prefix)
|
213
|
+
GIT_INLINE(int) git_iterator_advance_over(
|
214
|
+
const git_index_entry **entry,
|
215
|
+
git_iterator_status_t *status,
|
216
|
+
git_iterator *iter)
|
206
217
|
{
|
207
|
-
return iter->cb->
|
218
|
+
return iter->cb->advance_over(entry, status, iter);
|
208
219
|
}
|
209
220
|
|
210
221
|
/**
|
211
222
|
* Go back to the start of the iteration.
|
212
|
-
*
|
213
|
-
* This resets the iterator to the start of the iteration. It also allows
|
214
|
-
* you to reset the `start` and `end` pathname boundaries of the iteration
|
215
|
-
* when doing so.
|
216
223
|
*/
|
217
|
-
GIT_INLINE(int) git_iterator_reset(
|
218
|
-
git_iterator *iter, const char *start, const char *end)
|
224
|
+
GIT_INLINE(int) git_iterator_reset(git_iterator *iter)
|
219
225
|
{
|
220
|
-
return iter->cb->reset(iter
|
226
|
+
return iter->cb->reset(iter);
|
221
227
|
}
|
222
228
|
|
223
229
|
/**
|
224
|
-
*
|
225
|
-
*
|
226
|
-
* @return 0 if not at end, >0 if at end
|
230
|
+
* Go back to the start of the iteration after updating the `start` and
|
231
|
+
* `end` pathname boundaries of the iteration.
|
227
232
|
*/
|
228
|
-
|
229
|
-
|
230
|
-
return iter->cb->at_end(iter);
|
231
|
-
}
|
233
|
+
extern int git_iterator_reset_range(
|
234
|
+
git_iterator *iter, const char *start, const char *end);
|
232
235
|
|
233
236
|
GIT_INLINE(git_iterator_type_t) git_iterator_type(git_iterator *iter)
|
234
237
|
{
|
@@ -240,6 +243,11 @@ GIT_INLINE(git_repository *) git_iterator_owner(git_iterator *iter)
|
|
240
243
|
return iter->repo;
|
241
244
|
}
|
242
245
|
|
246
|
+
GIT_INLINE(git_index *) git_iterator_index(git_iterator *iter)
|
247
|
+
{
|
248
|
+
return iter->index;
|
249
|
+
}
|
250
|
+
|
243
251
|
GIT_INLINE(git_iterator_flag_t) git_iterator_flags(git_iterator *iter)
|
244
252
|
{
|
245
253
|
return iter->flags;
|
@@ -250,21 +258,19 @@ GIT_INLINE(bool) git_iterator_ignore_case(git_iterator *iter)
|
|
250
258
|
return ((iter->flags & GIT_ITERATOR_IGNORE_CASE) != 0);
|
251
259
|
}
|
252
260
|
|
253
|
-
extern
|
261
|
+
extern void git_iterator_set_ignore_case(
|
262
|
+
git_iterator *iter, bool ignore_case);
|
254
263
|
|
255
264
|
extern int git_iterator_current_tree_entry(
|
256
265
|
const git_tree_entry **entry_out, git_iterator *iter);
|
257
266
|
|
258
267
|
extern int git_iterator_current_parent_tree(
|
259
|
-
const git_tree **tree_out, git_iterator *iter,
|
268
|
+
const git_tree **tree_out, git_iterator *iter, size_t depth);
|
260
269
|
|
261
270
|
extern bool git_iterator_current_is_ignored(git_iterator *iter);
|
262
271
|
|
263
272
|
extern bool git_iterator_current_tree_is_ignored(git_iterator *iter);
|
264
273
|
|
265
|
-
extern int git_iterator_cmp(
|
266
|
-
git_iterator *iter, const char *path_prefix);
|
267
|
-
|
268
274
|
/**
|
269
275
|
* Get full path of the current item from a workdir iterator. This will
|
270
276
|
* return NULL for a non-workdir iterator. The git_buf is still owned by
|
@@ -273,35 +279,12 @@ extern int git_iterator_cmp(
|
|
273
279
|
extern int git_iterator_current_workdir_path(
|
274
280
|
git_buf **path, git_iterator *iter);
|
275
281
|
|
276
|
-
/* Return index pointer if index iterator, else NULL */
|
277
|
-
extern git_index *git_iterator_get_index(git_iterator *iter);
|
278
|
-
|
279
|
-
typedef enum {
|
280
|
-
GIT_ITERATOR_STATUS_NORMAL = 0,
|
281
|
-
GIT_ITERATOR_STATUS_IGNORED = 1,
|
282
|
-
GIT_ITERATOR_STATUS_EMPTY = 2,
|
283
|
-
GIT_ITERATOR_STATUS_FILTERED = 3
|
284
|
-
} git_iterator_status_t;
|
285
|
-
|
286
|
-
/* Advance over a directory and check if it contains no files or just
|
287
|
-
* ignored files.
|
288
|
-
*
|
289
|
-
* In a tree or the index, all directories will contain files, but in the
|
290
|
-
* working directory it is possible to have an empty directory tree or a
|
291
|
-
* tree that only contains ignored files. Many Git operations treat these
|
292
|
-
* cases specially. This advances over a directory (presumably an
|
293
|
-
* untracked directory) but checks during the scan if there are any files
|
294
|
-
* and any non-ignored files.
|
295
|
-
*/
|
296
|
-
extern int git_iterator_advance_over_with_status(
|
297
|
-
const git_index_entry **entry, git_iterator_status_t *status, git_iterator *iter);
|
298
|
-
|
299
282
|
/**
|
300
283
|
* Retrieve the index stored in the iterator.
|
301
284
|
*
|
302
|
-
* Only implemented for the workdir
|
285
|
+
* Only implemented for the workdir and index iterators.
|
303
286
|
*/
|
304
|
-
extern
|
287
|
+
extern git_index *git_iterator_index(git_iterator *iter);
|
305
288
|
|
306
289
|
typedef int (*git_iterator_walk_cb)(
|
307
290
|
const git_index_entry **entries,
|
data/vendor/libgit2/src/merge.c
CHANGED
@@ -18,6 +18,8 @@
|
|
18
18
|
#include "iterator.h"
|
19
19
|
#include "refs.h"
|
20
20
|
#include "diff.h"
|
21
|
+
#include "diff_generate.h"
|
22
|
+
#include "diff_tform.h"
|
21
23
|
#include "checkout.h"
|
22
24
|
#include "tree.h"
|
23
25
|
#include "blob.h"
|
@@ -29,6 +31,7 @@
|
|
29
31
|
#include "annotated_commit.h"
|
30
32
|
#include "commit.h"
|
31
33
|
#include "oidarray.h"
|
34
|
+
#include "merge_driver.h"
|
32
35
|
|
33
36
|
#include "git2/types.h"
|
34
37
|
#include "git2/repository.h"
|
@@ -50,18 +53,6 @@
|
|
50
53
|
#define GIT_MERGE_INDEX_ENTRY_ISFILE(X) S_ISREG((X).mode)
|
51
54
|
|
52
55
|
|
53
|
-
/** Internal merge flags. */
|
54
|
-
enum {
|
55
|
-
/** The merge is for a virtual base in a recursive merge. */
|
56
|
-
GIT_MERGE__VIRTUAL_BASE = (1 << 31),
|
57
|
-
};
|
58
|
-
|
59
|
-
enum {
|
60
|
-
/** Accept the conflict file, staging it as the merge result. */
|
61
|
-
GIT_MERGE_FILE_FAVOR__CONFLICTED = 4,
|
62
|
-
};
|
63
|
-
|
64
|
-
|
65
56
|
typedef enum {
|
66
57
|
TREE_IDX_ANCESTOR = 0,
|
67
58
|
TREE_IDX_OURS = 1,
|
@@ -273,7 +264,7 @@ int git_merge_base(git_oid *out, git_repository *repo, const git_oid *one, const
|
|
273
264
|
int git_merge_bases(git_oidarray *out, git_repository *repo, const git_oid *one, const git_oid *two)
|
274
265
|
{
|
275
266
|
int error;
|
276
|
-
|
267
|
+
git_revwalk *walk;
|
277
268
|
git_commit_list *result, *list;
|
278
269
|
git_array_oid_t array;
|
279
270
|
|
@@ -600,7 +591,7 @@ int git_repository_mergehead_foreach(
|
|
600
591
|
}
|
601
592
|
|
602
593
|
if (*buffer) {
|
603
|
-
giterr_set(GITERR_MERGE, "No EOL at line %
|
594
|
+
giterr_set(GITERR_MERGE, "No EOL at line %"PRIuZ, line_num);
|
604
595
|
error = -1;
|
605
596
|
goto cleanup;
|
606
597
|
}
|
@@ -810,76 +801,158 @@ static int merge_conflict_resolve_one_renamed(
|
|
810
801
|
return error;
|
811
802
|
}
|
812
803
|
|
813
|
-
static
|
814
|
-
|
815
|
-
git_merge_diff_list *diff_list,
|
816
|
-
const git_merge_diff *conflict,
|
817
|
-
const git_merge_file_options *file_opts)
|
804
|
+
static bool merge_conflict_can_resolve_contents(
|
805
|
+
const git_merge_diff *conflict)
|
818
806
|
{
|
819
|
-
const git_index_entry *ancestor = NULL, *ours = NULL, *theirs = NULL;
|
820
|
-
git_merge_file_result result = {0};
|
821
|
-
git_index_entry *index_entry;
|
822
|
-
git_odb *odb = NULL;
|
823
|
-
git_oid automerge_oid;
|
824
|
-
int error = 0;
|
825
|
-
|
826
|
-
assert(resolved && diff_list && conflict);
|
827
|
-
|
828
|
-
*resolved = 0;
|
829
|
-
|
830
807
|
if (!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ||
|
831
808
|
!GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry))
|
832
|
-
return
|
809
|
+
return false;
|
833
810
|
|
834
811
|
/* Reject D/F conflicts */
|
835
812
|
if (conflict->type == GIT_MERGE_DIFF_DIRECTORY_FILE)
|
836
|
-
return
|
813
|
+
return false;
|
837
814
|
|
838
815
|
/* Reject submodules. */
|
839
816
|
if (S_ISGITLINK(conflict->ancestor_entry.mode) ||
|
840
817
|
S_ISGITLINK(conflict->our_entry.mode) ||
|
841
818
|
S_ISGITLINK(conflict->their_entry.mode))
|
842
|
-
return
|
819
|
+
return false;
|
843
820
|
|
844
821
|
/* Reject link/file conflicts. */
|
845
|
-
if ((S_ISLNK(conflict->ancestor_entry.mode) ^
|
846
|
-
|
847
|
-
|
822
|
+
if ((S_ISLNK(conflict->ancestor_entry.mode) ^
|
823
|
+
S_ISLNK(conflict->our_entry.mode)) ||
|
824
|
+
(S_ISLNK(conflict->ancestor_entry.mode) ^
|
825
|
+
S_ISLNK(conflict->their_entry.mode)))
|
826
|
+
return false;
|
848
827
|
|
849
828
|
/* Reject name conflicts */
|
850
829
|
if (conflict->type == GIT_MERGE_DIFF_BOTH_RENAMED_2_TO_1 ||
|
851
830
|
conflict->type == GIT_MERGE_DIFF_RENAMED_ADDED)
|
852
|
-
return
|
831
|
+
return false;
|
853
832
|
|
854
833
|
if ((conflict->our_status & GIT_DELTA_RENAMED) == GIT_DELTA_RENAMED &&
|
855
834
|
(conflict->their_status & GIT_DELTA_RENAMED) == GIT_DELTA_RENAMED &&
|
856
835
|
strcmp(conflict->ancestor_entry.path, conflict->their_entry.path) != 0)
|
836
|
+
return false;
|
837
|
+
|
838
|
+
return true;
|
839
|
+
}
|
840
|
+
|
841
|
+
static int merge_conflict_invoke_driver(
|
842
|
+
git_index_entry **out,
|
843
|
+
const char *name,
|
844
|
+
git_merge_driver *driver,
|
845
|
+
git_merge_diff_list *diff_list,
|
846
|
+
git_merge_driver_source *src)
|
847
|
+
{
|
848
|
+
git_index_entry *result;
|
849
|
+
git_buf buf = GIT_BUF_INIT;
|
850
|
+
const char *path;
|
851
|
+
uint32_t mode;
|
852
|
+
git_odb *odb = NULL;
|
853
|
+
git_oid oid;
|
854
|
+
int error;
|
855
|
+
|
856
|
+
*out = NULL;
|
857
|
+
|
858
|
+
if ((error = driver->apply(driver, &path, &mode, &buf, name, src)) < 0 ||
|
859
|
+
(error = git_repository_odb(&odb, src->repo)) < 0 ||
|
860
|
+
(error = git_odb_write(&oid, odb, buf.ptr, buf.size, GIT_OBJ_BLOB)) < 0)
|
861
|
+
goto done;
|
862
|
+
|
863
|
+
result = git_pool_mallocz(&diff_list->pool, sizeof(git_index_entry));
|
864
|
+
GITERR_CHECK_ALLOC(result);
|
865
|
+
|
866
|
+
git_oid_cpy(&result->id, &oid);
|
867
|
+
result->mode = mode;
|
868
|
+
result->file_size = buf.size;
|
869
|
+
|
870
|
+
result->path = git_pool_strdup(&diff_list->pool, path);
|
871
|
+
GITERR_CHECK_ALLOC(result->path);
|
872
|
+
|
873
|
+
*out = result;
|
874
|
+
|
875
|
+
done:
|
876
|
+
git_buf_free(&buf);
|
877
|
+
git_odb_free(odb);
|
878
|
+
|
879
|
+
return error;
|
880
|
+
}
|
881
|
+
|
882
|
+
static int merge_conflict_resolve_contents(
|
883
|
+
int *resolved,
|
884
|
+
git_merge_diff_list *diff_list,
|
885
|
+
const git_merge_diff *conflict,
|
886
|
+
const git_merge_options *merge_opts,
|
887
|
+
const git_merge_file_options *file_opts)
|
888
|
+
{
|
889
|
+
git_merge_driver_source source = {0};
|
890
|
+
git_merge_file_result result = {0};
|
891
|
+
git_merge_driver *driver;
|
892
|
+
git_merge_driver__builtin builtin = {{0}};
|
893
|
+
git_index_entry *merge_result;
|
894
|
+
git_odb *odb = NULL;
|
895
|
+
const char *name;
|
896
|
+
bool fallback = false;
|
897
|
+
int error;
|
898
|
+
|
899
|
+
assert(resolved && diff_list && conflict);
|
900
|
+
|
901
|
+
*resolved = 0;
|
902
|
+
|
903
|
+
if (!merge_conflict_can_resolve_contents(conflict))
|
857
904
|
return 0;
|
858
905
|
|
859
|
-
|
906
|
+
source.repo = diff_list->repo;
|
907
|
+
source.default_driver = merge_opts->default_driver;
|
908
|
+
source.file_opts = file_opts;
|
909
|
+
source.ancestor = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
|
860
910
|
&conflict->ancestor_entry : NULL;
|
861
|
-
ours = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
|
911
|
+
source.ours = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->our_entry) ?
|
862
912
|
&conflict->our_entry : NULL;
|
863
|
-
theirs = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
|
913
|
+
source.theirs = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->their_entry) ?
|
864
914
|
&conflict->their_entry : NULL;
|
865
915
|
|
866
|
-
if (
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
916
|
+
if (file_opts->favor != GIT_MERGE_FILE_FAVOR_NORMAL) {
|
917
|
+
/* if the user requested a particular type of resolution (via the
|
918
|
+
* favor flag) then let that override the gitattributes and use
|
919
|
+
* the builtin driver.
|
920
|
+
*/
|
921
|
+
name = "text";
|
922
|
+
builtin.base.apply = git_merge_driver__builtin_apply;
|
923
|
+
builtin.favor = file_opts->favor;
|
924
|
+
|
925
|
+
driver = &builtin.base;
|
926
|
+
} else {
|
927
|
+
/* find the merge driver for this file */
|
928
|
+
if ((error = git_merge_driver_for_source(&name, &driver, &source)) < 0)
|
929
|
+
goto done;
|
930
|
+
|
931
|
+
if (driver == NULL)
|
932
|
+
fallback = true;
|
933
|
+
}
|
871
934
|
|
872
|
-
if (
|
873
|
-
|
935
|
+
if (driver) {
|
936
|
+
error = merge_conflict_invoke_driver(&merge_result, name, driver,
|
937
|
+
diff_list, &source);
|
874
938
|
|
875
|
-
|
876
|
-
|
939
|
+
if (error == GIT_PASSTHROUGH)
|
940
|
+
fallback = true;
|
941
|
+
}
|
877
942
|
|
878
|
-
|
879
|
-
|
880
|
-
|
943
|
+
if (fallback) {
|
944
|
+
error = merge_conflict_invoke_driver(&merge_result, "text",
|
945
|
+
&git_merge_driver__text.base, diff_list, &source);
|
946
|
+
}
|
881
947
|
|
882
|
-
|
948
|
+
if (error < 0) {
|
949
|
+
if (error == GIT_EMERGECONFLICT)
|
950
|
+
error = 0;
|
951
|
+
|
952
|
+
goto done;
|
953
|
+
}
|
954
|
+
|
955
|
+
git_vector_insert(&diff_list->staged, merge_result);
|
883
956
|
git_vector_insert(&diff_list->resolved, (git_merge_diff *)conflict);
|
884
957
|
|
885
958
|
*resolved = 1;
|
@@ -895,6 +968,7 @@ static int merge_conflict_resolve(
|
|
895
968
|
int *out,
|
896
969
|
git_merge_diff_list *diff_list,
|
897
970
|
const git_merge_diff *conflict,
|
971
|
+
const git_merge_options *merge_opts,
|
898
972
|
const git_merge_file_options *file_opts)
|
899
973
|
{
|
900
974
|
int resolved = 0;
|
@@ -902,16 +976,20 @@ static int merge_conflict_resolve(
|
|
902
976
|
|
903
977
|
*out = 0;
|
904
978
|
|
905
|
-
if ((error = merge_conflict_resolve_trivial(
|
979
|
+
if ((error = merge_conflict_resolve_trivial(
|
980
|
+
&resolved, diff_list, conflict)) < 0)
|
906
981
|
goto done;
|
907
982
|
|
908
|
-
if (!resolved && (error = merge_conflict_resolve_one_removed(
|
983
|
+
if (!resolved && (error = merge_conflict_resolve_one_removed(
|
984
|
+
&resolved, diff_list, conflict)) < 0)
|
909
985
|
goto done;
|
910
986
|
|
911
|
-
if (!resolved && (error = merge_conflict_resolve_one_renamed(
|
987
|
+
if (!resolved && (error = merge_conflict_resolve_one_renamed(
|
988
|
+
&resolved, diff_list, conflict)) < 0)
|
912
989
|
goto done;
|
913
990
|
|
914
|
-
if (!resolved && (error =
|
991
|
+
if (!resolved && (error = merge_conflict_resolve_contents(
|
992
|
+
&resolved, diff_list, conflict, merge_opts, file_opts)) < 0)
|
915
993
|
goto done;
|
916
994
|
|
917
995
|
*out = resolved;
|
@@ -1627,6 +1705,7 @@ static int merge_normalize_opts(
|
|
1627
1705
|
const git_merge_options *given)
|
1628
1706
|
{
|
1629
1707
|
git_config *cfg = NULL;
|
1708
|
+
git_config_entry *entry = NULL;
|
1630
1709
|
int error = 0;
|
1631
1710
|
|
1632
1711
|
assert(repo && opts);
|
@@ -1644,6 +1723,22 @@ static int merge_normalize_opts(
|
|
1644
1723
|
opts->rename_threshold = GIT_MERGE_DEFAULT_RENAME_THRESHOLD;
|
1645
1724
|
}
|
1646
1725
|
|
1726
|
+
if (given && given->default_driver) {
|
1727
|
+
opts->default_driver = git__strdup(given->default_driver);
|
1728
|
+
GITERR_CHECK_ALLOC(opts->default_driver);
|
1729
|
+
} else {
|
1730
|
+
error = git_config_get_entry(&entry, cfg, "merge.default");
|
1731
|
+
|
1732
|
+
if (error == 0) {
|
1733
|
+
opts->default_driver = git__strdup(entry->value);
|
1734
|
+
GITERR_CHECK_ALLOC(opts->default_driver);
|
1735
|
+
} else if (error == GIT_ENOTFOUND) {
|
1736
|
+
error = 0;
|
1737
|
+
} else {
|
1738
|
+
goto done;
|
1739
|
+
}
|
1740
|
+
}
|
1741
|
+
|
1647
1742
|
if (!opts->target_limit) {
|
1648
1743
|
int limit = git_config__get_int_force(cfg, "merge.renamelimit", 0);
|
1649
1744
|
|
@@ -1666,7 +1761,9 @@ static int merge_normalize_opts(
|
|
1666
1761
|
opts->metric->payload = (void *)GIT_HASHSIG_SMART_WHITESPACE;
|
1667
1762
|
}
|
1668
1763
|
|
1669
|
-
|
1764
|
+
done:
|
1765
|
+
git_config_entry_free(entry);
|
1766
|
+
return error;
|
1670
1767
|
}
|
1671
1768
|
|
1672
1769
|
|
@@ -1878,7 +1975,7 @@ int git_merge__iterators(
|
|
1878
1975
|
int resolved = 0;
|
1879
1976
|
|
1880
1977
|
if ((error = merge_conflict_resolve(
|
1881
|
-
&resolved, diff_list, conflict, &file_opts)) < 0)
|
1978
|
+
&resolved, diff_list, conflict, &opts, &file_opts)) < 0)
|
1882
1979
|
goto done;
|
1883
1980
|
|
1884
1981
|
if (!resolved) {
|
@@ -1899,6 +1996,8 @@ done:
|
|
1899
1996
|
if (!given_opts || !given_opts->metric)
|
1900
1997
|
git__free(opts.metric);
|
1901
1998
|
|
1999
|
+
git__free((char *)opts.default_driver);
|
2000
|
+
|
1902
2001
|
git_merge_diff_list__free(diff_list);
|
1903
2002
|
git_iterator_free(empty_ancestor);
|
1904
2003
|
git_iterator_free(empty_ours);
|
@@ -2111,14 +2210,14 @@ static int merge_annotated_commits(
|
|
2111
2210
|
git_iterator *base_iter = NULL, *our_iter = NULL, *their_iter = NULL;
|
2112
2211
|
int error;
|
2113
2212
|
|
2114
|
-
|
2213
|
+
if ((error = compute_base(&base, repo, ours, theirs, opts,
|
2115
2214
|
recursion_level)) < 0) {
|
2116
2215
|
|
2117
|
-
|
2118
|
-
|
2216
|
+
if (error != GIT_ENOTFOUND)
|
2217
|
+
goto done;
|
2119
2218
|
|
2120
|
-
|
2121
|
-
|
2219
|
+
giterr_clear();
|
2220
|
+
}
|
2122
2221
|
|
2123
2222
|
if ((error = iterator_for_annotated_commit(&base_iter, base)) < 0 ||
|
2124
2223
|
(error = iterator_for_annotated_commit(&our_iter, ours)) < 0 ||
|
data/vendor/libgit2/src/merge.h
CHANGED
@@ -12,8 +12,9 @@
|
|
12
12
|
#include "pool.h"
|
13
13
|
#include "iterator.h"
|
14
14
|
|
15
|
-
#include "git2/merge.h"
|
16
15
|
#include "git2/types.h"
|
16
|
+
#include "git2/merge.h"
|
17
|
+
#include "git2/sys/merge.h"
|
17
18
|
|
18
19
|
#define GIT_MERGE_MSG_FILE "MERGE_MSG"
|
19
20
|
#define GIT_MERGE_MODE_FILE "MERGE_MODE"
|
@@ -22,6 +23,19 @@
|
|
22
23
|
#define GIT_MERGE_DEFAULT_RENAME_THRESHOLD 50
|
23
24
|
#define GIT_MERGE_DEFAULT_TARGET_LIMIT 1000
|
24
25
|
|
26
|
+
|
27
|
+
/** Internal merge flags. */
|
28
|
+
enum {
|
29
|
+
/** The merge is for a virtual base in a recursive merge. */
|
30
|
+
GIT_MERGE__VIRTUAL_BASE = (1 << 31),
|
31
|
+
};
|
32
|
+
|
33
|
+
enum {
|
34
|
+
/** Accept the conflict file, staging it as the merge result. */
|
35
|
+
GIT_MERGE_FILE_FAVOR__CONFLICTED = 4,
|
36
|
+
};
|
37
|
+
|
38
|
+
|
25
39
|
/** Types of changes when files are merged from branch to branch. */
|
26
40
|
typedef enum {
|
27
41
|
/* No conflict - a change only occurs in one branch. */
|
@@ -70,7 +84,6 @@ typedef enum {
|
|
70
84
|
GIT_MERGE_DIFF_DF_CHILD = (1 << 11),
|
71
85
|
} git_merge_diff_type_t;
|
72
86
|
|
73
|
-
|
74
87
|
typedef struct {
|
75
88
|
git_repository *repo;
|
76
89
|
git_pool pool;
|
@@ -152,4 +165,50 @@ int git_merge__check_result(git_repository *repo, git_index *index_new);
|
|
152
165
|
|
153
166
|
int git_merge__append_conflicts_to_merge_msg(git_repository *repo, git_index *index);
|
154
167
|
|
168
|
+
/* Merge files */
|
169
|
+
|
170
|
+
GIT_INLINE(const char *) git_merge_file__best_path(
|
171
|
+
const char *ancestor,
|
172
|
+
const char *ours,
|
173
|
+
const char *theirs)
|
174
|
+
{
|
175
|
+
if (!ancestor) {
|
176
|
+
if (ours && theirs && strcmp(ours, theirs) == 0)
|
177
|
+
return ours;
|
178
|
+
|
179
|
+
return NULL;
|
180
|
+
}
|
181
|
+
|
182
|
+
if (ours && strcmp(ancestor, ours) == 0)
|
183
|
+
return theirs;
|
184
|
+
else if(theirs && strcmp(ancestor, theirs) == 0)
|
185
|
+
return ours;
|
186
|
+
|
187
|
+
return NULL;
|
188
|
+
}
|
189
|
+
|
190
|
+
GIT_INLINE(uint32_t) git_merge_file__best_mode(
|
191
|
+
uint32_t ancestor, uint32_t ours, uint32_t theirs)
|
192
|
+
{
|
193
|
+
/*
|
194
|
+
* If ancestor didn't exist and either ours or theirs is executable,
|
195
|
+
* assume executable. Otherwise, if any mode changed from the ancestor,
|
196
|
+
* use that one.
|
197
|
+
*/
|
198
|
+
if (!ancestor) {
|
199
|
+
if (ours == GIT_FILEMODE_BLOB_EXECUTABLE ||
|
200
|
+
theirs == GIT_FILEMODE_BLOB_EXECUTABLE)
|
201
|
+
return GIT_FILEMODE_BLOB_EXECUTABLE;
|
202
|
+
|
203
|
+
return GIT_FILEMODE_BLOB;
|
204
|
+
} else if (ours && theirs) {
|
205
|
+
if (ancestor == ours)
|
206
|
+
return theirs;
|
207
|
+
|
208
|
+
return ours;
|
209
|
+
}
|
210
|
+
|
211
|
+
return 0;
|
212
|
+
}
|
213
|
+
|
155
214
|
#endif
|