rugged 0.27.7 → 0.27.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/CMakeLists.txt +6 -2
  4. data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.c.in +29 -0
  5. data/vendor/libgit2/cmake/Modules/CheckPrototypeDefinition.cmake +96 -0
  6. data/vendor/libgit2/cmake/Modules/FindIconv.cmake +11 -6
  7. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +0 -2
  8. data/vendor/libgit2/include/git2.h +0 -1
  9. data/vendor/libgit2/include/git2/attr.h +7 -18
  10. data/vendor/libgit2/include/git2/blame.h +22 -39
  11. data/vendor/libgit2/include/git2/blob.h +1 -1
  12. data/vendor/libgit2/include/git2/branch.h +1 -1
  13. data/vendor/libgit2/include/git2/buffer.h +2 -14
  14. data/vendor/libgit2/include/git2/checkout.h +12 -13
  15. data/vendor/libgit2/include/git2/cherrypick.h +4 -6
  16. data/vendor/libgit2/include/git2/clone.h +6 -8
  17. data/vendor/libgit2/include/git2/commit.h +0 -28
  18. data/vendor/libgit2/include/git2/common.h +0 -27
  19. data/vendor/libgit2/include/git2/config.h +0 -1
  20. data/vendor/libgit2/include/git2/describe.h +7 -30
  21. data/vendor/libgit2/include/git2/diff.h +22 -32
  22. data/vendor/libgit2/include/git2/errors.h +0 -1
  23. data/vendor/libgit2/include/git2/ignore.h +2 -2
  24. data/vendor/libgit2/include/git2/merge.h +8 -10
  25. data/vendor/libgit2/include/git2/proxy.h +5 -9
  26. data/vendor/libgit2/include/git2/rebase.h +4 -7
  27. data/vendor/libgit2/include/git2/refs.h +1 -1
  28. data/vendor/libgit2/include/git2/refspec.h +0 -17
  29. data/vendor/libgit2/include/git2/remote.h +10 -12
  30. data/vendor/libgit2/include/git2/repository.h +5 -7
  31. data/vendor/libgit2/include/git2/revert.h +3 -5
  32. data/vendor/libgit2/include/git2/stash.h +8 -11
  33. data/vendor/libgit2/include/git2/status.h +3 -7
  34. data/vendor/libgit2/include/git2/submodule.h +7 -8
  35. data/vendor/libgit2/include/git2/sys/index.h +0 -3
  36. data/vendor/libgit2/include/git2/sys/mempack.h +35 -35
  37. data/vendor/libgit2/include/git2/sys/merge.h +1 -6
  38. data/vendor/libgit2/include/git2/transaction.h +0 -1
  39. data/vendor/libgit2/include/git2/types.h +5 -8
  40. data/vendor/libgit2/include/git2/version.h +2 -2
  41. data/vendor/libgit2/include/git2/worktree.h +11 -46
  42. data/vendor/libgit2/src/CMakeLists.txt +28 -91
  43. data/vendor/libgit2/src/annotated_commit.c +4 -4
  44. data/vendor/libgit2/src/apply.c +6 -5
  45. data/vendor/libgit2/src/attr.c +4 -4
  46. data/vendor/libgit2/src/attr_file.c +5 -5
  47. data/vendor/libgit2/src/attrcache.c +2 -2
  48. data/vendor/libgit2/src/blame.c +4 -11
  49. data/vendor/libgit2/src/blame.h +0 -1
  50. data/vendor/libgit2/src/blame_git.c +5 -8
  51. data/vendor/libgit2/src/blob.c +5 -5
  52. data/vendor/libgit2/src/branch.c +20 -20
  53. data/vendor/libgit2/src/buffer.c +4 -9
  54. data/vendor/libgit2/src/buffer.h +1 -1
  55. data/vendor/libgit2/src/checkout.c +24 -33
  56. data/vendor/libgit2/src/cherrypick.c +3 -3
  57. data/vendor/libgit2/src/clone.c +13 -13
  58. data/vendor/libgit2/src/commit.c +5 -18
  59. data/vendor/libgit2/src/commit_list.c +9 -3
  60. data/vendor/libgit2/src/common.h +1 -3
  61. data/vendor/libgit2/src/config.c +15 -6
  62. data/vendor/libgit2/src/config_file.c +249 -193
  63. data/vendor/libgit2/src/config_parse.c +66 -89
  64. data/vendor/libgit2/src/config_parse.h +2 -2
  65. data/vendor/libgit2/src/crlf.c +3 -9
  66. data/vendor/libgit2/src/diff.c +2 -2
  67. data/vendor/libgit2/src/diff_driver.c +3 -3
  68. data/vendor/libgit2/src/diff_file.c +3 -3
  69. data/vendor/libgit2/src/diff_generate.c +3 -4
  70. data/vendor/libgit2/src/diff_print.c +8 -8
  71. data/vendor/libgit2/src/diff_tform.c +4 -2
  72. data/vendor/libgit2/src/diff_xdiff.c +0 -12
  73. data/vendor/libgit2/src/features.h.in +0 -2
  74. data/vendor/libgit2/src/fetch.c +2 -2
  75. data/vendor/libgit2/src/fetchhead.c +5 -5
  76. data/vendor/libgit2/src/filebuf.c +4 -4
  77. data/vendor/libgit2/src/fileops.c +10 -10
  78. data/vendor/libgit2/src/filter.c +9 -3
  79. data/vendor/libgit2/src/global.c +12 -17
  80. data/vendor/libgit2/src/hash.h +0 -2
  81. data/vendor/libgit2/src/ignore.c +5 -5
  82. data/vendor/libgit2/src/index.c +40 -80
  83. data/vendor/libgit2/src/index.h +0 -10
  84. data/vendor/libgit2/src/indexer.c +9 -9
  85. data/vendor/libgit2/src/iterator.c +8 -8
  86. data/vendor/libgit2/src/khash.h +1 -3
  87. data/vendor/libgit2/src/merge.c +7 -7
  88. data/vendor/libgit2/src/netops.c +5 -5
  89. data/vendor/libgit2/src/notes.c +2 -2
  90. data/vendor/libgit2/src/odb.c +9 -9
  91. data/vendor/libgit2/src/odb_loose.c +22 -18
  92. data/vendor/libgit2/src/odb_pack.c +3 -3
  93. data/vendor/libgit2/src/pack-objects.c +3 -3
  94. data/vendor/libgit2/src/pack.c +5 -5
  95. data/vendor/libgit2/src/pack.h +1 -1
  96. data/vendor/libgit2/src/parse.c +7 -4
  97. data/vendor/libgit2/src/patch.c +1 -1
  98. data/vendor/libgit2/src/patch_generate.c +2 -2
  99. data/vendor/libgit2/src/patch_parse.c +4 -24
  100. data/vendor/libgit2/src/path.c +140 -39
  101. data/vendor/libgit2/src/path.h +84 -2
  102. data/vendor/libgit2/src/pathspec.c +1 -1
  103. data/vendor/libgit2/src/push.c +2 -2
  104. data/vendor/libgit2/src/rebase.c +23 -20
  105. data/vendor/libgit2/src/refdb_fs.c +34 -65
  106. data/vendor/libgit2/src/refs.c +16 -13
  107. data/vendor/libgit2/src/refspec.c +5 -30
  108. data/vendor/libgit2/src/refspec.h +1 -1
  109. data/vendor/libgit2/src/remote.c +43 -43
  110. data/vendor/libgit2/src/repository.c +56 -56
  111. data/vendor/libgit2/src/reset.c +1 -1
  112. data/vendor/libgit2/src/revert.c +3 -3
  113. data/vendor/libgit2/src/revparse.c +7 -6
  114. data/vendor/libgit2/src/revwalk.c +20 -48
  115. data/vendor/libgit2/src/revwalk.h +1 -2
  116. data/vendor/libgit2/src/settings.c +1 -25
  117. data/vendor/libgit2/src/signature.c +4 -2
  118. data/vendor/libgit2/src/stash.c +34 -80
  119. data/vendor/libgit2/src/status.c +1 -1
  120. data/vendor/libgit2/src/streams/curl.c +1 -1
  121. data/vendor/libgit2/src/streams/openssl.c +34 -132
  122. data/vendor/libgit2/src/streams/openssl.h +107 -0
  123. data/vendor/libgit2/src/streams/tls.c +0 -3
  124. data/vendor/libgit2/src/submodule.c +83 -118
  125. data/vendor/libgit2/src/sysdir.c +4 -4
  126. data/vendor/libgit2/src/tag.c +12 -12
  127. data/vendor/libgit2/src/trace.h +1 -1
  128. data/vendor/libgit2/src/trailer.c +6 -6
  129. data/vendor/libgit2/src/transport.c +2 -2
  130. data/vendor/libgit2/src/transports/auth.c +1 -1
  131. data/vendor/libgit2/src/transports/auth_negotiate.c +2 -2
  132. data/vendor/libgit2/src/transports/git.c +1 -1
  133. data/vendor/libgit2/src/transports/http.c +15 -12
  134. data/vendor/libgit2/src/transports/local.c +7 -7
  135. data/vendor/libgit2/src/transports/smart.c +15 -20
  136. data/vendor/libgit2/src/transports/smart.h +5 -5
  137. data/vendor/libgit2/src/transports/smart_pkt.c +131 -123
  138. data/vendor/libgit2/src/transports/smart_protocol.c +38 -48
  139. data/vendor/libgit2/src/transports/ssh.c +1 -1
  140. data/vendor/libgit2/src/transports/winhttp.c +26 -21
  141. data/vendor/libgit2/src/tree-cache.c +2 -2
  142. data/vendor/libgit2/src/tree.c +69 -23
  143. data/vendor/libgit2/src/tree.h +12 -0
  144. data/vendor/libgit2/src/util.c +99 -52
  145. data/vendor/libgit2/src/util.h +138 -14
  146. data/vendor/libgit2/src/vector.c +13 -8
  147. data/vendor/libgit2/src/win32/findfile.c +2 -2
  148. data/vendor/libgit2/src/win32/posix_w32.c +1 -1
  149. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +0 -94
  150. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +75 -28
  151. data/vendor/libgit2/src/worktree.c +44 -65
  152. data/vendor/libgit2/src/worktree.h +0 -2
  153. data/vendor/libgit2/src/xdiff/xdiffi.c +1 -3
  154. metadata +5 -17
  155. data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +0 -93
  156. data/vendor/libgit2/include/git2/mailmap.h +0 -115
  157. data/vendor/libgit2/include/git2/sys/alloc.h +0 -101
  158. data/vendor/libgit2/include/git2/sys/path.h +0 -55
  159. data/vendor/libgit2/src/alloc.c +0 -47
  160. data/vendor/libgit2/src/alloc.h +0 -40
  161. data/vendor/libgit2/src/hash/hash_mbedtls.c +0 -38
  162. data/vendor/libgit2/src/hash/hash_mbedtls.h +0 -20
  163. data/vendor/libgit2/src/mailmap.c +0 -485
  164. data/vendor/libgit2/src/mailmap.h +0 -35
  165. data/vendor/libgit2/src/stdalloc.c +0 -120
  166. data/vendor/libgit2/src/stdalloc.h +0 -17
  167. data/vendor/libgit2/src/streams/mbedtls.c +0 -463
  168. data/vendor/libgit2/src/streams/mbedtls.h +0 -20
