rugged 0.22.2 → 0.23.0b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged.c +1 -2
  3. data/ext/rugged/rugged_branch_collection.c +6 -44
  4. data/ext/rugged/rugged_config.c +7 -3
  5. data/ext/rugged/rugged_diff_delta.c +1 -1
  6. data/ext/rugged/rugged_diff_line.c +1 -1
  7. data/ext/rugged/rugged_object.c +2 -2
  8. data/ext/rugged/rugged_reference_collection.c +12 -56
  9. data/ext/rugged/rugged_remote.c +4 -33
  10. data/ext/rugged/rugged_remote_collection.c +1 -1
  11. data/ext/rugged/rugged_repo.c +10 -36
  12. data/ext/rugged/rugged_settings.c +3 -3
  13. data/ext/rugged/rugged_tree.c +1 -1
  14. data/lib/rugged/version.rb +1 -1
  15. data/vendor/libgit2/CMakeLists.txt +10 -3
  16. data/vendor/libgit2/COPYING +15 -21
  17. data/vendor/libgit2/include/git2/annotated_commit.h +20 -3
  18. data/vendor/libgit2/include/git2/branch.h +20 -16
  19. data/vendor/libgit2/include/git2/checkout.h +32 -18
  20. data/vendor/libgit2/include/git2/cherrypick.h +2 -2
  21. data/vendor/libgit2/include/git2/clone.h +4 -10
  22. data/vendor/libgit2/include/git2/config.h +66 -12
  23. data/vendor/libgit2/include/git2/describe.h +3 -2
  24. data/vendor/libgit2/include/git2/diff.h +3 -3
  25. data/vendor/libgit2/include/git2/errors.h +1 -0
  26. data/vendor/libgit2/include/git2/filter.h +21 -5
  27. data/vendor/libgit2/include/git2/index.h +32 -0
  28. data/vendor/libgit2/include/git2/merge.h +20 -3
  29. data/vendor/libgit2/include/git2/oid.h +1 -1
  30. data/vendor/libgit2/include/git2/pack.h +13 -0
  31. data/vendor/libgit2/include/git2/patch.h +3 -6
  32. data/vendor/libgit2/include/git2/rebase.h +8 -12
  33. data/vendor/libgit2/include/git2/refs.h +19 -29
  34. data/vendor/libgit2/include/git2/remote.h +5 -11
  35. data/vendor/libgit2/include/git2/repository.h +44 -15
  36. data/vendor/libgit2/include/git2/reset.h +19 -10
  37. data/vendor/libgit2/include/git2/revert.h +2 -2
  38. data/vendor/libgit2/include/git2/submodule.h +3 -9
  39. data/vendor/libgit2/include/git2/sys/config.h +3 -1
  40. data/vendor/libgit2/include/git2/sys/filter.h +10 -2
  41. data/vendor/libgit2/include/git2/sys/hashsig.h +49 -22
  42. data/vendor/libgit2/include/git2/transport.h +1 -1
  43. data/vendor/libgit2/include/git2/types.h +10 -3
  44. data/vendor/libgit2/include/git2/version.h +3 -2
  45. data/vendor/libgit2/src/annotated_commit.c +28 -0
  46. data/vendor/libgit2/src/array.h +19 -8
  47. data/vendor/libgit2/src/attr.c +95 -35
  48. data/vendor/libgit2/src/attr_file.c +51 -17
  49. data/vendor/libgit2/src/attr_file.h +37 -10
  50. data/vendor/libgit2/src/attrcache.c +13 -7
  51. data/vendor/libgit2/src/attrcache.h +1 -0
  52. data/vendor/libgit2/src/blame.c +26 -2
  53. data/vendor/libgit2/src/blame_git.c +6 -2
  54. data/vendor/libgit2/src/blob.c +6 -8
  55. data/vendor/libgit2/src/branch.c +55 -43
  56. data/vendor/libgit2/src/buf_text.c +13 -6
  57. data/vendor/libgit2/src/buffer.c +110 -25
  58. data/vendor/libgit2/src/buffer.h +18 -0
  59. data/vendor/libgit2/src/checkout.c +164 -92
  60. data/vendor/libgit2/src/checkout.h +0 -7
  61. data/vendor/libgit2/src/cherrypick.c +13 -7
  62. data/vendor/libgit2/src/clone.c +23 -25
  63. data/vendor/libgit2/src/commit.c +3 -3
  64. data/vendor/libgit2/src/common.h +23 -1
  65. data/vendor/libgit2/src/config.c +137 -19
  66. data/vendor/libgit2/src/config.h +2 -2
  67. data/vendor/libgit2/src/config_cache.c +2 -1
  68. data/vendor/libgit2/src/config_file.c +39 -18
  69. data/vendor/libgit2/src/config_file.h +1 -1
  70. data/vendor/libgit2/src/crlf.c +1 -1
  71. data/vendor/libgit2/src/delta-apply.c +3 -2
  72. data/vendor/libgit2/src/delta.c +25 -6
  73. data/vendor/libgit2/src/describe.c +2 -0
  74. data/vendor/libgit2/src/diff.c +8 -5
  75. data/vendor/libgit2/src/diff_driver.c +39 -18
  76. data/vendor/libgit2/src/diff_file.c +1 -1
  77. data/vendor/libgit2/src/diff_patch.c +12 -6
  78. data/vendor/libgit2/src/diff_tform.c +21 -24
  79. data/vendor/libgit2/src/filebuf.c +14 -12
  80. data/vendor/libgit2/src/fileops.c +61 -18
  81. data/vendor/libgit2/src/fileops.h +11 -2
  82. data/vendor/libgit2/src/filter.c +351 -99
  83. data/vendor/libgit2/src/filter.h +17 -0
  84. data/vendor/libgit2/src/global.c +38 -9
  85. data/vendor/libgit2/src/hash/hash_generic.c +1 -1
  86. data/vendor/libgit2/src/hashsig.c +28 -16
  87. data/vendor/libgit2/src/ignore.c +2 -2
  88. data/vendor/libgit2/src/index.c +159 -42
  89. data/vendor/libgit2/src/index.h +29 -0
  90. data/vendor/libgit2/src/indexer.c +11 -2
  91. data/vendor/libgit2/src/integer.h +96 -0
  92. data/vendor/libgit2/src/iterator.c +5 -3
  93. data/vendor/libgit2/src/khash.h +41 -29
  94. data/vendor/libgit2/src/merge.c +48 -35
  95. data/vendor/libgit2/src/merge.h +0 -1
  96. data/vendor/libgit2/src/merge_file.c +13 -0
  97. data/vendor/libgit2/src/mwindow.c +1 -1
  98. data/vendor/libgit2/src/notes.c +1 -1
  99. data/vendor/libgit2/src/odb.c +13 -11
  100. data/vendor/libgit2/src/odb_loose.c +22 -10
  101. data/vendor/libgit2/src/odb_mempack.c +4 -2
  102. data/vendor/libgit2/src/offmap.h +3 -2
  103. data/vendor/libgit2/src/oid.c +1 -1
  104. data/vendor/libgit2/src/oidmap.h +2 -1
  105. data/vendor/libgit2/src/openssl_stream.c +6 -3
  106. data/vendor/libgit2/src/pack-objects.c +273 -12
  107. data/vendor/libgit2/src/pack-objects.h +10 -0
  108. data/vendor/libgit2/src/pack.c +17 -6
  109. data/vendor/libgit2/src/pack.h +1 -3
  110. data/vendor/libgit2/src/path.c +68 -38
  111. data/vendor/libgit2/src/pathspec.c +3 -0
  112. data/vendor/libgit2/src/pool.c +9 -8
  113. data/vendor/libgit2/src/posix.c +11 -1
  114. data/vendor/libgit2/src/push.c +15 -17
  115. data/vendor/libgit2/src/push.h +1 -6
  116. data/vendor/libgit2/src/rebase.c +77 -35
  117. data/vendor/libgit2/src/refdb_fs.c +2 -2
  118. data/vendor/libgit2/src/refs.c +107 -81
  119. data/vendor/libgit2/src/refs.h +2 -2
  120. data/vendor/libgit2/src/refspec.c +3 -0
  121. data/vendor/libgit2/src/remote.c +19 -21
  122. data/vendor/libgit2/src/repository.c +258 -67
  123. data/vendor/libgit2/src/repository.h +31 -16
  124. data/vendor/libgit2/src/reset.c +28 -12
  125. data/vendor/libgit2/src/revert.c +12 -7
  126. data/vendor/libgit2/src/revwalk.c +3 -5
  127. data/vendor/libgit2/src/revwalk.h +1 -1
  128. data/vendor/libgit2/src/sortedcache.c +5 -3
  129. data/vendor/libgit2/src/stash.c +3 -5
  130. data/vendor/libgit2/src/strmap.h +2 -1
  131. data/vendor/libgit2/src/submodule.c +5 -6
  132. data/vendor/libgit2/src/tag.c +7 -5
  133. data/vendor/libgit2/src/transaction.c +1 -1
  134. data/vendor/libgit2/src/transports/cred.c +5 -2
  135. data/vendor/libgit2/src/transports/git.c +2 -3
  136. data/vendor/libgit2/src/transports/local.c +15 -34
  137. data/vendor/libgit2/src/transports/smart.c +1 -1
  138. data/vendor/libgit2/src/transports/smart_pkt.c +58 -18
  139. data/vendor/libgit2/src/transports/smart_protocol.c +2 -2
  140. data/vendor/libgit2/src/transports/winhttp.c +2 -2
  141. data/vendor/libgit2/src/tree.c +7 -5
  142. data/vendor/libgit2/src/tsort.c +3 -1
  143. data/vendor/libgit2/src/util.c +25 -0
  144. data/vendor/libgit2/src/util.h +31 -27
  145. data/vendor/libgit2/src/vector.c +2 -7
  146. data/vendor/libgit2/src/win32/dir.c +5 -3
  147. data/vendor/libgit2/src/win32/git2.rc +8 -4
  148. data/vendor/libgit2/src/win32/mingw-compat.h +7 -0
  149. data/vendor/libgit2/src/win32/msvc-compat.h +3 -0
  150. data/vendor/libgit2/src/win32/posix.h +1 -3
  151. data/vendor/libgit2/src/win32/posix_w32.c +31 -7
  152. data/vendor/libgit2/src/win32/utf-conv.c +1 -3
  153. data/vendor/libgit2/src/zstream.c +1 -1
  154. metadata +5 -5
  155. data/vendor/libgit2/src/bswap.h +0 -97
