rugged 0.25.0b2 → 0.25.0b3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/ext/rugged/extconf.rb +3 -1
  4. data/ext/rugged/rugged.c +1 -1
  5. data/ext/rugged/rugged.h +1 -1
  6. data/ext/rugged/rugged_blob.c +29 -38
  7. data/ext/rugged/rugged_commit.c +215 -78
  8. data/ext/rugged/rugged_rebase.c +18 -11
  9. data/ext/rugged/rugged_remote.c +2 -2
  10. data/ext/rugged/rugged_tree.c +132 -0
  11. data/lib/rugged/version.rb +1 -1
  12. data/vendor/libgit2/CMakeLists.txt +11 -3
  13. data/vendor/libgit2/include/git2.h +1 -0
  14. data/vendor/libgit2/include/git2/blob.h +39 -28
  15. data/vendor/libgit2/include/git2/commit.h +30 -0
  16. data/vendor/libgit2/include/git2/common.h +16 -1
  17. data/vendor/libgit2/include/git2/merge.h +10 -1
  18. data/vendor/libgit2/include/git2/proxy.h +92 -0
  19. data/vendor/libgit2/include/git2/refs.h +11 -0
  20. data/vendor/libgit2/include/git2/remote.h +17 -4
  21. data/vendor/libgit2/include/git2/signature.h +13 -0
  22. data/vendor/libgit2/include/git2/sys/merge.h +177 -0
  23. data/vendor/libgit2/include/git2/sys/remote.h +16 -0
  24. data/vendor/libgit2/include/git2/sys/stream.h +2 -1
  25. data/vendor/libgit2/include/git2/sys/transport.h +3 -1
  26. data/vendor/libgit2/include/git2/tag.h +9 -0
  27. data/vendor/libgit2/include/git2/tree.h +55 -0
  28. data/vendor/libgit2/src/annotated_commit.c +99 -80
  29. data/vendor/libgit2/src/annotated_commit.h +5 -2
  30. data/vendor/libgit2/src/array.h +40 -0
  31. data/vendor/libgit2/src/blame.c +8 -3
  32. data/vendor/libgit2/src/blame_git.c +2 -1
  33. data/vendor/libgit2/src/blob.c +71 -39
  34. data/vendor/libgit2/src/branch.c +2 -1
  35. data/vendor/libgit2/src/checkout.c +66 -42
  36. data/vendor/libgit2/src/commit.c +67 -3
  37. data/vendor/libgit2/src/config_cache.c +2 -1
  38. data/vendor/libgit2/src/config_file.c +32 -27
  39. data/vendor/libgit2/src/curl_stream.c +89 -6
  40. data/vendor/libgit2/src/delta-apply.c +36 -5
  41. data/vendor/libgit2/src/delta-apply.h +12 -0
  42. data/vendor/libgit2/src/describe.c +3 -2
  43. data/vendor/libgit2/src/diff.c +13 -20
  44. data/vendor/libgit2/src/diff_tform.c +5 -3
  45. data/vendor/libgit2/src/filebuf.c +12 -2
  46. data/vendor/libgit2/src/filebuf.h +1 -0
  47. data/vendor/libgit2/src/fnmatch.c +18 -5
  48. data/vendor/libgit2/src/global.c +18 -0
  49. data/vendor/libgit2/src/global.h +1 -0
  50. data/vendor/libgit2/src/ignore.c +11 -3
  51. data/vendor/libgit2/src/index.c +11 -5
  52. data/vendor/libgit2/src/indexer.c +11 -7
  53. data/vendor/libgit2/src/iterator.c +1575 -1468
  54. data/vendor/libgit2/src/iterator.h +52 -69
  55. data/vendor/libgit2/src/merge.c +160 -63
  56. data/vendor/libgit2/src/merge.h +61 -2
  57. data/vendor/libgit2/src/merge_driver.c +397 -0
  58. data/vendor/libgit2/src/merge_driver.h +60 -0
  59. data/vendor/libgit2/src/merge_file.c +11 -49
  60. data/vendor/libgit2/src/netops.c +12 -10
  61. data/vendor/libgit2/src/object.c +3 -6
  62. data/vendor/libgit2/src/object_api.c +19 -1
  63. data/vendor/libgit2/src/odb_loose.c +1 -1
  64. data/vendor/libgit2/src/openssl_stream.c +16 -3
  65. data/vendor/libgit2/src/pack-objects.c +3 -1
  66. data/vendor/libgit2/src/pack.c +5 -9
  67. data/vendor/libgit2/src/path.c +14 -0
  68. data/vendor/libgit2/src/path.h +12 -0
  69. data/vendor/libgit2/src/pathspec.c +1 -1
  70. data/vendor/libgit2/src/posix.c +7 -0
  71. data/vendor/libgit2/src/posix.h +1 -0
  72. data/vendor/libgit2/src/proxy.c +32 -0
  73. data/vendor/libgit2/src/proxy.h +14 -0
  74. data/vendor/libgit2/src/push.c +7 -7
  75. data/vendor/libgit2/src/rebase.c +61 -31
  76. data/vendor/libgit2/src/refdb_fs.c +1 -0
  77. data/vendor/libgit2/src/refs.c +16 -1
  78. data/vendor/libgit2/src/remote.c +20 -6
  79. data/vendor/libgit2/src/repository.c +1 -1
  80. data/vendor/libgit2/src/reset.c +1 -1
  81. data/vendor/libgit2/src/settings.c +23 -1
  82. data/vendor/libgit2/src/signature.c +26 -1
  83. data/vendor/libgit2/src/stransport_stream.c +5 -2
  84. data/vendor/libgit2/src/stream.h +2 -2
  85. data/vendor/libgit2/src/submodule.c +3 -2
  86. data/vendor/libgit2/src/tag.c +8 -2
  87. data/vendor/libgit2/src/transports/http.c +32 -9
  88. data/vendor/libgit2/src/transports/local.c +4 -1
  89. data/vendor/libgit2/src/transports/smart.c +6 -0
  90. data/vendor/libgit2/src/transports/smart.h +1 -0
  91. data/vendor/libgit2/src/transports/smart_protocol.c +61 -17
  92. data/vendor/libgit2/src/transports/winhttp.c +130 -11
  93. data/vendor/libgit2/src/tree.c +329 -98
  94. data/vendor/libgit2/src/tree.h +4 -5
  95. data/vendor/libgit2/src/unix/map.c +5 -0
  96. data/vendor/libgit2/src/win32/map.c +24 -5
  97. data/vendor/libgit2/src/xdiff/xprepare.c +2 -1
  98. metadata +10 -4
  99. data/vendor/libgit2/Makefile.embed +0 -60