@@ -11,7 +11,6 @@
11
11
  #include "git2/object.h"
12
12
  #include "git2/repository.h"
13
13
  #include "git2/signature.h"
14
- #include "git2/mailmap.h"
15
14
  #include "git2/sys/commit.h"
16
15
 
17
16
  #include "odb.h"
@@ -75,7 +74,7 @@ static int git_commit__create_buffer_internal(
75
74
  return 0;
76
75
 
77
76
  on_error:
78
- git_buf_dispose(out);
77
+ git_buf_free(out);
79
78
  return -1;
80
79
  }
81
80
 
@@ -177,7 +176,7 @@ static int git_commit__create_internal(
177
176
  cleanup:
178
177
  git_array_clear(parents);
179
178
  git_reference_free(ref);
180
- git_buf_dispose(&buf);
179
+ git_buf_free(&buf);
181
180
  return error;
182
181
  }
183
182
 
@@ -420,7 +419,7 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj)
420
419
  return -1;
421
420
 
422
421
  /* Some tools create multiple author fields, ignore the extra ones */
423
- while ((size_t)(buffer_end - buffer) >= strlen("author ") && !git__prefixcmp(buffer, "author ")) {
422
+ while (!git__prefixncmp(buffer, buffer_end - buffer, "author ")) {
424
423
  if (git_signature__parse(&dummy_sig, &buffer, buffer_end, "author ", '\n') < 0)
425
424
  return -1;
426
425
 
@@ -444,7 +443,7 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj)
444
443
  while (eoln < buffer_end && *eoln != '\n')
445
444
  ++eoln;
446
445
 
447
- if (git__prefixcmp(buffer, "encoding ") == 0) {
446
+ if (git__prefixncmp(buffer, buffer_end - buffer, "encoding ") == 0) {
448
447
  buffer += strlen("encoding ");
449
448
 
450
449
  commit->message_encoding = git__strndup(buffer, eoln - buffer);
@@ -887,18 +886,6 @@ int git_commit_create_with_signature(
887
886
  goto cleanup;
888
887
 
889
888
  cleanup:
890
- git_buf_dispose(&commit);
889
+ git_buf_free(&commit);
891
890
  return error;
892
891
  }
893
-
894
- int git_commit_committer_with_mailmap(
895
- git_signature **out, const git_commit *commit, const git_mailmap *mailmap)
896
- {
897
- return git_mailmap_resolve_signature(out, mailmap, commit->committer);
898
- }
899
-
900
- int git_commit_author_with_mailmap(
901
- git_signature **out, const git_commit *commit, const git_mailmap *mailmap)
902
- {
903
- return git_mailmap_resolve_signature(out, mailmap, commit->author);
904
- }
@@ -69,11 +69,15 @@ static int commit_error(git_commit_list_node *commit, const char *msg)
69
69
  static git_commit_list_node **alloc_parents(
70
70
  git_revwalk *walk, git_commit_list_node *commit, size_t n_parents)
71
71
  {
72
+ size_t bytes;
73
+
72
74
  if (n_parents <= PARENTS_PER_COMMIT)
73
75
  return (git_commit_list_node **)((char *)commit + sizeof(git_commit_list_node));
74
76
 
75
- return (git_commit_list_node **)git_pool_malloc(
76
- &walk->commit_pool, (uint32_t)(n_parents * sizeof(git_commit_list_node *)));
77
+ if (git__multiply_sizet_overflow(&bytes, n_parents, sizeof(git_commit_list_node *)))
78
+ return NULL;
79
+
80
+ return (git_commit_list_node **)git_pool_malloc(&walk->commit_pool, bytes);
77
81
  }
78
82
 
79
83
 
@@ -171,7 +175,9 @@ static int commit_quick_parse(
171
175
  buffer--;
172
176
  }
173
177
 
174
- if ((buffer == committer_start) || (git__strtol64(&commit_time, (char *)(buffer + 1), NULL, 10) < 0))
178
+ if ((buffer == committer_start) ||
179
+ (git__strntol64(&commit_time, (char *)(buffer + 1),
180
+ buffer_end - buffer + 1, NULL, 10) < 0))
175
181
  return commit_error(commit, "cannot parse commit time");
176
182
 
177
183
  commit->time = commit_time;
@@ -17,10 +17,8 @@
17
17
  /** Declare a function as always inlined. */
18
18
  #if defined(_MSC_VER)
19
19
  # define GIT_INLINE(type) static __inline type
20
- #elif defined(__GNUC__)
21
- # define GIT_INLINE(type) static __inline__ type
22
20
  #else
23
- # define GIT_INLINE(type) static type
21
+ # define GIT_INLINE(type) static inline type
24
22
  #endif
25
23
 
26
24
  /** Support for gcc/clang __has_builtin intrinsic */
@@ -109,7 +109,7 @@ int git_config_add_file_ondisk(
109
109
  assert(cfg && path);
110
110
 
111
111
  res = p_stat(path, &st);
112
- if (res < 0 && errno != ENOENT) {
112
+ if (res < 0 && errno != ENOENT && errno != ENOTDIR) {
113
113
  giterr_set(GITERR_CONFIG, "failed to stat '%s'", path);
114
114
  return -1;
115
115
  }
@@ -513,6 +513,8 @@ int git_config_backend_foreach_match(
513
513
  regex_t regex;
514
514
  int error = 0;
515
515
 
516
+ assert(backend && cb);
517
+
516
518
  if (regexp != NULL) {
517
519
  if ((error = p_regcomp(&regex, regexp, REG_EXTENDED)) != 0) {
518
520
  giterr_set_regex(&regex, error);
@@ -1109,8 +1111,15 @@ int git_config_find_system(git_buf *path)
1109
1111
 
1110
1112
  int git_config_find_programdata(git_buf *path)
1111
1113
  {
1114
+ int ret;
1115
+
1112
1116
  git_buf_sanitize(path);
1113
- return git_sysdir_find_programdata_file(path, GIT_CONFIG_FILENAME_PROGRAMDATA);
1117
+ ret = git_sysdir_find_programdata_file(path,
1118
+ GIT_CONFIG_FILENAME_PROGRAMDATA);
1119
+ if (ret != GIT_OK)
1120
+ return ret;
1121
+
1122
+ return git_path_validate_system_file_ownership(path->ptr);
1114
1123
  }
1115
1124
 
1116
1125
  int git_config__global_location(git_buf *buf)
@@ -1164,7 +1173,7 @@ int git_config_open_default(git_config **out)
1164
1173
  error = git_config_add_file_ondisk(cfg, buf.ptr,
1165
1174
  GIT_CONFIG_LEVEL_PROGRAMDATA, NULL, 0);
1166
1175
 
1167
- git_buf_dispose(&buf);
1176
+ git_buf_free(&buf);
1168
1177
 
1169
1178
  if (error) {
1170
1179
  git_config_free(cfg);
@@ -1300,7 +1309,7 @@ int git_config_parse_int64(int64_t *out, const char *value)
1300
1309
  const char *num_end;
1301
1310
  int64_t num;
1302
1311
 
1303
- if (!value || git__strtol64(&num, value, &num_end, 0) < 0)
1312
+ if (!value || git__strntol64(&num, value, strlen(value), &num_end, 0) < 0)
1304
1313
  goto fail_parse;
1305
1314
 
1306
1315
  switch (*num_end) {
@@ -1478,8 +1487,8 @@ int git_config_rename_section(
1478
1487
  config, git_buf_cstr(&pattern), rename_config_entries_cb, &data);
1479
1488
 
1480
1489
  cleanup:
1481
- git_buf_dispose(&pattern);
1482
- git_buf_dispose(&replace);
1490
+ git_buf_free(&pattern);
1491
+ git_buf_free(&replace);
1483
1492
 
1484
1493
  return error;
1485
1494
  }
@@ -23,30 +23,69 @@
23
23
  #include <sys/types.h>
24
24
  #include <regex.h>
25
25
 
26
- typedef struct config_entry_list {
27
- struct config_entry_list *next;
26
+ typedef struct cvar_t {
27
+ struct cvar_t *next;
28
28
  git_config_entry *entry;
29
- } config_entry_list;
29
+ bool included; /* whether this is part of [include] */
30
+ } cvar_t;
30
31
 
31
32
  typedef struct git_config_file_iter {
32
33
  git_config_iterator parent;
33
- config_entry_list *head;
34
+ git_strmap_iter iter;
35
+ cvar_t* next_var;
34
36
  } git_config_file_iter;
35
37
 
36
38
  /* Max depth for [include] directives */
37
39
  #define MAX_INCLUDE_DEPTH 10
38
40
 
41
+ #define CVAR_LIST_HEAD(list) ((list)->head)
42
+
43
+ #define CVAR_LIST_TAIL(list) ((list)->tail)
44
+
45
+ #define CVAR_LIST_NEXT(var) ((var)->next)
46
+
47
+ #define CVAR_LIST_EMPTY(list) ((list)->head == NULL)
48
+
49
+ #define CVAR_LIST_APPEND(list, var) do {\
50
+ if (CVAR_LIST_EMPTY(list)) {\
51
+ CVAR_LIST_HEAD(list) = CVAR_LIST_TAIL(list) = var;\
52
+ } else {\
53
+ CVAR_LIST_NEXT(CVAR_LIST_TAIL(list)) = var;\
54
+ CVAR_LIST_TAIL(list) = var;\
55
+ }\
56
+ } while(0)
57
+
58
+ #define CVAR_LIST_REMOVE_HEAD(list) do {\
59
+ CVAR_LIST_HEAD(list) = CVAR_LIST_NEXT(CVAR_LIST_HEAD(list));\
60
+ } while(0)
61
+
62
+ #define CVAR_LIST_REMOVE_AFTER(var) do {\
63
+ CVAR_LIST_NEXT(var) = CVAR_LIST_NEXT(CVAR_LIST_NEXT(var));\
64
+ } while(0)
65
+
66
+ #define CVAR_LIST_FOREACH(list, iter)\
67
+ for ((iter) = CVAR_LIST_HEAD(list);\
68
+ (iter) != NULL;\
69
+ (iter) = CVAR_LIST_NEXT(iter))
70
+
71
+ /*
72
+ * Inspired by the FreeBSD functions
73
+ */
74
+ #define CVAR_LIST_FOREACH_SAFE(start, iter, tmp)\
75
+ for ((iter) = CVAR_LIST_HEAD(vars);\
76
+ (iter) && (((tmp) = CVAR_LIST_NEXT(iter) || 1));\
77
+ (iter) = (tmp))
78
+
39
79
  typedef struct {
40
80
  git_atomic refcount;
41
- git_strmap *map;
42
- config_entry_list *list;
43
- } diskfile_entries;
81
+ git_strmap *values;
82
+ } refcounted_strmap;
44
83
 
45
84
  typedef struct {
46
85
  git_config_backend parent;
47
86
  /* mutex to coordinate accessing the values */
48
87
  git_mutex values_mutex;
49
- diskfile_entries *entries;
88
+ refcounted_strmap *values;
50
89
  const git_repository *repo;
51
90
  git_config_level_t level;
52
91
  } diskfile_header;
@@ -69,15 +108,7 @@ typedef struct {
69
108
  diskfile_backend *snapshot_from;
70
109
  } diskfile_readonly_backend;
71
110
 
72
- typedef struct {
73
- const git_repository *repo;
74
- const char *file_path;
75
- diskfile_entries *entries;
76
- git_config_level_t level;
77
- unsigned int depth;
78
- } diskfile_parse_state;
79
-
80
- static int config_read(diskfile_entries *entries, const git_repository *repo, git_config_file *file, git_config_level_t level, int depth);
111
+ static int config_read(git_strmap *values, const git_repository *repo, git_config_file *file, git_config_level_t level, int depth);
81
112
  static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const regex_t *preg, const char *value);
82
113
  static char *escape_value(const char *ptr);
83
114
 
@@ -90,20 +121,15 @@ static int config_error_readonly(void)
90
121
  return -1;
91
122
  }
92
123
 
93
- static void config_entry_list_free(config_entry_list *list)
124
+ static void cvar_free(cvar_t *var)
94
125
  {
95
- config_entry_list *next;
96
-
97
- while (list != NULL) {
98
- next = list->next;
99
-
100
- git__free((char*) list->entry->name);
101
- git__free((char *) list->entry->value);
102
- git__free(list->entry);
103
- git__free(list);
126
+ if (var == NULL)
127
+ return;
104
128
 
105
- list = next;
106
- };
129
+ git__free((char*)var->entry->name);
130
+ git__free((char *)var->entry->value);
131
+ git__free(var->entry);
132
+ git__free(var);
107
133
  }
108
134
 
109
135
  int git_config_file_normalize_section(char *start, char *end)
@@ -129,70 +155,57 @@ int git_config_file_normalize_section(char *start, char *end)
129
155
  return 0;
130
156
  }
131
157
 
132
- static void config_entry_list_append(config_entry_list **list, config_entry_list *entry)
133
- {
134
- config_entry_list *head = *list;
135
-
136
- if (head) {
137
- while (head->next != NULL)
138
- head = head->next;
139
- head->next = entry;
140
- } else {
141
- *list = entry;
142
- }
143
- }
144
-
145
158
  /* Add or append the new config option */
146
- static int diskfile_entries_append(diskfile_entries *entries, git_config_entry *entry)
159
+ static int append_entry(git_strmap *values, cvar_t *var)
147
160
  {
148
161
  git_strmap_iter pos;
149
- config_entry_list *existing, *var;
162
+ cvar_t *existing;
150
163
  int error = 0;
151
164
 
152
- var = git__calloc(1, sizeof(config_entry_list));
153
- GITERR_CHECK_ALLOC(var);
154
- var->entry = entry;
155
-
156
- pos = git_strmap_lookup_index(entries->map, entry->name);
157
- if (!git_strmap_valid_index(entries->map, pos)) {
158
- git_strmap_insert(entries->map, entry->name, var, &error);
159
-
160
- if (error > 0)
161
- error = 0;
165
+ pos = git_strmap_lookup_index(values, var->entry->name);
166
+ if (!git_strmap_valid_index(values, pos)) {
167
+ git_strmap_insert(values, var->entry->name, var, &error);
162
168
  } else {
163
- existing = git_strmap_value_at(entries->map, pos);
164
- config_entry_list_append(&existing, var);
169
+ existing = git_strmap_value_at(values, pos);
170
+ while (existing->next != NULL) {
171
+ existing = existing->next;
172
+ }
173
+ existing->next = var;
165
174
  }
166
175
 
167
- var = git__calloc(1, sizeof(config_entry_list));
168
- GITERR_CHECK_ALLOC(var);
169
- var->entry = entry;
170
- config_entry_list_append(&entries->list, var);
176
+ if (error > 0)
177
+ error = 0;
171
178
 
172
179
  return error;
173
180
  }
174
181
 
175
- static void diskfile_entries_free(diskfile_entries *entries)
182
+ static void free_vars(git_strmap *values)
176
183
  {
177
- config_entry_list *list = NULL, *next;
184
+ cvar_t *var = NULL;
178
185
 
179
- if (!entries)
186
+ if (values == NULL)
180
187
  return;
181
188
 
182
- if (git_atomic_dec(&entries->refcount) != 0)
183
- return;
189
+ git_strmap_foreach_value(values, var,
190
+ while (var != NULL) {
191
+ cvar_t *next = CVAR_LIST_NEXT(var);
192
+ cvar_free(var);
193
+ var = next;
194
+ });
184
195
 
185
- git_strmap_foreach_value(entries->map, list, config_entry_list_free(list));
186
- git_strmap_free(entries->map);
196
+ git_strmap_free(values);
197
+ }
187
198
 
188
- list = entries->list;
189
- while (list != NULL) {
190
- next = list->next;
191
- git__free(list);
192
- list = next;
193
- }
199
+ static void refcounted_strmap_free(refcounted_strmap *map)
200
+ {
201
+ if (!map)
202
+ return;
194
203
 
195
- git__free(entries);
204
+ if (git_atomic_dec(&map->refcount) != 0)
205
+ return;
206
+
207
+ free_vars(map->values);
208
+ git__free(map);
196
209
  }
197
210
 
198
211
  /**
@@ -200,37 +213,37 @@ static void diskfile_entries_free(diskfile_entries *entries)
200
213
  * refcount. This is its own function to make sure we use the mutex to
201
214
  * avoid the map pointer from changing under us.
202
215
  */
203
- static diskfile_entries *diskfile_entries_take(diskfile_header *h)
216
+ static refcounted_strmap *refcounted_strmap_take(diskfile_header *h)
204
217
  {
205
- diskfile_entries *entries;
218
+ refcounted_strmap *map;
206
219
 
207
220
  if (git_mutex_lock(&h->values_mutex) < 0) {
208
221
  giterr_set(GITERR_OS, "failed to lock config backend");
209
222
  return NULL;
210
223
  }
211
224
 
212
- entries = h->entries;
213
- git_atomic_inc(&entries->refcount);
225
+ map = h->values;
226
+ git_atomic_inc(&map->refcount);
214
227
 
215
228
  git_mutex_unlock(&h->values_mutex);
216
229
 
217
- return entries;
230
+ return map;
218
231
  }
219
232
 
220
- static int diskfile_entries_alloc(diskfile_entries **out)
233
+ static int refcounted_strmap_alloc(refcounted_strmap **out)
221
234
  {
222
- diskfile_entries *entries;
235
+ refcounted_strmap *map;
223
236
  int error;
224
237
 
225
- entries = git__calloc(1, sizeof(diskfile_entries));
226
- GITERR_CHECK_ALLOC(entries);
238
+ map = git__calloc(1, sizeof(refcounted_strmap));
239
+ GITERR_CHECK_ALLOC(map);
227
240
 
228
- git_atomic_set(&entries->refcount, 1);
241
+ git_atomic_set(&map->refcount, 1);
229
242
 
230
- if ((error = git_strmap_alloc(&entries->map)) < 0)
231
- git__free(entries);
243
+ if ((error = git_strmap_alloc(&map->values)) < 0)
244
+ git__free(map);
232
245
  else
233
- *out = entries;
246
+ *out = map;
234
247
 
235
248
  return error;
236
249
  }
@@ -259,15 +272,15 @@ static int config_open(git_config_backend *cfg, git_config_level_t level, const
259
272
  b->header.level = level;
260
273
  b->header.repo = repo;
261
274
 
262
- if ((res = diskfile_entries_alloc(&b->header.entries)) < 0)
275
+ if ((res = refcounted_strmap_alloc(&b->header.values)) < 0)
263
276
  return res;
264
277
 
265
278
  if (!git_path_exists(b->file.path))
266
279
  return 0;
267
280
 
268
- if (res < 0 || (res = config_read(b->header.entries, repo, &b->file, level, 0)) < 0) {
269
- diskfile_entries_free(b->header.entries);
270
- b->header.entries = NULL;
281
+ if (res < 0 || (res = config_read(b->header.values->values, repo, &b->file, level, 0)) < 0) {
282
+ refcounted_strmap_free(b->header.values);
283
+ b->header.values = NULL;
271
284
  }
272
285
 
273
286
  return res;
@@ -300,7 +313,7 @@ static int config_is_modified(int *modified, struct config_file *file)
300
313
  }
301
314
 
302
315
  out:
303
- git_buf_dispose(&buf);
316
+ git_buf_free(&buf);
304
317
 
305
318
  return error;
306
319
  }
@@ -308,7 +321,7 @@ out:
308
321
  static int config_refresh(git_config_backend *cfg)
309
322
  {
310
323
  diskfile_backend *b = (diskfile_backend *)cfg;
311
- diskfile_entries *entries = NULL, *tmp;
324
+ refcounted_strmap *values = NULL, *tmp;
312
325
  git_config_file *include;
313
326
  int error, modified;
314
327
  uint32_t i;
@@ -323,7 +336,7 @@ static int config_refresh(git_config_backend *cfg)
323
336
  if (!modified)
324
337
  return 0;
325
338
 
326
- if ((error = diskfile_entries_alloc(&entries)) < 0)
339
+ if ((error = refcounted_strmap_alloc(&values)) < 0)
327
340
  goto out;
328
341
 
329
342
  /* Reparse the current configuration */
@@ -332,7 +345,7 @@ static int config_refresh(git_config_backend *cfg)
332
345
  }
333
346
  git_array_clear(b->file.includes);
334
347
 
335
- if ((error = config_read(entries, b->header.repo, &b->file, b->header.level, 0)) < 0)
348
+ if ((error = config_read(values->values, b->header.repo, &b->file, b->header.level, 0)) < 0)
336
349
  goto out;
337
350
 
338
351
  if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
@@ -340,14 +353,14 @@ static int config_refresh(git_config_backend *cfg)
340
353
  goto out;
341
354
  }
342
355
 
343
- tmp = b->header.entries;
344
- b->header.entries = entries;
345
- entries = tmp;
356
+ tmp = b->header.values;
357
+ b->header.values = values;
358
+ values = tmp;
346
359
 
347
360
  git_mutex_unlock(&b->header.values_mutex);
348
361
 
349
362
  out:
350
- diskfile_entries_free(entries);
363
+ refcounted_strmap_free(values);
351
364
 
352
365
  return (error == GIT_ENOTFOUND) ? 0 : error;
353
366
  }
@@ -360,7 +373,7 @@ static void backend_free(git_config_backend *_backend)
360
373
  return;
361
374
 
362
375
  config_file_clear(&backend->file);
363
- diskfile_entries_free(backend->header.entries);
376
+ refcounted_strmap_free(backend->header.values);
364
377
  git_mutex_free(&backend->header.values_mutex);
365
378
  git__free(backend);
366
379
  }
