rugged 0.21.0 → 0.21.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/include/git2/revert.h +1 -1
  4. data/vendor/libgit2/include/git2/transport.h +12 -10
  5. data/vendor/libgit2/include/git2/tree.h +2 -4
  6. data/vendor/libgit2/include/git2/version.h +2 -2
  7. data/vendor/libgit2/include/git2.h +1 -0
  8. data/vendor/libgit2/src/array.h +1 -1
  9. data/vendor/libgit2/src/buf_text.c +5 -9
  10. data/vendor/libgit2/src/buf_text.h +2 -3
  11. data/vendor/libgit2/src/cc-compat.h +8 -0
  12. data/vendor/libgit2/src/checkout.c +21 -3
  13. data/vendor/libgit2/src/config_file.c +11 -6
  14. data/vendor/libgit2/src/crlf.c +1 -2
  15. data/vendor/libgit2/src/diff_patch.c +1 -0
  16. data/vendor/libgit2/src/filebuf.c +2 -0
  17. data/vendor/libgit2/src/filter.c +11 -2
  18. data/vendor/libgit2/src/global.c +30 -2
  19. data/vendor/libgit2/src/index.c +29 -24
  20. data/vendor/libgit2/src/indexer.c +2 -9
  21. data/vendor/libgit2/src/merge.c +11 -3
  22. data/vendor/libgit2/src/mwindow.c +8 -117
  23. data/vendor/libgit2/src/mwindow.h +1 -9
  24. data/vendor/libgit2/src/netops.c +4 -1
  25. data/vendor/libgit2/src/odb_pack.c +3 -6
  26. data/vendor/libgit2/src/pack.c +5 -22
  27. data/vendor/libgit2/src/pack.h +0 -3
  28. data/vendor/libgit2/src/path.c +26 -16
  29. data/vendor/libgit2/src/pool.c +2 -2
  30. data/vendor/libgit2/src/refspec.c +42 -18
  31. data/vendor/libgit2/src/remote.c +13 -2
  32. data/vendor/libgit2/src/repository.c +3 -1
  33. data/vendor/libgit2/src/revwalk.c +0 -3
  34. data/vendor/libgit2/src/stash.c +5 -3
  35. data/vendor/libgit2/src/tag.c +3 -2
  36. data/vendor/libgit2/src/transports/http.c +20 -4
  37. data/vendor/libgit2/src/transports/ssh.c +23 -4
  38. data/vendor/libgit2/src/tree.c +60 -64
  39. data/vendor/libgit2/src/tree.h +3 -2
  40. data/vendor/libgit2/src/win32/posix_w32.c +14 -29
  41. metadata +68 -68
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0356879d784d17079ccdae0dfef24d5841c0774
4
- data.tar.gz: 2a4d772157bcc8b25f61a7745d1694507bc56ca4
3
+ metadata.gz: 7fd19143d7ae79c19dcc780edd7399e0b96c677b
4
+ data.tar.gz: c2e501d2d3525acc5a3a2297bc3726fc0c3465f8
5
5
  SHA512:
6
- metadata.gz: d6f0d49db816f5337decf934efda9529ddbf8beaf6edfa72737f661e7b5759afd7b4f27f21734de0098e101bc7b714b90aad674c450344d7cd7865de5fe73e3b
7
- data.tar.gz: cf7dca7617881507c212c4c813bd41494d31ed1c3d8579092dc138a5b449d89af5264c9b673cf938f39a8781c000c768bcf498bd82136afb167e950d617b88bc
6
+ metadata.gz: 2b6f3fb73a8d64f10b2dcac66dc7bc6a27c8257bf72f9d2d02b7d3179bb24a096a36593c87b420cfd31e889425c72b725d81f551907115ef717101716bb4f390
7
+ data.tar.gz: 991a7b7aaa258c7fe858dedde2694493ce4af466e61ea42935fac3afe3ceaa1b80298f345f83cb82ee237256968ffe45faabfc182402d349ded4665bcf794424
@@ -1,3 +1,3 @@
1
1
  module Rugged