@@ -94,4 +94,33 @@ extern int git_index_snapshot_find(
94
94
  const char *path, size_t path_len, int stage);
95
95
 
96
96
 
97
+ typedef struct {
98
+ git_index *index;
99
+ git_filebuf file;
100
+ unsigned int should_write:1;
101
+ } git_indexwriter;
102
+
103
+ #define GIT_INDEXWRITER_INIT { NULL, GIT_FILEBUF_INIT }
104
+
105
+ /* Lock the index for eventual writing. */
106
+ extern int git_indexwriter_init(git_indexwriter *writer, git_index *index);
107
+
108
+ /* Lock the index for eventual writing by a repository operation: a merge,
109
+ * revert, cherry-pick or a rebase. Note that the given checkout strategy
110
+ * will be updated for the operation's use so that checkout will not write
111
+ * the index.
112
+ */
113
+ extern int git_indexwriter_init_for_operation(
114
+ git_indexwriter *writer,
115
+ git_repository *repo,
116
+ unsigned int *checkout_strategy);
117
+
118
+ /* Write the index and unlock it. */
119
+ extern int git_indexwriter_commit(git_indexwriter *writer);
120
+
121
+ /* Cleanup an index writing session, unlocking the file (if it is still
122
+ * locked and freeing any data structures.
123
+ */
124
+ extern void git_indexwriter_cleanup(git_indexwriter *writer);
125
+
97
126
  #endif