@@ -377,12 +390,24 @@ static int config_iterator_next(
377
390
  git_config_iterator *iter)
378
391
  {
379
392
  git_config_file_iter *it = (git_config_file_iter *) iter;
393
+ diskfile_header *h = (diskfile_header *) it->parent.backend;
394
+ git_strmap *values = h->values->values;
395
+ int err = 0;
396
+ cvar_t * var;
380
397
 
381
- if (!it->head)
382
- return GIT_ITEROVER;
398
+ if (it->next_var == NULL) {
399
+ err = git_strmap_next((void**) &var, &(it->iter), values);
400
+ } else {
401
+ var = it->next_var;
402
+ }
383
403
 
384
- *entry = it->head->entry;
385
- it->head = it->head->next;
404
+ if (err < 0) {
405
+ it->next_var = NULL;
406
+ return err;
407
+ }
408
+
409
+ *entry = var->entry;
410
+ it->next_var = CVAR_LIST_NEXT(var);
386
411
 
387
412
  return 0;
388
413
  }
@@ -408,11 +433,15 @@ static int config_iterator_new(
408
433
 
409
434
  h = (diskfile_header *)snapshot;
410
435
 
436
+ /* strmap_begin() is currently a macro returning 0 */
437
+ GIT_UNUSED(h);
438
+
411
439
  it->parent.backend = snapshot;
412
- it->head = h->entries->list;
440
+ it->iter = git_strmap_begin(h->values);
441
+ it->next_var = NULL;
442
+
413
443
  it->parent.next = config_iterator_next;
414
444
  it->parent.free = config_iterator_free;
415
-
416
445
  *iter = (git_config_iterator *) it;
417
446
 
418
447
  return 0;
@@ -421,8 +450,8 @@ static int config_iterator_new(
421
450
  static int config_set(git_config_backend *cfg, const char *name, const char *value)
422
451
  {
423
452
  diskfile_backend *b = (diskfile_backend *)cfg;
424
- diskfile_entries *entries;
425
- git_strmap *entry_map;
453
+ refcounted_strmap *map;
454
+ git_strmap *values;
426
455
  char *key, *esc_value = NULL;
427
456
  khiter_t pos;
428
457
  int rval, ret;
@@ -430,17 +459,17 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
430
459
  if ((rval = git_config__normalize_name(name, &key)) < 0)
431
460
  return rval;
432
461
 
433
- if ((entries = diskfile_entries_take(&b->header)) == NULL)
462
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
434
463
  return -1;
435
- entry_map = entries->map;
464
+ values = map->values;
436
465
 
437
466
  /*
438
467
  * Try to find it in the existing values and update it if it
439
468
  * only has one value.
440
469
  */
441
- pos = git_strmap_lookup_index(entry_map, key);
442
- if (git_strmap_valid_index(entry_map, pos)) {
443
- config_entry_list *existing = git_strmap_value_at(entry_map, pos);
470
+ pos = git_strmap_lookup_index(values, key);
471
+ if (git_strmap_valid_index(values, pos)) {
472
+ cvar_t *existing = git_strmap_value_at(values, pos);
444
473
 
445
474
  if (existing->next != NULL) {
446
475
  giterr_set(GITERR_CONFIG, "multivar incompatible with simple set");
@@ -448,7 +477,7 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
448
477
  goto out;
449
478
  }
450
479
 
451
- if (existing->entry->include_depth) {
480
+ if (existing->included) {
452
481
  giterr_set(GITERR_CONFIG, "modifying included variable is not supported");
453
482
  ret = -1;
454
483
  goto out;
@@ -476,17 +505,17 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
476
505
  ret = config_refresh(cfg);
477
506
 
478
507
  out:
479
- diskfile_entries_free(entries);
508
+ refcounted_strmap_free(map);
480
509
  git__free(esc_value);
481
510
  git__free(key);
482
511
  return ret;
483
512
  }
484
513
 
485
514
  /* release the map containing the entry as an equivalent to freeing it */
486
- static void free_diskfile_entry(git_config_entry *entry)
515
+ static void release_map(git_config_entry *entry)
487
516
  {
488
- diskfile_entries *map = (diskfile_entries *) entry->payload;
489
- diskfile_entries_free(map);
517
+ refcounted_strmap *map = (refcounted_strmap *) entry->payload;
518
+ refcounted_strmap_free(map);
490
519
  }
491
520
 
492
521
  /*
@@ -495,34 +524,34 @@ static void free_diskfile_entry(git_config_entry *entry)
495
524
  static int config_get(git_config_backend *cfg, const char *key, git_config_entry **out)
496
525
  {
497
526
  diskfile_header *h = (diskfile_header *)cfg;
498
- diskfile_entries *entries;
499
- git_strmap *entry_map;
527
+ refcounted_strmap *map;
528
+ git_strmap *values;
500
529
  khiter_t pos;
501
- config_entry_list *var;
530
+ cvar_t *var;
502
531
  int error = 0;
503
532
 
504
533
  if (!h->parent.readonly && ((error = config_refresh(cfg)) < 0))
505
534
  return error;
506
535
 
507
- if ((entries = diskfile_entries_take(h)) == NULL)
536
+ if ((map = refcounted_strmap_take(h)) == NULL)
508
537
  return -1;
509
- entry_map = entries->map;
538
+ values = map->values;
510
539
 
511
- pos = git_strmap_lookup_index(entry_map, key);
540
+ pos = git_strmap_lookup_index(values, key);
512
541
 
513
542
  /* no error message; the config system will write one */
514
- if (!git_strmap_valid_index(entry_map, pos)) {
515
- diskfile_entries_free(entries);
543
+ if (!git_strmap_valid_index(values, pos)) {
544
+ refcounted_strmap_free(map);
516
545
  return GIT_ENOTFOUND;
517
546
  }
518
547
 
519
- var = git_strmap_value_at(entry_map, pos);
548
+ var = git_strmap_value_at(values, pos);
520
549
  while (var->next)
521
550
  var = var->next;
522
551
 
523
552
  *out = var->entry;
524
- (*out)->free = free_diskfile_entry;
525
- (*out)->payload = entries;
553
+ (*out)->free = release_map;
554
+ (*out)->payload = map;
526
555
 
527
556
  return error;
528
557
  }
@@ -562,10 +591,9 @@ out:
562
591
 
563
592
  static int config_delete(git_config_backend *cfg, const char *name)
564
593
  {
565
- config_entry_list *var;
594
+ cvar_t *var;
566
595
  diskfile_backend *b = (diskfile_backend *)cfg;
567
- diskfile_entries *map;
568
- git_strmap *entry_map;
596
+ refcounted_strmap *map; git_strmap *values;
569
597
  char *key;
570
598
  int result;
571
599
  khiter_t pos;
@@ -573,23 +601,23 @@ static int config_delete(git_config_backend *cfg, const char *name)
573
601
  if ((result = git_config__normalize_name(name, &key)) < 0)
574
602
  return result;
575
603
 
576
- if ((map = diskfile_entries_take(&b->header)) == NULL)
604
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
577
605
  return -1;
578
- entry_map = b->header.entries->map;
606
+ values = b->header.values->values;
579
607
 
580
- pos = git_strmap_lookup_index(entry_map, key);
608
+ pos = git_strmap_lookup_index(values, key);
581
609
  git__free(key);
582
610
 
583
- if (!git_strmap_valid_index(entry_map, pos)) {
584
- diskfile_entries_free(map);
611
+ if (!git_strmap_valid_index(values, pos)) {
612
+ refcounted_strmap_free(map);
585
613
  giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
586
614
  return GIT_ENOTFOUND;
587
615
  }
588
616
 
589
- var = git_strmap_value_at(entry_map, pos);
590
- diskfile_entries_free(map);
617
+ var = git_strmap_value_at(values, pos);
618
+ refcounted_strmap_free(map);
591
619
 
592
- if (var->entry->include_depth) {
620
+ if (var->included) {
593
621
  giterr_set(GITERR_CONFIG, "cannot delete included variable");
594
622
  return -1;
595
623
  }
@@ -608,8 +636,8 @@ static int config_delete(git_config_backend *cfg, const char *name)
608
636
  static int config_delete_multivar(git_config_backend *cfg, const char *name, const char *regexp)
609
637
  {
610
638
  diskfile_backend *b = (diskfile_backend *)cfg;
611
- diskfile_entries *map;
612
- git_strmap *entry_map;
639
+ refcounted_strmap *map;
640
+ git_strmap *values;
613
641
  char *key;
614
642
  regex_t preg;
615
643
  int result;
@@ -618,20 +646,20 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
618
646
  if ((result = git_config__normalize_name(name, &key)) < 0)
619
647
  return result;
620
648
 
621
- if ((map = diskfile_entries_take(&b->header)) == NULL)
649
+ if ((map = refcounted_strmap_take(&b->header)) == NULL)
622
650
  return -1;
623
- entry_map = b->header.entries->map;
651
+ values = b->header.values->values;
624
652
 
625
- pos = git_strmap_lookup_index(entry_map, key);
653
+ pos = git_strmap_lookup_index(values, key);
626
654
 
627
- if (!git_strmap_valid_index(entry_map, pos)) {
628
- diskfile_entries_free(map);
655
+ if (!git_strmap_valid_index(values, pos)) {
656
+ refcounted_strmap_free(map);
629
657
  git__free(key);
630
658
  giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
631
659
  return GIT_ENOTFOUND;
632
660
  }
633
661
 
634
- diskfile_entries_free(map);
662
+ refcounted_strmap_free(map);
635
663
 
636
664
  result = p_regcomp(&preg, regexp, REG_EXTENDED);
637
665
  if (result != 0) {
@@ -688,7 +716,7 @@ static int config_unlock(git_config_backend *_cfg, int success)
688
716
  }
689
717
 
690
718
  git_filebuf_cleanup(&cfg->locked_buf);
691
- git_buf_dispose(&cfg->locked_content);
719
+ git_buf_free(&cfg->locked_content);
692
720
  cfg->locked = false;
693
721
 
694
722
  return error;
@@ -784,7 +812,7 @@ static void backend_readonly_free(git_config_backend *_backend)
784
812
  if (backend == NULL)
785
813
  return;
786
814
 
787
- diskfile_entries_free(backend->header.entries);
815
+ refcounted_strmap_free(backend->header.values);
788
816
  git_mutex_free(&backend->header.values_mutex);
789
817
  git__free(backend);
790
818
  }
@@ -794,7 +822,7 @@ static int config_readonly_open(git_config_backend *cfg, git_config_level_t leve
794
822
  diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
795
823
  diskfile_backend *src = b->snapshot_from;
796
824
  diskfile_header *src_header = &src->header;
797
- diskfile_entries *entries;
825
+ refcounted_strmap *src_map;
798
826
  int error;
799
827
 
800
828
  if (!src_header->parent.readonly && (error = config_refresh(&src_header->parent)) < 0)
@@ -804,9 +832,9 @@ static int config_readonly_open(git_config_backend *cfg, git_config_level_t leve
804
832
  GIT_UNUSED(level);
805
833
  GIT_UNUSED(repo);
806
834
 
807
- if ((entries = diskfile_entries_take(src_header)) == NULL)
835
+ if ((src_map = refcounted_strmap_take(src_header)) == NULL)
808
836
  return -1;
809
- b->header.entries = entries;
837
+ b->header.values = src_map;
810
838
 
811
839
  return 0;
812
840
  }
@@ -876,20 +904,33 @@ static char *escape_value(const char *ptr)
876
904
  ptr++;
877
905
  }
878
906
 
879
- if (git_buf_oom(&buf))
907
+ if (git_buf_oom(&buf)) {
908
+ git_buf_free(&buf);
880
909
  return NULL;
910
+ }
881
911
 
882
912
  return git_buf_detach(&buf);
883
913
  }
884
914
 
915
+ struct parse_data {
916
+ const git_repository *repo;
917
+ const char *file_path;
918
+ git_strmap *values;
919
+ git_config_level_t level;
920
+ int depth;
921
+ };
922
+
885
923
  static int parse_include(git_config_parser *reader,
886
- diskfile_parse_state *parse_data, const char *file)
924
+ struct parse_data *parse_data, const char *file)
887
925
  {
888
926
  struct config_file *include;
889
927
  git_buf path = GIT_BUF_INIT;
890
928
  char *dir;
891
929
  int result;
892
930
 
931
+ if (!file)
932
+ return 0;
933
+
893
934
  if ((result = git_path_dirname_r(&path, reader->file->path)) < 0)
894
935
  return result;
895
936
 
@@ -905,7 +946,7 @@ static int parse_include(git_config_parser *reader,
905
946
  git_array_init(include->includes);
906
947
  include->path = git_buf_detach(&path);
907
948
 
908
- result = config_read(parse_data->entries, parse_data->repo,
949
+ result = config_read(parse_data->values, parse_data->repo,
909
950
  include, parse_data->level, parse_data->depth+1);
910
951
 
911
952
  if (result == GIT_ENOTFOUND) {
@@ -954,7 +995,7 @@ static int do_match_gitdir(
954
995
  *matches = (error == 0);
955
996
 
956
997
  out:
957
- git_buf_dispose(&path);
998
+ git_buf_free(&path);
958
999
  return error;
959
1000
  }
960
1001
 
@@ -985,13 +1026,13 @@ static const struct {
985
1026
  };
986
1027
 
987
1028
  static int parse_conditional_include(git_config_parser *reader,
988
- diskfile_parse_state *parse_data, const char *section, const char *file)
1029
+ struct parse_data *parse_data, const char *section, const char *file)
989
1030
  {
990
1031
  char *condition;
991
1032
  size_t i;
992
1033
  int error = 0, matches;
993
1034
 
994
- if (!parse_data->repo)
1035
+ if (!parse_data->repo || !file)
995
1036
  return 0;
996
1037
 
997
1038
  condition = git__substrdup(section + strlen("includeIf."),
@@ -1020,60 +1061,72 @@ static int parse_conditional_include(git_config_parser *reader,
1020
1061
  static int read_on_variable(
1021
1062
  git_config_parser *reader,
1022
1063
  const char *current_section,
1023
- const char *var_name,
1024
- const char *var_value,
1064
+ char *var_name,
1065
+ char *var_value,
1025
1066
  const char *line,
1026
1067
  size_t line_len,
1027
1068
  void *data)
1028
1069
  {
1029
- diskfile_parse_state *parse_data = (diskfile_parse_state *)data;
1070
+ struct parse_data *parse_data = (struct parse_data *)data;
1030
1071
  git_buf buf = GIT_BUF_INIT;
1031
- git_config_entry *entry;
1032
- const char *c;
1072
+ cvar_t *var;
1033
1073
  int result = 0;
1034
1074
 
1035
1075
  GIT_UNUSED(line);
1036
1076
  GIT_UNUSED(line_len);
1037
1077
 
1038
- git_buf_puts(&buf, current_section);
1039
- git_buf_putc(&buf, '.');
1040
- for (c = var_name; *c; c++)
1041
- git_buf_putc(&buf, git__tolower(*c));
1078
+ if (current_section) {
1079
+ /* TODO: Once warnings lang, we should likely warn
1080
+ * here. Git appears to warn in most cases if it sees
1081
+ * un-namespaced config options.
1082
+ */
1083
+ git_buf_puts(&buf, current_section);
1084
+ git_buf_putc(&buf, '.');
1085
+ }
1086
+ git__strtolower(var_name);
1087
+ git_buf_puts(&buf, var_name);
1088
+ git__free(var_name);
1042
1089
 
1043
- if (git_buf_oom(&buf))
1090
+ if (git_buf_oom(&buf)) {
1091
+ git__free(var_value);
1044
1092
  return -1;
1093
+ }
1045
1094
 
1046
- entry = git__calloc(1, sizeof(git_config_entry));
1047
- GITERR_CHECK_ALLOC(entry);
1048
- entry->name = git_buf_detach(&buf);
1049
- entry->value = var_value ? git__strdup(var_value) : NULL;
1050
- entry->level = parse_data->level;
1051
- entry->include_depth = parse_data->depth;
1095
+ var = git__calloc(1, sizeof(cvar_t));
1096
+ GITERR_CHECK_ALLOC(var);
1097
+ var->entry = git__calloc(1, sizeof(git_config_entry));
1098
+ GITERR_CHECK_ALLOC(var->entry);
1052
1099
 
1053
- if ((result = diskfile_entries_append(parse_data->entries, entry)) < 0)
1100
+ var->entry->name = git_buf_detach(&buf);
1101
+ var->entry->value = var_value;
1102
+ var->entry->level = parse_data->level;
1103
+ var->included = !!parse_data->depth;
1104
+
1105
+ if ((result = append_entry(parse_data->values, var)) < 0)
1054
1106
  return result;
1055
1107
 
1056
1108
  result = 0;
1057
1109
 
1058
1110
  /* Add or append the new config option */
1059
- if (!git__strcmp(entry->name, "include.path"))
1060
- result = parse_include(reader, parse_data, entry->value);
1061
- else if (!git__prefixcmp(entry->name, "includeif.") &&
1062
- !git__suffixcmp(entry->name, ".path"))
1111
+ if (!git__strcmp(var->entry->name, "include.path"))
1112
+ result = parse_include(reader, parse_data, var->entry->value);
1113
+ else if (!git__prefixcmp(var->entry->name, "includeif.") &&
1114
+ !git__suffixcmp(var->entry->name, ".path"))
1063
1115
  result = parse_conditional_include(reader, parse_data,
1064
- entry->name, entry->value);
1116
+ var->entry->name, var->entry->value);
1117
+
1065
1118
 
1066
1119
  return result;
1067
1120
  }
1068
1121
 
1069
1122
  static int config_read(
1070
- diskfile_entries *entries,
1123
+ git_strmap *values,
1071
1124
  const git_repository *repo,
1072
1125
  git_config_file *file,
1073
1126
  git_config_level_t level,
1074
1127
  int depth)
1075
1128
  {
1076
- diskfile_parse_state parse_data;
1129
+ struct parse_data parse_data;
1077
1130
  git_config_parser reader;
1078
1131
  git_buf contents = GIT_BUF_INIT;
1079
1132
  int error;
@@ -1101,14 +1154,14 @@ static int config_read(
1101
1154
 
1102
1155
  parse_data.repo = repo;
1103
1156
  parse_data.file_path = file->path;
1104
- parse_data.entries = entries;
1157
+ parse_data.values = values;
1105
1158
  parse_data.level = level;
1106
1159
  parse_data.depth = depth;
1107
1160
 
1108
1161
  error = git_config_parse(&reader, NULL, read_on_variable, NULL, NULL, &parse_data);
1109
1162
 
1110
1163
  out:
1111
- git_buf_dispose(&contents);
1164
+ git_buf_free(&contents);
1112
1165
  return error;
1113
1166
  }
1114
1167
 
@@ -1137,7 +1190,7 @@ static int write_section(git_buf *fbuf, const char *key)
1137
1190
  return -1;
1138
1191
 
1139
1192
  result = git_buf_put(fbuf, git_buf_cstr(&buf), buf.size);
1140
- git_buf_dispose(&buf);
1193
+ git_buf_free(&buf);
1141
1194
 
1142
1195
  return result;
1143
1196
  }
@@ -1246,8 +1299,8 @@ static int write_on_section(
1246
1299
  static int write_on_variable(
1247
1300
  git_config_parser *reader,
1248
1301
  const char *current_section,
1249
- const char *var_name,
1250
- const char *var_value,
1302
+ char *var_name,
1303
+ char *var_value,
1251
1304
  const char *line,
1252
1305
  size_t line_len,
1253
1306
  void *data)
@@ -1276,6 +1329,9 @@ static int write_on_variable(
1276
1329
  if (has_matched && write_data->preg != NULL)
1277
1330
  has_matched = (regexec(write_data->preg, var_value, 0, NULL, 0) == 0);
1278
1331
 
1332
+ git__free(var_name);
1333
+ git__free(var_value);
1334
+
1279
1335
  /* If this isn't the name/value we're looking for, simply dump the
1280
1336
  * existing data back out and continue on.
1281
1337
  */
@@ -1353,7 +1409,7 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1353
1409
  /* Lock the file */
1354
1410
  if ((result = git_filebuf_open(
1355
1411
  &file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS, GIT_CONFIG_FILE_MODE)) < 0) {
1356
- git_buf_dispose(&contents);
1412
+ git_buf_free(&contents);
1357
1413
  return result;
1358
1414
  }
1359
1415
 
@@ -1398,7 +1454,7 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1398
1454
  &write_data);
1399
1455
  git__free(section);
1400
1456
  git__free(orig_section);
1401
- git_buf_dispose(&write_data.buffered_comment);
1457
+ git_buf_free(&write_data.buffered_comment);
1402
1458
 
1403
1459
  if (result < 0) {
1404
1460
  git_filebuf_cleanup(&file);
@@ -1408,7 +1464,7 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1408
1464
  if (cfg->locked) {
1409
1465
  size_t len = buf.asize;
1410
1466
  /* Update our copy with the modified contents */
1411
- git_buf_dispose(&cfg->locked_content);
1467
+ git_buf_free(&cfg->locked_content);
1412
1468
  git_buf_attach(&cfg->locked_content, git_buf_detach(&buf), len);
1413
1469
  } else {
1414
1470
  git_filebuf_write(&file, git_buf_cstr(&buf), git_buf_len(&buf));
@@ -1416,8 +1472,8 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1416
1472
  }
1417
1473
 
1418
1474
  done:
1419
- git_buf_dispose(&buf);
1420
- git_buf_dispose(&contents);
1475
+ git_buf_free(&buf);
1476
+ git_buf_free(&contents);
1421
1477
  git_parse_ctx_clear(&reader.ctx);
1422
1478
  return result;
1423
1479
  }