2
- Version = VERSION = '0.21.0'
2
+ Version = VERSION = '0.21.2'
3
3
  end
@@ -59,7 +59,7 @@ GIT_EXTERN(int) git_revert_init_options(
59
59
  * @param merge_options the merge options (or null for defaults)
60
60
  * @return zero on success, -1 on failure.
61
61
  */
62
- GIT_EXTERN(int) git_revert_commit(
62
+ int git_revert_commit(
63
63
  git_index **out,
64
64
  git_repository *repo,
65
65
  git_commit *revert_commit,
@@ -11,10 +11,6 @@
11
11
  #include "net.h"
12
12
  #include "types.h"
13
13
 
14
- #ifdef GIT_SSH
15
- #include <libssh2.h>
16
- #endif
17
-
18
14
  /**
19
15
  * @file git2/transport.h
20
16
  * @brief Git transport interfaces and functions
@@ -61,14 +57,20 @@ typedef struct {
61
57
  char *password;
62
58
  } git_cred_userpass_plaintext;
63
59
 
64
- #ifdef GIT_SSH
65
- typedef LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC((*git_cred_sign_callback));
66
- typedef LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC((*git_cred_ssh_interactive_callback));
67
- #else
68
- typedef int (*git_cred_sign_callback)(void *, ...);
69
- typedef int (*git_cred_ssh_interactive_callback)(void *, ...);
60
+
61
+ /*
62
+ * If the user hasn't included libssh2.h before git2.h, we need to
63
+ * define a few types for the callback signatures.
64
+ */
65
+ #ifndef LIBSSH2_VERSION
66
+ typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION;
67
+ typedef struct _LIBSSH2_USERAUTH_KBDINT_PROMPT LIBSSH2_USERAUTH_KBDINT_PROMPT;
68
+ typedef struct _LIBSSH2_USERAUTH_KBDINT_RESPONSE LIBSSH2_USERAUTH_KBDINT_RESPONSE;
70
69
  #endif
71
70
 
71
+ typedef int (*git_cred_sign_callback)(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract);
72
+ typedef void (*git_cred_ssh_interactive_callback)(const char* name, int name_len, const char* instruction, int instruction_len, int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT* prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE* responses, void **abstract);
73
+
72
74
  /**
73
75
  * A ssh key from disk
74
76
  */
@@ -301,10 +301,8 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(
301
301
  * If an entry named `filename` already exists, its attributes
302
302
  * will be updated with the given ones.
303
303
  *
304
- * The optional pointer `out` can be used to retrieve a pointer to the
305
- * newly created/updated entry. Pass NULL if you do not need it. The
306
- * pointer may not be valid past the next operation in this
307
- * builder. Duplicate the entry if you want to keep it.
304
+ * The optional pointer `out` can be used to retrieve a pointer to
305
+ * the newly created/updated entry. Pass NULL if you do not need it.
308
306
  *
309
307
  * No attempt is being made to ensure that the provided oid points
310
308
  * to an existing git object in the object database, nor that the
@@ -7,10 +7,10 @@
7
7
  #ifndef INCLUDE_git_version_h__
8
8
  #define INCLUDE_git_version_h__
9
9
 
10
- #define LIBGIT2_VERSION "0.21.0"
10
+ #define LIBGIT2_VERSION "0.21.2"
11
11
  #define LIBGIT2_VER_MAJOR 0
12
12
  #define LIBGIT2_VER_MINOR 21
13
- #define LIBGIT2_VER_REVISION 0
13
+ #define LIBGIT2_VER_REVISION 2
14
14
 
15
15
  #define LIBGIT2_SOVERSION 21
16
16
 
@@ -32,6 +32,7 @@
32
32
  #include "git2/notes.h"
33
33
  #include "git2/object.h"
34
34
  #include "git2/odb.h"
35
+ #include "git2/odb_backend.h"
35
36
  #include "git2/oid.h"
36
37
  #include "git2/pack.h"
37
38
  #include "git2/patch.h"
@@ -44,7 +44,7 @@ typedef git_array_t(char) git_array_generic_t;
44
44
  /* use a generic array for growth so this can return the new item */
45
45
  GIT_INLINE(void *) git_array_grow(void *_a, size_t item_size)
46
46
  {
47
- git_array_generic_t *a = _a;
47
+ volatile git_array_generic_t *a = _a;
48
48
  uint32_t new_size = (a->size < 8) ? 8 : a->asize * 3 / 2;
49
49
  char *new_array = git__realloc(a->ptr, new_size * item_size);
50
50
  if (!new_array) {
@@ -123,13 +123,9 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
123
123
 
124
124
  for (; next; scan = next + 1, next = memchr(scan, '\n', end - scan)) {
125
125
  size_t copylen = next - scan;
126
- size_t needsize = tgt->size + copylen + 2 + 1;
127
-
128
- /* if we find mixed line endings, bail */
129
- if (next > start && next[-1] == '\r') {
130
- git_buf_free(tgt);
131
- return GIT_PASSTHROUGH;
132
- }
126
+ /* don't convert existing \r\n to \r\r\n */
127
+ size_t extralen = (next > start && next[-1] == '\r') ? 1 : 2;
128
+ size_t needsize = tgt->size + copylen + extralen + 1;
133
129
 
134
130
  if (tgt->asize < needsize && git_buf_grow(tgt, needsize) < 0)
135
131
  return -1;
@@ -138,8 +134,8 @@ int git_buf_text_lf_to_crlf(git_buf *tgt, const git_buf *src)
138
134
  memcpy(tgt->ptr + tgt->size, scan, copylen);
139
135
  tgt->size += copylen;
140
136
  }
141
-
142
- tgt->ptr[tgt->size++] = '\r';
137
+ if (extralen == 2)
138
+ tgt->ptr[tgt->size++] = '\r';
143
139
  tgt->ptr[tgt->size++] = '\n';
144
140
  }
145
141
 
@@ -56,10 +56,9 @@ GIT_INLINE(int) git_buf_text_puts_escape_regex(git_buf *buf, const char *string)
56
56
  extern void git_buf_text_unescape(git_buf *buf);
57
57
 
58
58
  /**
59
- * Replace all \r\n with \n.
59
+ * Replace all \r\n with \n. Does not modify \r without trailing \n.
60
60
  *
61
- * @return 0 on success, -1 on memory error, GIT_PASSTHROUGH if the
62
- * source buffer has mixed line endings.
61
+ * @return 0 on success, -1 on memory error
63
62
  */
64
63
  extern int git_buf_text_crlf_to_lf(git_buf *tgt, const git_buf *src);
65
64
 
@@ -35,6 +35,14 @@
35
35
  # define GIT_TYPEOF(x)
36
36
  #endif
37
37
 
38
+ #if defined(__GNUC__)
39
+ # define GIT_ALIGN(x,size) x __attribute__ ((aligned(size)))
40
+ #elif defined(_MSC_VER)
41
+ # define GIT_ALIGN(x,size) __declspec(align(size)) x
42
+ #else
43
+ # define GIT_ALIGN(x,size) x
44
+ #endif
45
+
38
46
  #define GIT_UNUSED(x) ((void)(x))
39
47
 
40
48
  /* Define the printf format specifer to use for size_t output */
@@ -1736,10 +1736,12 @@ static int checkout_write_merge(
1736
1736
  checkout_conflictdata *conflict)
1737
1737
  {
1738
1738
  git_buf our_label = GIT_BUF_INIT, their_label = GIT_BUF_INIT,
1739
- path_suffixed = GIT_BUF_INIT, path_workdir = GIT_BUF_INIT;
1739
+ path_suffixed = GIT_BUF_INIT, path_workdir = GIT_BUF_INIT,
1740
+ in_data = GIT_BUF_INIT, out_data = GIT_BUF_INIT;
1740
1741
  git_merge_file_options opts = GIT_MERGE_FILE_OPTIONS_INIT;
1741
1742
  git_merge_file_result result = {0};
1742
1743
  git_filebuf output = GIT_FILEBUF_INIT;
1744
+ git_filter_list *fl = NULL;
1743
1745
  int error = 0;
1744
1746
 
1745
1747
  if (data->opts.checkout_strategy & GIT_CHECKOUT_CONFLICT_STYLE_DIFF3)
@@ -1785,13 +1787,29 @@ static int checkout_write_merge(
1785
1787
  (error = checkout_safe_for_update_only(git_buf_cstr(&path_workdir), result.mode)) <= 0)
1786
1788
  goto done;
1787
1789
 
1790
+ if (!data->opts.disable_filters) {
1791
+ in_data.ptr = (char *)result.ptr;
1792
+ in_data.size = result.len;
1793
+
1794
+ if ((error = git_filter_list_load(&fl, data->repo, NULL, git_buf_cstr(&path_workdir),
1795
+ GIT_FILTER_TO_WORKTREE, GIT_FILTER_OPT_DEFAULT)) < 0 ||
1796
+ (error = git_filter_list_apply_to_data(&out_data, fl, &in_data)) < 0)
1797
+ goto done;
1798
+ } else {
1799
+ out_data.ptr = (char *)result.ptr;
1800
+ out_data.size = result.len;
1801
+ }
1802
+
1788
1803
  if ((error = git_futils_mkpath2file(path_workdir.ptr, 0755)) < 0 ||
1789
- (error = git_filebuf_open(&output, path_workdir.ptr, GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 ||
1790
- (error = git_filebuf_write(&output, result.ptr, result.len)) < 0 ||
1804
+ (error = git_filebuf_open(&output, git_buf_cstr(&path_workdir), GIT_FILEBUF_DO_NOT_BUFFER, result.mode)) < 0 ||
1805
+ (error = git_filebuf_write(&output, out_data.ptr, out_data.size)) < 0 ||
1791
1806
  (error = git_filebuf_commit(&output)) < 0)
1792
1807
  goto done;
1793
1808
 
1794
1809
  done:
1810
+ git_filter_list_free(fl);
1811
+
1812
+ git_buf_free(&out_data);
1795
1813
  git_buf_free(&our_label);
1796
1814
  git_buf_free(&their_label);
1797
1815
 
@@ -767,12 +767,17 @@ static int config_readonly_open(git_config_backend *cfg, git_config_level_t leve
767
767
  {
768
768
  diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
769
769
  diskfile_backend *src = b->snapshot_from;
770
+ diskfile_header *src_header = &src->header;
770
771
  refcounted_strmap *src_map;
772
+ int error;
773
+
774
+ if (!src_header->readonly && (error = config_refresh(&src_header->parent)) < 0)
775
+ return error;
771
776
 
772
777
  /* We're just copying data, don't care about the level */
773
778
  GIT_UNUSED(level);
774
779
 
775
- src_map = refcounted_strmap_take(&src->header);
780
+ src_map = refcounted_strmap_take(src_header);
776
781
  b->header.values = src_map;
777
782
 
778
783
  return 0;
@@ -1163,7 +1168,7 @@ static int strip_comments(char *line, int in_quotes)
1163
1168
  }
1164
1169
 
1165
1170
  /* skip any space at the end */
1166
- if (ptr > line && git__isspace(ptr[-1])) {
1171
+ while (ptr > line && git__isspace(ptr[-1])) {
1167
1172
  ptr--;
1168
1173
  }
1169
1174
  ptr[0] = '\0';
@@ -1522,6 +1527,9 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
1522
1527
 
1523
1528
  git_filebuf_write(&file, reader->buffer.ptr, reader->buffer.size);
1524
1529
 
1530
+ if (reader->buffer.size > 0 && *(reader->buffer.ptr + reader->buffer.size - 1) != '\n')
1531
+ git_filebuf_write(&file, "\n", 1);
1532
+
1525
1533
  /* And now if we just need to add a variable */
1526
1534
  if (!section_matches && write_section(&file, section) < 0)
1527
1535
  goto rewrite_fail;
@@ -1536,9 +1544,6 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
1536
1544
  }
1537
1545
 
1538
1546
  /* If we are here, there is at least a section line */
1539
- if (reader->buffer.size > 0 && *(reader->buffer.ptr + reader->buffer.size - 1) != '\n')
1540
- git_filebuf_write(&file, "\n", 1);
1541
-
1542
1547
  q = quotes_for_value(value);
1543
1548
  git_filebuf_printf(&file, "\t%s = %s%s%s\n", name, q, value, q);
1544
1549
  }
@@ -1649,7 +1654,7 @@ static int is_multiline_var(const char *str)
1649
1654
  }
1650
1655
 
1651
1656
  /* An odd number means last backslash wasn't escaped, so it's multiline */
1652
- return (end > str) && (count & 1);
1657
+ return count & 1;
1653
1658
  }
1654
1659
 
1655
1660
  static int parse_multiline_variable(struct reader *reader, git_buf *value, int in_quotes)
@@ -286,8 +286,7 @@ static int crlf_check(
286
286
  if (error < 0)
287
287
  return error;
288
288
 
289
- if (ca.crlf_action == GIT_CRLF_GUESS &&
290
- ca.auto_crlf == GIT_AUTO_CRLF_FALSE)
289
+ if (ca.auto_crlf == GIT_AUTO_CRLF_FALSE)
291
290
  return GIT_PASSTHROUGH;
292
291
 
293
292
  if (ca.auto_crlf == GIT_AUTO_CRLF_INPUT &&
@@ -274,6 +274,7 @@ int git_diff_foreach(
274
274
  return error;
275
275
 
276
276
  memset(&xo, 0, sizeof(xo));
277
+ memset(&patch, 0, sizeof(patch));
277
278
  diff_output_init(
278
279
  &xo.output, &diff->opts, file_cb, hunk_cb, data_cb, payload);
279
280
  git_xdiff_init(&xo, &diff->opts);
@@ -334,6 +334,8 @@ int git_filebuf_commit(git_filebuf *file)
334
334
 
335
335
  file->fd = -1;
336
336
 
337
+ p_unlink(file->path_original);
338
+
337
339
  if (p_rename(file->path_lock, file->path_original) < 0) {
338
340
  giterr_set(GITERR_OS, "Failed to rename lockfile to '%s'", file->path_original);
339
341
  goto on_error;
@@ -38,7 +38,7 @@ struct git_filter_list {
38
38
  };
39
39
 
40
40
  typedef struct {
41
- const char *filter_name;
41
+ char *filter_name;
42
42
  git_filter *filter;
43
43
  int priority;
44
44
  int initialized;
@@ -75,6 +75,7 @@ static void filter_registry_shutdown(void)
75
75
  fdef->initialized = false;
76
76
  }
77
77
 
78
+ git__free(fdef->filter_name);
78
79
  git__free(fdef->attrdata);
79
80
  git__free(fdef);
80
81
  }
@@ -230,6 +231,8 @@ int git_filter_register(
230
231
  size_t nattr = 0, nmatch = 0;
231
232
  git_buf attrs = GIT_BUF_INIT;
232
233
 
234
+ assert(name && filter);
235
+
233
236
  if (filter_registry_initialize() < 0)
234
237
  return -1;
235
238
 
@@ -246,7 +249,9 @@ int git_filter_register(
246
249
  sizeof(git_filter_def) + 2 * nattr * sizeof(char *), 1);
247
250
  GITERR_CHECK_ALLOC(fdef);
248
251
 
249
- fdef->filter_name = name;
252
+ fdef->filter_name = git__strdup(name);
253
+ GITERR_CHECK_ALLOC(fdef->filter_name);
254
+
250
255
  fdef->filter = filter;
251
256
  fdef->priority = priority;
252
257
  fdef->nattrs = nattr;
@@ -256,6 +261,7 @@ int git_filter_register(
256
261
  filter_def_set_attrs(fdef);
257
262
 
258
263
  if (git_vector_insert(&git__filter_registry->filters, fdef) < 0) {
264
+ git__free(fdef->filter_name);
259
265
  git__free(fdef->attrdata);
260
266
  git__free(fdef);
261
267
  return -1;
@@ -270,6 +276,8 @@ int git_filter_unregister(const char *name)
270
276
  size_t pos;
271
277
  git_filter_def *fdef;
272
278
 
279
+ assert(name);
280
+
273
281
  /* cannot unregister default filters */
274
282
  if (!strcmp(GIT_FILTER_CRLF, name) || !strcmp(GIT_FILTER_IDENT, name)) {
275
283
  giterr_set(GITERR_FILTER, "Cannot unregister filter '%s'", name);
@@ -288,6 +296,7 @@ int git_filter_unregister(const char *name)
288
296
  fdef->initialized = false;
289
297
  }
290
298
 
299
+ git__free(fdef->filter_name);
291
300
  git__free(fdef->attrdata);
292
301
  git__free(fdef);
293
302
 
@@ -61,15 +61,32 @@ void openssl_locking_function(int mode, int n, const char *file, int line)
61
61
  git_mutex_unlock(&openssl_locks[n]);
62
62
  }
63
63
  }
64
- #endif
65
64
 
65
+ static void shutdown_ssl(void)
66
+ {
67
+ git__free(openssl_locks);
68
+ }
69
+ #endif
66
70
 
67
71
  static void init_ssl(void)
68
72
  {
69
73
  #ifdef GIT_SSL
70
74
  SSL_load_error_strings();
71
75
  OpenSSL_add_ssl_algorithms();
76
+ /*
77
+ * Load SSLv{2,3} and TLSv1 so that we can talk with servers
78
+ * which use the SSL hellos, which are often used for
79
+ * compatibility. We then disable SSL so we only allow OpenSSL
80
+ * to speak TLSv1 to perform the encryption itself.
81
+ */
72
82
  git__ssl_ctx = SSL_CTX_new(SSLv23_method());
83
+ SSL_CTX_set_options(git__ssl_ctx,
84
+ SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3
85
+ /* Older OpenSSL and MacOS OpenSSL doesn't have this */
86
+ # ifdef SSL_OP_NO_COMPRESSION
87
+ | SSL_OP_NO_COMPRESSION
88
+ # endif
89
+ );
73
90
  SSL_CTX_set_mode(git__ssl_ctx, SSL_MODE_AUTO_RETRY);
74
91
  SSL_CTX_set_verify(git__ssl_ctx, SSL_VERIFY_NONE, NULL);
75
92
  if (!SSL_CTX_set_default_verify_paths(git__ssl_ctx)) {
@@ -97,6 +114,8 @@ static void init_ssl(void)
97
114
 
98
115
  CRYPTO_set_locking_callback(openssl_locking_function);
99
116
  }
117
+
118
+ git__on_shutdown(shutdown_ssl);
100
119
  # endif
101
120
  #endif
102
121
  }
@@ -221,6 +240,9 @@ int init_error = 0;
221
240
 
222
241
  static void cb__free_status(void *st)
223
242
  {
243
+ git_global_st *state = (git_global_st *) st;
244
+ git__free(state->error_t.message);
245
+
224
246
  git__free(st);
225
247
  }
226
248
 
@@ -291,7 +313,13 @@ static git_global_st __state;
291
313
 
292
314
  int git_threads_init(void)
293
315
  {
294
- init_ssl();
316
+ static int ssl_inited = 0;
317
+
318
+ if (!ssl_inited) {
319
+ init_ssl();
320
+ ssl_inited = 1;
321
+ }
322
+
295
323
  git_atomic_inc(&git__n_inits);
296
324
  return 0;
297
325
  }
@@ -1767,35 +1767,42 @@ static size_t read_entry(
1767
1767
  git_index_entry **out, const void *buffer, size_t buffer_size)
1768
1768
  {
1769
1769
  size_t path_length, entry_size;
1770
- uint16_t flags_raw;
1771
1770
  const char *path_ptr;
1772
- const struct entry_short *source = buffer;
1771
+ struct entry_short source;
1773
1772
  git_index_entry entry = {{0}};
1774
1773
 
1775
1774
  if (INDEX_FOOTER_SIZE + minimal_entry_size > buffer_size)
1776
1775
  return 0;
1777
1776
 
1778
- entry.ctime.seconds = (git_time_t)ntohl(source->ctime.seconds);
1779
- entry.ctime.nanoseconds = ntohl(source->ctime.nanoseconds);
1780
- entry.mtime.seconds = (git_time_t)ntohl(source->mtime.seconds);
1781
- entry.mtime.nanoseconds = ntohl(source->mtime.nanoseconds);
1782
- entry.dev = ntohl(source->dev);
1783
- entry.ino = ntohl(source->ino);
1784
- entry.mode = ntohl(source->mode);
1785
- entry.uid = ntohl(source->uid);
1786
- entry.gid = ntohl(source->gid);
1787
- entry.file_size = ntohl(source->file_size);
1788
- git_oid_cpy(&entry.id, &source->oid);
1789
- entry.flags = ntohs(source->flags);
1777
+ /* buffer is not guaranteed to be aligned */
1778
+ memcpy(&source, buffer, sizeof(struct entry_short));
1779
+
1780
+ entry.ctime.seconds = (git_time_t)ntohl(source.ctime.seconds);
1781
+ entry.ctime.nanoseconds = ntohl(source.ctime.nanoseconds);
1782
+ entry.mtime.seconds = (git_time_t)ntohl(source.mtime.seconds);
1783
+ entry.mtime.nanoseconds = ntohl(source.mtime.nanoseconds);
1784
+ entry.dev = ntohl(source.dev);
1785
+ entry.ino = ntohl(source.ino);
1786
+ entry.mode = ntohl(source.mode);
1787
+ entry.uid = ntohl(source.uid);
1788
+ entry.gid = ntohl(source.gid);
1789
+ entry.file_size = ntohl(source.file_size);
1790
+ git_oid_cpy(&entry.id, &source.oid);
1791
+ entry.flags = ntohs(source.flags);
1790
1792
 
1791
1793
  if (entry.flags & GIT_IDXENTRY_EXTENDED) {
1792
- const struct entry_long *source_l = (const struct entry_long *)source;
1793
- path_ptr = source_l->path;
1794
+ uint16_t flags_raw;
1795
+ size_t flags_offset;
1794
1796
 
1795
- flags_raw = ntohs(source_l->flags_extended);
1796
- memcpy(&entry.flags_extended, &flags_raw, 2);
1797
+ flags_offset = offsetof(struct entry_long, flags_extended);
1798
+ memcpy(&flags_raw, (const char *) buffer + flags_offset,
1799
+ sizeof(flags_raw));
1800
+ flags_raw = ntohs(flags_raw);
1801
+
1802
+ memcpy(&entry.flags_extended, &flags_raw, sizeof(flags_raw));
1803
+ path_ptr = (const char *) buffer + offsetof(struct entry_long, path);
1797
1804
  } else
1798
- path_ptr = source->path;
1805
+ path_ptr = (const char *) buffer + offsetof(struct entry_short, path);
1799
1806
 
1800
1807
  path_length = entry.flags & GIT_IDXENTRY_NAMEMASK;
1801
1808
 
@@ -1846,14 +1853,12 @@ static int read_header(struct index_header *dest, const void *buffer)
1846
1853
 
1847
1854
  static size_t read_extension(git_index *index, const char *buffer, size_t buffer_size)
1848
1855
  {
1849
- const struct index_extension *source;
1850
1856
  struct index_extension dest;
1851
1857
  size_t total_size;
1852
1858
 
1853
- source = (const struct index_extension *)(buffer);
1854
-
1855
- memcpy(dest.signature, source->signature, 4);
1856
- dest.extension_size = ntohl(source->extension_size);
1859
+ /* buffer is not guaranteed to be aligned */
1860
+ memcpy(&dest, buffer, sizeof(struct index_extension));
1861
+ dest.extension_size = ntohl(dest.extension_size);
1857
1862
 
1858
1863
  total_size = dest.extension_size + sizeof(struct index_extension);
1859
1864
 
@@ -18,8 +18,6 @@
18
18
  #include "oidmap.h"
19
19
  #include "zstream.h"
20
20
 
21
- extern git_mutex git__mwindow_mutex;
22
-
23
21
  #define UINT31_MAX (0x7FFFFFFF)
24
22
 
25
23
  struct entry {
@@ -455,7 +453,7 @@ static int append_to_pack(git_indexer *idx, const void *data, size_t size)
455
453
 
456
454
  /* add the extra space we need at the end */
457
455
  if (p_ftruncate(idx->pack->mwf.fd, current_size + size) < 0) {
458
- giterr_system_set(errno);
456
+ giterr_set(GITERR_OS, "Failed to increase size of pack file '%s'", idx->pack->pack_name);
459
457
  return -1;
460
458
  }
461
459
 
@@ -1046,11 +1044,6 @@ void git_indexer_free(git_indexer *idx)
1046
1044
  }
1047
1045
 
1048
1046
  git_vector_free_deep(&idx->deltas);
1049
-
1050
- if (!git_mutex_lock(&git__mwindow_mutex)) {
1051
- git_packfile_free(idx->pack);
1052
- git_mutex_unlock(&git__mwindow_mutex);
1053
- }
1054
-
1047
+ git_packfile_free(idx->pack);
1055
1048
  git__free(idx);
1056
1049
  }
@@ -2342,7 +2342,6 @@ done:
2342
2342
 
2343
2343
  static int merge_check_workdir(size_t *conflicts, git_repository *repo, git_index *index_new, git_vector *merged_paths)
2344
2344
  {
2345
- git_index *index_repo = NULL;
2346
2345
  git_diff *wd_diff_list = NULL;
2347
2346
  git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
2348
2347
  int error = 0;
@@ -2351,6 +2350,16 @@ static int merge_check_workdir(size_t *conflicts, git_repository *repo, git_inde
2351
2350
 
2352
2351
  *conflicts = 0;
2353
2352
 
2353
+ /* We need to have merged at least 1 file for the possibility to exist to
2354
+ * have conflicts with the workdir. Passing 0 as the pathspec count paramter
2355
+ * will consider all files in the working directory, that is, we may detect
2356
+ * a conflict if there were untracked files in the workdir prior to starting
2357
+ * the merge. This typically happens when cherry-picking a commmit whose
2358
+ * changes have already been applied.
2359
+ */
2360
+ if (merged_paths->length == 0)
2361
+ return 0;
2362
+
2354
2363
  opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
2355
2364
 
2356
2365
  /* Workdir changes may exist iff they do not conflict with changes that
@@ -2360,13 +2369,12 @@ static int merge_check_workdir(size_t *conflicts, git_repository *repo, git_inde
2360
2369
  opts.pathspec.count = merged_paths->length;
2361
2370
  opts.pathspec.strings = (char **)merged_paths->contents;
2362
2371
 
2363
- if ((error = git_diff_index_to_workdir(&wd_diff_list, repo, index_repo, &opts)) < 0)
2372
+ if ((error = git_diff_index_to_workdir(&wd_diff_list, repo, NULL, &opts)) < 0)
2364
2373
  goto done;
2365
2374
 
2366
2375
  *conflicts = wd_diff_list->deltas.length;
2367
2376
 
2368
2377
  done:
2369
- git_index_free(index_repo);
2370
2378
  git_diff_free(wd_diff_list);
2371
2379
 
2372
2380
  return error;