@@ -18,6 +18,8 @@
18
18
  #include "oidmap.h"
19
19
  #include "zstream.h"
20
20
 
21
+ GIT__USE_OIDMAP;
22
+
21
23
  extern git_mutex git__mwindow_mutex;
22
24
 
23
25
  #define UINT31_MAX (0x7FFFFFFF)
@@ -287,12 +289,19 @@ static int store_object(git_indexer *idx)
287
289
  pentry->offset = entry_start;
288
290
 
289
291
  k = kh_put(oid, idx->pack->idx_cache, &pentry->sha1, &error);
290
- if (!error) {
292
+ if (error == -1) {
293
+ git__free(pentry);
294
+ giterr_set_oom();
295
+ goto on_error;
296
+ }
297
+
298
+ if (error == 0) {
299
+ giterr_set(GITERR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->sha1));
291
300
  git__free(pentry);
292
- giterr_set(GITERR_INDEXER, "cannot handle duplicate objects in pack");
293
301
  goto on_error;
294
302
  }
295
303
 
304
+
296
305
  kh_value(idx->pack->idx_cache, k) = pentry;
297
306
 
298
307
  git_oid_cpy(&entry->oid, &oid);
@@ -0,0 +1,96 @@
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_integer_h__
8
+ #define INCLUDE_integer_h__
9
+
10
+ /** @return true if p fits into the range of a size_t */
11
+ GIT_INLINE(int) git__is_sizet(git_off_t p)
12
+ {
13
+ size_t r = (size_t)p;
14
+ return p == (git_off_t)r;
15
+ }
16
+
17
+ /** @return true if p fits into the range of an ssize_t */
18
+ GIT_INLINE(int) git__is_ssizet(size_t p)
19
+ {
20
+ ssize_t r = (ssize_t)p;
21
+ return p == (size_t)r;
22
+ }
23
+
24
+ /** @return true if p fits into the range of a uint32_t */
25
+ GIT_INLINE(int) git__is_uint32(size_t p)
26
+ {
27
+ uint32_t r = (uint32_t)p;
28
+ return p == (size_t)r;
29
+ }
30
+
31
+ /** @return true if p fits into the range of an unsigned long */
32
+ GIT_INLINE(int) git__is_ulong(git_off_t p)
33
+ {
34
+ unsigned long r = (unsigned long)p;
35
+ return p == (git_off_t)r;
36
+ }
37
+
38
+ /** @return true if p fits into the range of an int */
39
+ GIT_INLINE(int) git__is_int(long long p)
40
+ {
41
+ int r = (int)p;
42
+ return p == (long long)r;
43
+ }
44
+
45
+ /**
46
+ * Sets `one + two` into `out`, unless the arithmetic would overflow.
47
+ * @return true if the result fits in a `uint64_t`, false on overflow.
48
+ */
49
+ GIT_INLINE(bool) git__add_uint64_overflow(uint64_t *out, uint64_t one, uint64_t two)
50
+ {
51
+ if (UINT64_MAX - one < two)
52
+ return true;
53
+ *out = one + two;
54
+ return false;
55
+ }
56
+
57
+ /* Use clang/gcc compiler intrinsics whenever possible */
58
+ #if (SIZE_MAX == UINT_MAX) && __has_builtin(__builtin_uadd_overflow)
59
+ # define git__add_sizet_overflow(out, one, two) \
60
+ __builtin_uadd_overflow(one, two, out)
61
+ # define git__multiply_sizet_overflow(out, one, two) \
62
+ __builtin_umul_overflow(one, two, out)
63
+ #elif (SIZE_MAX == ULONG_MAX) && __has_builtin(__builtin_uaddl_overflow)
64
+ # define git__add_sizet_overflow(out, one, two) \
65
+ __builtin_uaddl_overflow(one, two, out)
66
+ # define git__multiply_sizet_overflow(out, one, two) \
67
+ __builtin_umull_overflow(one, two, out)
68
+ #else
69
+
70
+ /**
71
+ * Sets `one + two` into `out`, unless the arithmetic would overflow.
72
+ * @return true if the result fits in a `size_t`, false on overflow.
73
+ */
74
+ GIT_INLINE(bool) git__add_sizet_overflow(size_t *out, size_t one, size_t two)
75
+ {
76
+ if (SIZE_MAX - one < two)
77
+ return true;
78
+ *out = one + two;
79
+ return false;
80
+ }
81
+
82
+ /**
83
+ * Sets `one * two` into `out`, unless the arithmetic would overflow.
84
+ * @return true if the result fits in a `size_t`, false on overflow.
85
+ */
86
+ GIT_INLINE(bool) git__multiply_sizet_overflow(size_t *out, size_t one, size_t two)
87
+ {
88
+ if (one && SIZE_MAX / one < two)
89
+ return true;
90
+ *out = one * two;
91
+ return false;
92
+ }
93
+
94
+ #endif
95
+
96
+ #endif /* INCLUDE_integer_h__ */
@@ -336,7 +336,7 @@ static int tree_iterator__push_frame(tree_iterator *ti)
336
336
  {
337
337
  int error = 0;
338
338
  tree_iterator_frame *head = ti->head, *tf = NULL;
339
- size_t i, n_entries = 0;
339
+ size_t i, n_entries = 0, alloclen;
340
340
 
341
341
  if (head->current >= head->n_entries || !head->entries[head->current]->tree)
342
342
  return GIT_ITEROVER;
@@ -344,8 +344,10 @@ static int tree_iterator__push_frame(tree_iterator *ti)
344
344
  for (i = head->current; i < head->next; ++i)
345
345
  n_entries += git_tree_entrycount(head->entries[i]->tree);
346
346
 
347
- tf = git__calloc(sizeof(tree_iterator_frame) +
348
- n_entries * sizeof(tree_iterator_entry *), 1);
347
+ GITERR_CHECK_ALLOC_MULTIPLY(&alloclen, sizeof(tree_iterator_entry *), n_entries);
348
+ GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, sizeof(tree_iterator_frame));
349
+
350
+ tf = git__calloc(1, alloclen);
349
351
  GITERR_CHECK_ALLOC(tf);