@@ -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
@@ -0,0 +1,397 @@
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
+ #include "common.h"
9
+ #include "vector.h"
10
+ #include "global.h"
11
+ #include "merge.h"
12
+ #include "merge_driver.h"
13
+ #include "git2/merge.h"
14
+ #include "git2/sys/merge.h"
15
+
16
+ static const char *merge_driver_name__text = "text";
17
+ static const char *merge_driver_name__union = "union";
18
+ static const char *merge_driver_name__binary = "binary";
19
+
20
+ struct merge_driver_registry {
21
+ git_rwlock lock;
22
+ git_vector drivers;
23
+ };
24
+
25
+ typedef struct {
26
+ git_merge_driver *driver;
27
+ int initialized;
28
+ char name[GIT_FLEX_ARRAY];
29
+ } git_merge_driver_entry;
30
+
31
+ static struct merge_driver_registry merge_driver_registry;
32
+
33
+ static void git_merge_driver_global_shutdown(void);
34
+
35
+
36
+ int git_merge_driver__builtin_apply(
37
+ git_merge_driver *self,
38
+ const char **path_out,
39
+ uint32_t *mode_out,
40
+ git_buf *merged_out,
41
+ const char *filter_name,
42
+ const git_merge_driver_source *src)
43
+ {
44
+ git_merge_driver__builtin *driver = (git_merge_driver__builtin *)self;
45
+ git_merge_file_options file_opts = GIT_MERGE_FILE_OPTIONS_INIT;
46
+ git_merge_file_result result = {0};
47
+ int error;
48
+
49
+ GIT_UNUSED(filter_name);
50
+
51
+ if (src->file_opts)
52
+ memcpy(&file_opts, src->file_opts, sizeof(git_merge_file_options));
53
+
54
+ if (driver->favor)
55
+ file_opts.favor = driver->favor;
56
+
57
+ if ((error = git_merge_file_from_index(&result, src->repo,
58
+ src->ancestor, src->ours, src->theirs, &file_opts)) < 0)
59
+ goto done;
60
+
61
+ if (!result.automergeable &&
62
+ !(file_opts.flags & GIT_MERGE_FILE_FAVOR__CONFLICTED)) {
63
+ error = GIT_EMERGECONFLICT;
64
+ goto done;
65
+ }
66
+
67
+ *path_out = git_merge_file__best_path(
68
+ src->ancestor ? src->ancestor->path : NULL,
69
+ src->ours ? src->ours->path : NULL,
70
+ src->theirs ? src->theirs->path : NULL);
71
+
72
+ *mode_out = git_merge_file__best_mode(
73
+ src->ancestor ? src->ancestor->mode : 0,
74
+ src->ours ? src->ours->mode : 0,
75
+ src->theirs ? src->theirs->mode : 0);
76
+
77
+ merged_out->ptr = (char *)result.ptr;
78
+ merged_out->size = result.len;
79
+ merged_out->asize = result.len;
80
+ result.ptr = NULL;
81
+
82
+ done:
83
+ git_merge_file_result_free(&result);
84
+ return error;
85
+ }
86
+
87
+ static int merge_driver_binary_apply(
88
+ git_merge_driver *self,
89
+ const char **path_out,
90
+ uint32_t *mode_out,
91
+ git_buf *merged_out,
92
+ const char *filter_name,
93
+ const git_merge_driver_source *src)
94
+ {
95
+ GIT_UNUSED(self);
96
+ GIT_UNUSED(path_out);
97
+ GIT_UNUSED(mode_out);
98
+ GIT_UNUSED(merged_out);
99
+ GIT_UNUSED(filter_name);
100
+ GIT_UNUSED(src);
101
+
102
+ return GIT_EMERGECONFLICT;
103
+ }
104
+
105
+ static int merge_driver_entry_cmp(const void *a, const void *b)
106
+ {
107
+ const git_merge_driver_entry *entry_a = a;
108
+ const git_merge_driver_entry *entry_b = b;
109
+
110
+ return strcmp(entry_a->name, entry_b->name);
111
+ }
112
+
113
+ static int merge_driver_entry_search(const void *a, const void *b)
114
+ {
115
+ const char *name_a = a;
116
+ const git_merge_driver_entry *entry_b = b;
117
+
118
+ return strcmp(name_a, entry_b->name);
119
+ }
120
+
121
+ git_merge_driver__builtin git_merge_driver__text = {
122
+ {
123
+ GIT_MERGE_DRIVER_VERSION,
124
+ NULL,
125
+ NULL,
126
+ git_merge_driver__builtin_apply,
127
+ },
128
+ GIT_MERGE_FILE_FAVOR_NORMAL
129
+ };
130
+
131
+ git_merge_driver__builtin git_merge_driver__union = {
132
+ {
133
+ GIT_MERGE_DRIVER_VERSION,
134
+ NULL,
135
+ NULL,
136
+ git_merge_driver__builtin_apply,
137
+ },
138
+ GIT_MERGE_FILE_FAVOR_UNION
139
+ };
140
+
141
+ git_merge_driver git_merge_driver__binary = {
142
+ GIT_MERGE_DRIVER_VERSION,
143
+ NULL,
144
+ NULL,
145
+ merge_driver_binary_apply
146
+ };
147
+
148
+ /* Note: callers must lock the registry before calling this function */
149
+ static int merge_driver_registry_insert(
150
+ const char *name, git_merge_driver *driver)
151
+ {
152
+ git_merge_driver_entry *entry;
153
+
154
+ entry = git__calloc(1, sizeof(git_merge_driver_entry) + strlen(name) + 1);
155
+ GITERR_CHECK_ALLOC(entry);
156
+
157
+ strcpy(entry->name, name);
158
+ entry->driver = driver;
159
+
160
+ return git_vector_insert_sorted(
161
+ &merge_driver_registry.drivers, entry, NULL);
162
+ }
163
+
164
+ int git_merge_driver_global_init(void)
165
+ {
166
+ int error;
167
+
168
+ if (git_rwlock_init(&merge_driver_registry.lock) < 0)
169
+ return -1;
170
+
171
+ if ((error = git_vector_init(&merge_driver_registry.drivers, 3,
172
+ merge_driver_entry_cmp)) < 0)
173
+ goto done;
174
+
175
+ if ((error = merge_driver_registry_insert(
176
+ merge_driver_name__text, &git_merge_driver__text.base)) < 0 ||
177
+ (error = merge_driver_registry_insert(
178
+ merge_driver_name__union, &git_merge_driver__union.base)) < 0 ||
179
+ (error = merge_driver_registry_insert(
180
+ merge_driver_name__binary, &git_merge_driver__binary)) < 0)
181
+ goto done;
182
+
183
+ git__on_shutdown(git_merge_driver_global_shutdown);
184
+
185
+ done:
186
+ if (error < 0)
187
+ git_vector_free_deep(&merge_driver_registry.drivers);
188
+
189
+ return error;
190
+ }
191
+
192
+ static void git_merge_driver_global_shutdown(void)
193
+ {
194
+ git_merge_driver_entry *entry;
195
+ size_t i;
196
+
197
+ if (git_rwlock_wrlock(&merge_driver_registry.lock) < 0)
198
+ return;
199
+
200
+ git_vector_foreach(&merge_driver_registry.drivers, i, entry) {
201
+ if (entry->driver->shutdown)
202
+ entry->driver->shutdown(entry->driver);
203
+
204
+ git__free(entry);
205
+ }
206
+
207
+ git_vector_free(&merge_driver_registry.drivers);
208
+
209
+ git_rwlock_wrunlock(&merge_driver_registry.lock);
210
+ git_rwlock_free(&merge_driver_registry.lock);
211
+ }
212
+
213
+ /* Note: callers must lock the registry before calling this function */
214
+ static int merge_driver_registry_find(size_t *pos, const char *name)
215
+ {
216
+ return git_vector_search2(pos, &merge_driver_registry.drivers,
217
+ merge_driver_entry_search, name);
218
+ }
219
+
220
+ /* Note: callers must lock the registry before calling this function */
221
+ static git_merge_driver_entry *merge_driver_registry_lookup(
222
+ size_t *pos, const char *name)
223
+ {
224
+ git_merge_driver_entry *entry = NULL;
225
+
226
+ if (!merge_driver_registry_find(pos, name))
227
+ entry = git_vector_get(&merge_driver_registry.drivers, *pos);
228
+
229
+ return entry;
230
+ }
231
+
232
+ int git_merge_driver_register(const char *name, git_merge_driver *driver)
233
+ {
234
+ int error;
235
+
236
+ assert(name && driver);
237
+
238
+ if (git_rwlock_wrlock(&merge_driver_registry.lock) < 0) {
239
+ giterr_set(GITERR_OS, "failed to lock merge driver registry");
240
+ return -1;
241
+ }
242
+
243
+ if (!merge_driver_registry_find(NULL, name)) {
244
+ giterr_set(GITERR_MERGE, "attempt to reregister existing driver '%s'",
245
+ name);
246
+ error = GIT_EEXISTS;
247
+ goto done;
248
+ }
249
+
250
+ error = merge_driver_registry_insert(name, driver);
251
+
252
+ done:
253
+ git_rwlock_wrunlock(&merge_driver_registry.lock);
254
+ return error;
255
+ }
256
+
257
+ int git_merge_driver_unregister(const char *name)
258
+ {
259
+ git_merge_driver_entry *entry;
260
+ size_t pos;
261
+ int error = 0;
262
+
263
+ if (git_rwlock_wrlock(&merge_driver_registry.lock) < 0) {
264
+ giterr_set(GITERR_OS, "failed to lock merge driver registry");
265
+ return -1;
266
+ }
267
+
268
+ if ((entry = merge_driver_registry_lookup(&pos, name)) == NULL) {
269
+ giterr_set(GITERR_MERGE, "cannot find merge driver '%s' to unregister",
270
+ name);
271
+ error = GIT_ENOTFOUND;
272
+ goto done;
273
+ }
274
+
275
+ git_vector_remove(&merge_driver_registry.drivers, pos);
276
+
277
+ if (entry->initialized && entry->driver->shutdown) {
278
+ entry->driver->shutdown(entry->driver);
279
+ entry->initialized = false;
280
+ }
281
+
282
+ git__free(entry);
283
+
284
+ done:
285
+ git_rwlock_wrunlock(&merge_driver_registry.lock);
286
+ return error;
287
+ }
288
+
289
+ git_merge_driver *git_merge_driver_lookup(const char *name)
290
+ {
291
+ git_merge_driver_entry *entry;
292
+ size_t pos;
293
+ int error;
294
+
295
+ /* If we've decided the merge driver to use internally - and not
296
+ * based on user configuration (in merge_driver_name_for_path)
297
+ * then we can use a hardcoded name to compare instead of bothering
298
+ * to take a lock and look it up in the vector.
299
+ */
300
+ if (name == merge_driver_name__text)
301
+ return &git_merge_driver__text.base;
302
+ else if (name == merge_driver_name__binary)
303
+ return &git_merge_driver__binary;
304
+
305
+ if (git_rwlock_rdlock(&merge_driver_registry.lock) < 0) {
306
+ giterr_set(GITERR_OS, "failed to lock merge driver registry");
307
+ return NULL;
308
+ }
309
+
310
+ entry = merge_driver_registry_lookup(&pos, name);
311
+
312
+ git_rwlock_rdunlock(&merge_driver_registry.lock);
313
+
314
+ if (entry == NULL) {
315
+ giterr_set(GITERR_MERGE, "cannot use an unregistered filter");
316
+ return NULL;
317
+ }
318
+
319
+ if (!entry->initialized) {
320
+ if (entry->driver->initialize &&
321
+ (error = entry->driver->initialize(entry->driver)) < 0)
322
+ return NULL;
323
+
324
+ entry->initialized = 1;
325
+ }
326
+
327
+ return entry->driver;
328
+ }
329
+
330
+ static int merge_driver_name_for_path(
331
+ const char **out,
332
+ git_repository *repo,
333
+ const char *path,
334
+ const char *default_driver)
335
+ {
336
+ const char *value;
337
+ int error;
338
+
339
+ *out = NULL;
340
+
341
+ if ((error = git_attr_get(&value, repo, 0, path, "merge")) < 0)
342
+ return error;
343
+
344
+ /* set: use the built-in 3-way merge driver ("text") */
345
+ if (GIT_ATTR_TRUE(value))
346
+ *out = merge_driver_name__text;
347
+
348
+ /* unset: do not merge ("binary") */
349
+ else if (GIT_ATTR_FALSE(value))
350
+ *out = merge_driver_name__binary;
351
+
352
+ else if (GIT_ATTR_UNSPECIFIED(value) && default_driver)
353
+ *out = default_driver;
354
+
355
+ else if (GIT_ATTR_UNSPECIFIED(value))
356
+ *out = merge_driver_name__text;
357
+
358
+ else
359
+ *out = value;
360
+
361
+ return 0;
362
+ }
363
+
364
+
365
+ GIT_INLINE(git_merge_driver *) merge_driver_lookup_with_wildcard(
366
+ const char *name)
367
+ {
368
+ git_merge_driver *driver = git_merge_driver_lookup(name);
369
+
370
+ if (driver == NULL)
371
+ driver = git_merge_driver_lookup("*");
372
+
373
+ return driver;
374
+ }
375
+
376
+ int git_merge_driver_for_source(
377
+ const char **name_out,
378
+ git_merge_driver **driver_out,
379
+ const git_merge_driver_source *src)
380
+ {
381
+ const char *path, *driver_name;
382
+ int error = 0;
383
+
384
+ path = git_merge_file__best_path(
385
+ src->ancestor ? src->ancestor->path : NULL,
386
+ src->ours ? src->ours->path : NULL,
387
+ src->theirs ? src->theirs->path : NULL);
388
+
389
+ if ((error = merge_driver_name_for_path(
390
+ &driver_name, src->repo, path, src->default_driver)) < 0)
391
+ return error;
392
+
393
+ *name_out = driver_name;
394
+ *driver_out = merge_driver_lookup_with_wildcard(driver_name);
395
+ return error;
396
+ }
397
+