350
352
 
351
353
  tf->n_entries = n_entries;
@@ -46,6 +46,19 @@ int main() {
46
46
  */
47
47
 
48
48
  /*
49
+ 2013-05-02 (0.2.8):
50
+
51
+ * Use quadratic probing. When the capacity is power of 2, stepping function
52
+ i*(i+1)/2 guarantees to traverse each bucket. It is better than double
53
+ hashing on cache performance and is more robust than linear probing.
54
+
55
+ In theory, double hashing should be more robust than quadratic probing.
56
+ However, my implementation is probably not for large hash tables, because
57
+ the second hash function is closely tied to the first hash function,
58
+ which reduce the effectiveness of double hashing.
59
+
60
+ Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php
61
+
49
62
  2011-12-29 (0.2.7):
50
63
 
51
64
  * Minor code clean up; no actual effect.
@@ -110,13 +123,13 @@ int main() {
110
123
  Generic hash table library.
111
124
  */
112
125
 
113
- #define AC_VERSION_KHASH_H "0.2.6"
126
+ #define AC_VERSION_KHASH_H "0.2.8"
114
127
 
115
128
  #include <stdlib.h>
116
129
  #include <string.h>
117
130
  #include <limits.h>
118
131
 
119
- /* compipler specific configuration */
132
+ /* compiler specific configuration */
120
133
 
121
134
  #if UINT_MAX == 0xffffffffu
122
135
  typedef unsigned int khint32_t;
@@ -130,11 +143,13 @@ typedef unsigned long khint64_t;
130
143
  typedef unsigned long long khint64_t;
131
144
  #endif
132
145
 
146
+ #ifndef kh_inline
133
147
  #ifdef _MSC_VER
134
148
  #define kh_inline __inline
135
149
  #else
136
150
  #define kh_inline inline
137
151
  #endif
152
+ #endif /* kh_inline */
138
153
 
139
154
  typedef khint32_t khint_t;
140
155
  typedef khint_t khiter_t;
@@ -147,12 +162,6 @@ typedef khint_t khiter_t;
147
162
  #define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1)))
148
163
  #define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1))
149
164
 
150
- #ifdef KHASH_LINEAR
151
- #define __ac_inc(k, m) 1
152
- #else
153
- #define __ac_inc(k, m) (((k)>>3 ^ (k)<<3) | 1) & (m)
154
- #endif
155
-
156
165
  #define __ac_fsize(m) ((m) < 16? 1 : (m)>>4)
157
166
 
158
167
  #ifndef kroundup32
@@ -168,6 +177,9 @@ typedef khint_t khiter_t;
168
177
  #ifndef krealloc
169
178
  #define krealloc(P,Z) realloc(P,Z)
170
179
  #endif
180
+ #ifndef kreallocarray
181
+ #define kreallocarray(P,N,Z) ((SIZE_MAX - N < Z) ? NULL : krealloc(P, (N*Z)))
182
+ #endif
171
183
  #ifndef kfree
172
184
  #define kfree(P) free(P)
173
185
  #endif
@@ -175,7 +187,7 @@ typedef khint_t khiter_t;
175
187
  static const double __ac_HASH_UPPER = 0.77;
176
188
 
177
189
  #define __KHASH_TYPE(name, khkey_t, khval_t) \
178
- typedef struct { \
190
+ typedef struct kh_##name##_s { \
179
191
  khint_t n_buckets, size, n_occupied, upper_bound; \
180
192
  khint32_t *flags; \
181
193
  khkey_t *keys; \
@@ -213,19 +225,19 @@ static const double __ac_HASH_UPPER = 0.77;
213
225
  SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \
214
226
  { \
215
227
  if (h->n_buckets) { \
216
- khint_t inc, k, i, last, mask; \
228
+ khint_t k, i, last, mask, step = 0; \
217
229
  mask = h->n_buckets - 1; \
218
230
  k = __hash_func(key); i = k & mask; \
219
- inc = __ac_inc(k, mask); last = i; /* inc==1 for linear probing */ \
231
+ last = i; \
220
232
  while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
221
- i = (i + inc) & mask; \
233
+ i = (i + (++step)) & mask; \
222
234
  if (i == last) return h->n_buckets; \
223
235
  } \
224
236
  return __ac_iseither(h->flags, i)? h->n_buckets : i; \
225
237
  } else return 0; \
226
238
  } \
227
239
  SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \
228
- { /* This function uses 0.25*n_bucktes bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \
240
+ { /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \
229
241
  khint32_t *new_flags = 0; \
230
242
  khint_t j = 1; \
231
243
  { \
@@ -233,16 +245,16 @@ static const double __ac_HASH_UPPER = 0.77;
233
245
  if (new_n_buckets < 4) new_n_buckets = 4; \
234
246
  if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \
235
247
  else { /* hash table size to be changed (shrink or expand); rehash */ \
236
- new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
248
+ new_flags = (khint32_t*)kreallocarray(NULL, __ac_fsize(new_n_buckets), sizeof(khint32_t)); \
237
249
  if (!new_flags) return -1; \
238
250
  memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \
239
251
  if (h->n_buckets < new_n_buckets) { /* expand */ \
240
- khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
241
- if (!new_keys) return -1; \
252
+ khkey_t *new_keys = (khkey_t*)kreallocarray((void *)h->keys, new_n_buckets, sizeof(khkey_t)); \
253
+ if (!new_keys) { kfree(new_flags); return -1; } \
242
254
  h->keys = new_keys; \
243
255
  if (kh_is_map) { \
244
- khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
245
- if (!new_vals) return -1; \
256
+ khval_t *new_vals = (khval_t*)kreallocarray((void *)h->vals, new_n_buckets, sizeof(khval_t)); \
257
+ if (!new_vals) { kfree(new_flags); return -1; } \
246
258
  h->vals = new_vals; \
247
259
  } \
248
260
  } /* otherwise shrink */ \
@@ -258,11 +270,10 @@ static const double __ac_HASH_UPPER = 0.77;
258
270
  if (kh_is_map) val = h->vals[j]; \
259
271
  __ac_set_isdel_true(h->flags, j); \
260
272
  while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \
261
- khint_t inc, k, i; \
273
+ khint_t k, i, step = 0; \
262
274
  k = __hash_func(key); \
263
275
  i = k & new_mask; \
264
- inc = __ac_inc(k, new_mask); \
265
- while (!__ac_isempty(new_flags, i)) i = (i + inc) & new_mask; \
276
+ while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \
266
277
  __ac_set_isempty_false(new_flags, i); \
267
278
  if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \
268
279
  { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \
@@ -277,8 +288,8 @@ static const double __ac_HASH_UPPER = 0.77;
277
288
  } \
278
289
  } \
279
290
  if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \
280
- h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
281
- if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \
291
+ h->keys = (khkey_t*)kreallocarray((void *)h->keys, new_n_buckets, sizeof(khkey_t)); \
292
+ if (kh_is_map) h->vals = (khval_t*)kreallocarray((void *)h->vals, new_n_buckets, sizeof(khval_t)); \
282
293
  } \
283
294
  kfree(h->flags); /* free the working space */ \
284
295
  h->flags = new_flags; \
@@ -301,14 +312,14 @@ static const double __ac_HASH_UPPER = 0.77;
301
312
  } \
302
313
  } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \
303
314
  { \
304
- khint_t inc, k, i, site, last, mask = h->n_buckets - 1; \
315
+ khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \
305
316
  x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \
306
317
  if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \
307
318
  else { \
308
- inc = __ac_inc(k, mask); last = i; \
319
+ last = i; \
309
320
  while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \
310
321
  if (__ac_isdel(h->flags, i)) site = i; \
311
- i = (i + inc) & mask; \
322
+ i = (i + (++step)) & mask; \
312
323
  if (i == last) { x = site; break; } \
313
324
  } \
314
325
  if (x == h->n_buckets) { \
@@ -449,7 +460,8 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
449
460
  @param name Name of the hash table [symbol]
450
461
  @param h Pointer to the hash table [khash_t(name)*]
451
462
  @param k Key [type of keys]
452
- @param r Extra return code: 0 if the key is present in the hash table;
463
+ @param r Extra return code: -1 if the operation failed;
464
+ 0 if the key is present in the hash table;
453
465
  1 if the bucket is empty (never used); 2 if the element in
454
466
  the bucket has been deleted [int*]
455
467
  @return Iterator to the inserted element [khint_t]
@@ -461,7 +473,7 @@ static kh_inline khint_t __ac_Wang_hash(khint_t key)
461
473
  @param name Name of the hash table [symbol]
462
474
  @param h Pointer to the hash table [khash_t(name)*]
463
475
  @param k Key [type of keys]
464
- @return Iterator to the found element, or kh_end(h) is the element is absent [khint_t]
476
+ @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t]
465
477
  */
466
478
  #define kh_get(name, h, k) kh_get_##name(h, k)
467
479
 
@@ -607,4 +619,4 @@ typedef const char *kh_cstr_t;
607
619
  #define KHASH_MAP_INIT_STR(name, khval_t) \
608
620
  KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal)
609
621
 
610
- #endif /* __AC_KHASH_H */
622
+ #endif /* __AC_KHASH_H */
@@ -61,6 +61,11 @@ struct merge_diff_df_data {
61
61
  git_merge_diff *prev_conflict;
62
62
  };
63
63
 
64
+ GIT_INLINE(int) merge_diff_detect_binary(
65
+ bool *binary_out,
66
+ git_repository *repo,
67
+ const git_merge_diff *conflict);
68
+
64
69
 
65
70
  /* Merge base computation */
66
71
 
@@ -653,7 +658,8 @@ static int merge_conflict_resolve_automerge(
653
658
  int *resolved,
654
659
  git_merge_diff_list *diff_list,
655
660
  const git_merge_diff *conflict,
656
- unsigned int merge_file_favor)
661
+ unsigned int merge_file_favor,
662
+ unsigned int file_flags)
657
663
  {
658
664
  const git_index_entry *ancestor = NULL, *ours = NULL, *theirs = NULL;
659
665
  git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
@@ -662,6 +668,7 @@ static int merge_conflict_resolve_automerge(
662
668
  git_odb *odb = NULL;
663
669
  git_oid automerge_oid;
664
670
  int error = 0;
671
+ bool binary = false;
665
672
 
666
673
  assert(resolved && diff_list && conflict);
667
674
 
@@ -697,7 +704,9 @@ static int merge_conflict_resolve_automerge(
697
704
  return 0;
698
705
 
699
706
  /* Reject binary conflicts */
700
- if (conflict->binary)
707
+ if ((error = merge_diff_detect_binary(&binary, diff_list->repo, conflict)) < 0)
708
+ return error;
709
+ if (binary)
701
710
  return 0;
702
711
 
703
712
  ancestor = GIT_MERGE_INDEX_ENTRY_EXISTS(conflict->ancestor_entry) ?
@@ -708,6 +717,7 @@ static int merge_conflict_resolve_automerge(
708
717
  &conflict->their_entry : NULL;
709
718
 
710
719
  opts.favor = merge_file_favor;
720
+ opts.flags = file_flags;
711
721
 
712
722
  if ((error = git_repository_odb(&odb, diff_list->repo)) < 0 ||
713
723
  (error = git_merge_file_from_index(&result, diff_list->repo, ancestor, ours, theirs, &opts)) < 0 ||
@@ -741,7 +751,8 @@ static int merge_conflict_resolve(
741
751
  int *out,
742
752
  git_merge_diff_list *diff_list,
743
753
  const git_merge_diff *conflict,
744
- unsigned int merge_file_favor)
754
+ unsigned int merge_file_favor,
755
+ unsigned int file_flags)
745
756
  {
746
757
  int resolved = 0;
747
758
  int error = 0;
@@ -757,7 +768,8 @@ static int merge_conflict_resolve(
757
768
  if (!resolved && (error = merge_conflict_resolve_one_renamed(&resolved, diff_list, conflict)) < 0)
758
769
  goto done;
759
770
 
760
- if (!resolved && (error = merge_conflict_resolve_automerge(&resolved, diff_list, conflict, merge_file_favor)) < 0)
771
+ if (!resolved && (error = merge_conflict_resolve_automerge(&resolved, diff_list, conflict,
772
+ merge_file_favor, file_flags)) < 0)
761
773
  goto done;
762
774
 
763
775
  *out = resolved;
@@ -1150,7 +1162,7 @@ int git_merge_diff_list__find_renames(
1150
1162
 
1151
1163
  assert(diff_list && opts);
1152
1164
 
1153
- if ((opts->flags & GIT_MERGE_TREE_FIND_RENAMES) == 0)
1165
+ if ((opts->tree_flags & GIT_MERGE_TREE_FIND_RENAMES) == 0)
1154
1166
  return 0;
1155
1167
 
1156
1168
  similarity_ours = git__calloc(diff_list->conflicts.length,
@@ -1169,7 +1181,7 @@ int git_merge_diff_list__find_renames(
1169
1181
  goto done;
1170
1182
 
1171
1183
  if (diff_list->conflicts.length <= opts->target_limit) {
1172
- cache_size = diff_list->conflicts.length * 3;
1184
+ GITERR_CHECK_ALLOC_MULTIPLY(&cache_size, diff_list->conflicts.length, 3);
1173
1185
  cache = git__calloc(cache_size, sizeof(void *));
1174
1186
  GITERR_CHECK_ALLOC(cache);
1175
1187
 
@@ -1303,35 +1315,39 @@ GIT_INLINE(int) merge_diff_detect_type(
1303
1315
  }
1304
1316
 
1305
1317
  GIT_INLINE(int) merge_diff_detect_binary(
1318
+ bool *binary_out,
1306
1319
  git_repository *repo,
1307
- git_merge_diff *conflict)
1320
+ const git_merge_diff *conflict)
1308
1321
  {
1309
1322
  git_blob *ancestor_blob = NULL, *our_blob = NULL, *their_blob = NULL;
1310
1323
  int error = 0;
1324
+ bool binary = false;
1311
1325
 
1312
1326
  if (GIT_MERGE_INDEX_ENTRY_ISFILE(conflict->ancestor_entry)) {
1313
1327
  if ((error = git_blob_lookup(&ancestor_blob, repo, &conflict->ancestor_entry.id)) < 0)
1314
1328
  goto done;
1315
1329
 
1316
- conflict->binary = git_blob_is_binary(ancestor_blob);
1330
+ binary = git_blob_is_binary(ancestor_blob);
1317
1331
  }
1318
1332
 
1319
- if (!conflict->binary &&
1333
+ if (!binary &&
1320
1334
  GIT_MERGE_INDEX_ENTRY_ISFILE(conflict->our_entry)) {
1321
1335
  if ((error = git_blob_lookup(&our_blob, repo, &conflict->our_entry.id)) < 0)
1322
1336
  goto done;
1323
1337
 
1324
- conflict->binary = git_blob_is_binary(our_blob);
1338
+ binary = git_blob_is_binary(our_blob);
1325
1339
  }
1326
1340
 
1327
- if (!conflict->binary &&
1341
+ if (!binary &&
1328
1342
  GIT_MERGE_INDEX_ENTRY_ISFILE(conflict->their_entry)) {
1329
1343
  if ((error = git_blob_lookup(&their_blob, repo, &conflict->their_entry.id)) < 0)
1330
1344
  goto done;
1331
1345
 
1332
- conflict->binary = git_blob_is_binary(their_blob);
1346
+ binary = git_blob_is_binary(their_blob);
1333
1347
  }
1334
1348
 
1349
+ *binary_out = binary;
1350
+
1335
1351
  done:
1336
1352
  git_blob_free(ancestor_blob);
1337
1353
  git_blob_free(our_blob);
@@ -1411,7 +1427,6 @@ static int merge_diff_list_insert_conflict(
1411
1427
  if ((conflict = merge_diff_from_index_entries(diff_list, tree_items)) == NULL ||
1412
1428
  merge_diff_detect_type(conflict) < 0 ||
1413
1429
  merge_diff_detect_df_conflict(merge_df_data, conflict) < 0 ||
1414
- merge_diff_detect_binary(diff_list->repo, conflict) < 0 ||
1415
1430
  git_vector_insert(&diff_list->conflicts, conflict) < 0)
1416
1431
  return -1;
1417
1432
 
@@ -1589,7 +1604,7 @@ static int merge_normalize_opts(
1589
1604
  git_merge_options init = GIT_MERGE_OPTIONS_INIT;
1590
1605
  memcpy(opts, &init, sizeof(init));
1591
1606
 
1592
- opts->flags = GIT_MERGE_TREE_FIND_RENAMES;
1607
+ opts->tree_flags = GIT_MERGE_TREE_FIND_RENAMES;
1593
1608
  opts->rename_threshold = GIT_MERGE_TREE_RENAME_THRESHOLD;
1594
1609
  }
1595
1610
 
@@ -1612,13 +1627,7 @@ static int merge_normalize_opts(
1612
1627
  opts->metric->buffer_signature = git_diff_find_similar__hashsig_for_buf;
1613
1628
  opts->metric->free_signature = git_diff_find_similar__hashsig_free;
1614
1629
  opts->metric->similarity = git_diff_find_similar__calc_similarity;
1615
-
1616
- if (opts->flags & GIT_DIFF_FIND_IGNORE_WHITESPACE)
1617
- opts->metric->payload = (void *)GIT_HASHSIG_IGNORE_WHITESPACE;
1618
- else if (opts->flags & GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE)
1619
- opts->metric->payload = (void *)GIT_HASHSIG_NORMAL;
1620
- else
1621
- opts->metric->payload = (void *)GIT_HASHSIG_SMART_WHITESPACE;
1630
+ opts->metric->payload = (void *)GIT_HASHSIG_SMART_WHITESPACE;
1622
1631
  }
1623
1632
 
1624
1633
  return 0;
@@ -1785,7 +1794,7 @@ int git_merge_trees(
1785
1794
  git_vector_foreach(&changes, i, conflict) {
1786
1795
  int resolved = 0;
1787
1796
 
1788
- if ((error = merge_conflict_resolve(&resolved, diff_list, conflict, opts.file_favor)) < 0)
1797
+ if ((error = merge_conflict_resolve(&resolved, diff_list, conflict, opts.file_favor, opts.file_flags)) < 0)
1789
1798
  goto done;
1790
1799
 
1791
1800
  if (!resolved)
@@ -2229,12 +2238,13 @@ static int merge_ancestor_head(
2229
2238
  size_t their_heads_len)
2230
2239
  {
2231
2240
  git_oid *oids, ancestor_oid;
2232
- size_t i;
2241
+ size_t i, alloc_len;
2233
2242
  int error = 0;
2234
2243
 
2235
2244
  assert(repo && our_head && their_heads);
2236
2245
 
2237
- oids = git__calloc(their_heads_len + 1, sizeof(git_oid));
2246
+ GITERR_CHECK_ALLOC_ADD(&alloc_len, their_heads_len, 1);
2247
+ oids = git__calloc(alloc_len, sizeof(git_oid));
2238
2248
  GITERR_CHECK_ALLOC(oids);
2239
2249
 
2240
2250
  git_oid_cpy(&oids[0], git_commit_id(our_head->commit));
@@ -2657,7 +2667,8 @@ int git_merge(
2657
2667
  git_checkout_options checkout_opts;
2658
2668
  git_annotated_commit *ancestor_head = NULL, *our_head = NULL;
2659
2669
  git_tree *ancestor_tree = NULL, *our_tree = NULL, **their_trees = NULL;
2660
- git_index *index_new = NULL;
2670
+ git_index *index = NULL;
2671
+ git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
2661
2672
  size_t i;
2662
2673
  int error = 0;
2663
2674
 
@@ -2671,11 +2682,10 @@ int git_merge(
2671
2682
  their_trees = git__calloc(their_heads_len, sizeof(git_tree *));
2672
2683
  GITERR_CHECK_ALLOC(their_trees);
2673
2684
 
2674
- if ((error = merge_heads(&ancestor_head, &our_head, repo, their_heads, their_heads_len)) < 0)
2675
- goto on_error;
2676
-
2677
- if ((error = merge_normalize_checkout_opts(repo, &checkout_opts, given_checkout_opts,
2678
- ancestor_head, our_head, their_heads_len, their_heads)) < 0)
2685
+ if ((error = merge_heads(&ancestor_head, &our_head, repo, their_heads, their_heads_len)) < 0 ||
2686
+ (error = merge_normalize_checkout_opts(repo, &checkout_opts, given_checkout_opts,
2687
+ ancestor_head, our_head, their_heads_len, their_heads)) < 0 ||
2688
+ (error = git_indexwriter_init_for_operation(&indexwriter, repo, &checkout_opts.checkout_strategy)) < 0)
2679
2689
  goto on_error;
2680
2690
 
2681
2691
  /* Write the merge files to the repository. */
@@ -2696,10 +2706,11 @@ int git_merge(
2696
2706
 
2697
2707
  /* TODO: recursive, octopus, etc... */
2698
2708
 
2699
- if ((error = git_merge_trees(&index_new, repo, ancestor_tree, our_tree, their_trees[0], merge_opts)) < 0 ||
2700
- (error = git_merge__check_result(repo, index_new)) < 0 ||
2701
- (error = git_merge__append_conflicts_to_merge_msg(repo, index_new)) < 0 ||
2702
- (error = git_checkout_index(repo, index_new, &checkout_opts)) < 0)
2709
+ if ((error = git_merge_trees(&index, repo, ancestor_tree, our_tree, their_trees[0], merge_opts)) < 0 ||
2710
+ (error = git_merge__check_result(repo, index)) < 0 ||
2711
+ (error = git_merge__append_conflicts_to_merge_msg(repo, index)) < 0 ||
2712
+ (error = git_checkout_index(repo, index, &checkout_opts)) < 0 ||
2713
+ (error = git_indexwriter_commit(&indexwriter)) < 0)
2703
2714
  goto on_error;
2704
2715
 
2705
2716
  goto done;
@@ -2708,7 +2719,9 @@ on_error:
2708
2719
  merge_state_cleanup(repo);
2709
2720
 
2710
2721
  done:
2711
- git_index_free(index_new);
2722
+ git_indexwriter_cleanup(&indexwriter);
2723
+
2724
+ git_index_free(index);
2712
2725
 
2713
2726
  git_tree_free(ancestor_tree);
2714
2727
  git_tree_free(our_tree);