rugged 0.27.5 → 0.27.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rugged/version.rb +1 -1
  3. data/vendor/libgit2/CMakeLists.txt +2 -2
  4. data/vendor/libgit2/cmake/Modules/FindmbedTLS.cmake +93 -0
  5. data/vendor/libgit2/deps/http-parser/CMakeLists.txt +2 -0
  6. data/vendor/libgit2/include/git2.h +1 -0
  7. data/vendor/libgit2/include/git2/attr.h +18 -7
  8. data/vendor/libgit2/include/git2/blame.h +39 -22
  9. data/vendor/libgit2/include/git2/blob.h +1 -1
  10. data/vendor/libgit2/include/git2/branch.h +1 -1
  11. data/vendor/libgit2/include/git2/buffer.h +14 -2
  12. data/vendor/libgit2/include/git2/checkout.h +13 -12
  13. data/vendor/libgit2/include/git2/cherrypick.h +6 -4
  14. data/vendor/libgit2/include/git2/clone.h +8 -6
  15. data/vendor/libgit2/include/git2/commit.h +28 -0
  16. data/vendor/libgit2/include/git2/common.h +27 -0
  17. data/vendor/libgit2/include/git2/config.h +1 -0
  18. data/vendor/libgit2/include/git2/describe.h +30 -7
  19. data/vendor/libgit2/include/git2/diff.h +32 -22
  20. data/vendor/libgit2/include/git2/errors.h +1 -0
  21. data/vendor/libgit2/include/git2/ignore.h +2 -2
  22. data/vendor/libgit2/include/git2/mailmap.h +115 -0
  23. data/vendor/libgit2/include/git2/merge.h +10 -8
  24. data/vendor/libgit2/include/git2/proxy.h +9 -5
  25. data/vendor/libgit2/include/git2/rebase.h +7 -4
  26. data/vendor/libgit2/include/git2/refspec.h +17 -0
  27. data/vendor/libgit2/include/git2/remote.h +12 -10
  28. data/vendor/libgit2/include/git2/repository.h +7 -5
  29. data/vendor/libgit2/include/git2/revert.h +5 -3
  30. data/vendor/libgit2/include/git2/stash.h +11 -8
  31. data/vendor/libgit2/include/git2/status.h +7 -3
  32. data/vendor/libgit2/include/git2/submodule.h +8 -7
  33. data/vendor/libgit2/include/git2/sys/alloc.h +101 -0
  34. data/vendor/libgit2/include/git2/sys/index.h +3 -0
  35. data/vendor/libgit2/include/git2/sys/mempack.h +35 -35
  36. data/vendor/libgit2/include/git2/sys/merge.h +6 -1
  37. data/vendor/libgit2/include/git2/sys/path.h +55 -0
  38. data/vendor/libgit2/include/git2/transaction.h +1 -0
  39. data/vendor/libgit2/include/git2/types.h +8 -5
  40. data/vendor/libgit2/include/git2/version.h +2 -2
  41. data/vendor/libgit2/include/git2/worktree.h +46 -11
  42. data/vendor/libgit2/src/CMakeLists.txt +87 -15
  43. data/vendor/libgit2/src/alloc.c +47 -0
  44. data/vendor/libgit2/src/alloc.h +40 -0
  45. data/vendor/libgit2/src/apply.c +4 -4
  46. data/vendor/libgit2/src/attr.c +4 -4
  47. data/vendor/libgit2/src/attr_file.c +8 -7
  48. data/vendor/libgit2/src/attrcache.c +2 -2
  49. data/vendor/libgit2/src/blame.c +11 -4
  50. data/vendor/libgit2/src/blame.h +1 -0
  51. data/vendor/libgit2/src/blame_git.c +8 -5
  52. data/vendor/libgit2/src/blob.c +5 -5
  53. data/vendor/libgit2/src/branch.c +20 -20
  54. data/vendor/libgit2/src/buffer.c +9 -4
  55. data/vendor/libgit2/src/buffer.h +1 -1
  56. data/vendor/libgit2/src/checkout.c +33 -24
  57. data/vendor/libgit2/src/cherrypick.c +3 -3
  58. data/vendor/libgit2/src/clone.c +13 -13
  59. data/vendor/libgit2/src/commit.c +16 -3
  60. data/vendor/libgit2/src/common.h +3 -1
  61. data/vendor/libgit2/src/config.c +3 -3
  62. data/vendor/libgit2/src/config_file.c +193 -241
  63. data/vendor/libgit2/src/config_parse.c +89 -66
  64. data/vendor/libgit2/src/config_parse.h +2 -2
  65. data/vendor/libgit2/src/crlf.c +9 -3
  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 +4 -3
  70. data/vendor/libgit2/src/diff_print.c +8 -8
  71. data/vendor/libgit2/src/diff_tform.c +1 -1
  72. data/vendor/libgit2/src/diff_xdiff.c +12 -0
  73. data/vendor/libgit2/src/features.h.in +2 -0
  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 +3 -3
  79. data/vendor/libgit2/src/global.c +17 -12
  80. data/vendor/libgit2/src/hash.h +2 -0
  81. data/vendor/libgit2/src/hash/hash_mbedtls.c +38 -0
  82. data/vendor/libgit2/src/hash/hash_mbedtls.h +20 -0
  83. data/vendor/libgit2/src/ignore.c +15 -20
  84. data/vendor/libgit2/src/index.c +77 -36
  85. data/vendor/libgit2/src/index.h +10 -0
  86. data/vendor/libgit2/src/indexer.c +9 -9
  87. data/vendor/libgit2/src/iterator.c +8 -8
  88. data/vendor/libgit2/src/khash.h +3 -1
  89. data/vendor/libgit2/src/mailmap.c +485 -0
  90. data/vendor/libgit2/src/mailmap.h +35 -0
  91. data/vendor/libgit2/src/merge.c +7 -7
  92. data/vendor/libgit2/src/netops.c +5 -5
  93. data/vendor/libgit2/src/notes.c +2 -2
  94. data/vendor/libgit2/src/odb.c +7 -7
  95. data/vendor/libgit2/src/odb_loose.c +13 -13
  96. data/vendor/libgit2/src/odb_pack.c +3 -3
  97. data/vendor/libgit2/src/pack-objects.c +2 -2
  98. data/vendor/libgit2/src/pack.c +5 -5
  99. data/vendor/libgit2/src/pack.h +1 -1
  100. data/vendor/libgit2/src/patch.c +1 -1
  101. data/vendor/libgit2/src/patch_generate.c +2 -2
  102. data/vendor/libgit2/src/patch_parse.c +11 -4
  103. data/vendor/libgit2/src/path.c +42 -66
  104. data/vendor/libgit2/src/path.h +2 -72
  105. data/vendor/libgit2/src/pathspec.c +1 -1
  106. data/vendor/libgit2/src/push.c +2 -2
  107. data/vendor/libgit2/src/rebase.c +19 -22
  108. data/vendor/libgit2/src/refdb_fs.c +65 -34
  109. data/vendor/libgit2/src/refs.c +6 -6
  110. data/vendor/libgit2/src/refspec.c +30 -5
  111. data/vendor/libgit2/src/refspec.h +1 -1
  112. data/vendor/libgit2/src/remote.c +40 -40
  113. data/vendor/libgit2/src/repository.c +63 -59
  114. data/vendor/libgit2/src/reset.c +1 -1
  115. data/vendor/libgit2/src/revert.c +3 -3
  116. data/vendor/libgit2/src/revparse.c +4 -4
  117. data/vendor/libgit2/src/revwalk.c +44 -10
  118. data/vendor/libgit2/src/revwalk.h +2 -1
  119. data/vendor/libgit2/src/settings.c +25 -1
  120. data/vendor/libgit2/src/signature.c +1 -1
  121. data/vendor/libgit2/src/stash.c +80 -34
  122. data/vendor/libgit2/src/status.c +1 -1
  123. data/vendor/libgit2/src/stdalloc.c +120 -0
  124. data/vendor/libgit2/src/stdalloc.h +17 -0
  125. data/vendor/libgit2/src/streams/mbedtls.c +463 -0
  126. data/vendor/libgit2/src/streams/mbedtls.h +20 -0
  127. data/vendor/libgit2/src/streams/openssl.c +132 -34
  128. data/vendor/libgit2/src/streams/openssl.h +0 -107
  129. data/vendor/libgit2/src/streams/tls.c +3 -0
  130. data/vendor/libgit2/src/submodule.c +117 -82
  131. data/vendor/libgit2/src/sysdir.c +4 -4
  132. data/vendor/libgit2/src/tag.c +7 -7
  133. data/vendor/libgit2/src/trace.h +1 -1
  134. data/vendor/libgit2/src/trailer.c +6 -6
  135. data/vendor/libgit2/src/transport.c +2 -2
  136. data/vendor/libgit2/src/transports/auth.c +1 -1
  137. data/vendor/libgit2/src/transports/auth_negotiate.c +2 -2
  138. data/vendor/libgit2/src/transports/git.c +1 -1
  139. data/vendor/libgit2/src/transports/http.c +12 -12
  140. data/vendor/libgit2/src/transports/local.c +7 -7
  141. data/vendor/libgit2/src/transports/smart.c +17 -8
  142. data/vendor/libgit2/src/transports/smart.h +5 -5
  143. data/vendor/libgit2/src/transports/smart_pkt.c +122 -130
  144. data/vendor/libgit2/src/transports/smart_protocol.c +48 -38
  145. data/vendor/libgit2/src/transports/ssh.c +1 -1
  146. data/vendor/libgit2/src/transports/winhttp.c +6 -6
  147. data/vendor/libgit2/src/tree.c +12 -53
  148. data/vendor/libgit2/src/tree.h +0 -12
  149. data/vendor/libgit2/src/util.c +16 -0
  150. data/vendor/libgit2/src/util.h +12 -135
  151. data/vendor/libgit2/src/win32/findfile.c +2 -2
  152. data/vendor/libgit2/src/win32/posix_w32.c +1 -1
  153. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +94 -0
  154. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +28 -75
  155. data/vendor/libgit2/src/worktree.c +64 -43
  156. data/vendor/libgit2/src/worktree.h +2 -0
  157. data/vendor/libgit2/src/xdiff/xdiffi.c +3 -1
  158. metadata +16 -2
@@ -116,7 +116,7 @@ int git_buf_grow_by(git_buf *buffer, size_t additional_size)
116
116
  return git_buf_try_grow(buffer, newsize, true);
117
117
  }
118
118
 
119
- void git_buf_free(git_buf *buf)
119
+ void git_buf_dispose(git_buf *buf)
120
120
  {
121
121
  if (!buf) return;
122
122
 
@@ -126,6 +126,11 @@ void git_buf_free(git_buf *buf)
126
126
  git_buf_init(buf, 0);
127
127
  }
128
128
 
129
+ void git_buf_free(git_buf *buf)
130
+ {
131
+ git_buf_dispose(buf);
132
+ }
133
+
129
134
  void git_buf_sanitize(git_buf *buf)
130
135
  {
131
136
  if (buf->ptr == NULL) {
@@ -610,7 +615,7 @@ char *git_buf_detach(git_buf *buf)
610
615
 
611
616
  int git_buf_attach(git_buf *buf, char *ptr, size_t asize)
612
617
  {
613
- git_buf_free(buf);
618
+ git_buf_dispose(buf);
614
619
 
615
620
  if (ptr) {
616
621
  buf->ptr = ptr;
@@ -628,7 +633,7 @@ int git_buf_attach(git_buf *buf, char *ptr, size_t asize)
628
633
  void git_buf_attach_notowned(git_buf *buf, const char *ptr, size_t size)
629
634
  {
630
635
  if (git_buf_is_allocated(buf))
631
- git_buf_free(buf);
636
+ git_buf_dispose(buf);
632
637
 
633
638
  if (!size) {
634
639
  git_buf_init(buf, 0);
@@ -949,7 +954,7 @@ int git_buf_quote(git_buf *buf)
949
954
  git_buf_swap(&quoted, buf);
950
955
 
951
956
  done:
952
- git_buf_free(&quoted);
957
+ git_buf_dispose(&quoted);
953
958
  return error;
954
959
  }
955
960
 
@@ -76,7 +76,7 @@ extern char *git_buf_detach(git_buf *buf);
76
76
  extern int git_buf_attach(git_buf *buf, char *ptr, size_t asize);
77
77
 
78
78
  /* Populates a `git_buf` where the contents are not "owned" by the
79
- * buffer, and calls to `git_buf_free` will not free the given buf.
79
+ * buffer, and calls to `git_buf_dispose` will not free the given buf.
80
80
  */
81
81
  extern void git_buf_attach_notowned(
82
82
  git_buf *buf, const char *ptr, size_t size);
@@ -1604,7 +1604,7 @@ static int blob_content_to_link(
1604
1604
  st->st_mode = GIT_FILEMODE_LINK;
1605
1605
  }
1606
1606
 
1607
- git_buf_free(&linktarget);
1607
+ git_buf_dispose(&linktarget);
1608
1608
 
1609
1609
  return error;
1610
1610
  }
@@ -2161,13 +2161,13 @@ static int checkout_write_merge(
2161
2161
  done:
2162
2162
  git_filter_list_free(fl);
2163
2163
 
2164
- git_buf_free(&out_data);
2165
- git_buf_free(&our_label);
2166
- git_buf_free(&their_label);
2164
+ git_buf_dispose(&out_data);
2165
+ git_buf_dispose(&our_label);
2166
+ git_buf_dispose(&their_label);
2167
2167
 
2168
2168
  git_merge_file_result_free(&result);
2169
- git_buf_free(&path_workdir);
2170
- git_buf_free(&path_suffixed);
2169
+ git_buf_dispose(&path_workdir);
2170
+ git_buf_dispose(&path_suffixed);
2171
2171
 
2172
2172
  return error;
2173
2173
  }
@@ -2347,8 +2347,8 @@ static void checkout_data_clear(checkout_data *data)
2347
2347
  git__free(data->pfx);
2348
2348
  data->pfx = NULL;
2349
2349
 
2350
- git_buf_free(&data->target_path);
2351
- git_buf_free(&data->tmp);
2350
+ git_buf_dispose(&data->target_path);
2351
+ git_buf_dispose(&data->tmp);
2352
2352
 
2353
2353
  git_index_free(data->index);
2354
2354
  data->index = NULL;
@@ -2397,6 +2397,9 @@ static int checkout_data_init(
2397
2397
  GIT_DIR_MODE, GIT_MKDIR_VERIFY_DIR)) < 0)
2398
2398
  goto cleanup;
2399
2399
 
2400
+ if ((error = git_repository_index(&data->index, data->repo)) < 0)
2401
+ goto cleanup;
2402
+
2400
2403
  /* refresh config and index content unless NO_REFRESH is given */
2401
2404
  if ((data->opts.checkout_strategy & GIT_CHECKOUT_NO_REFRESH) == 0) {
2402
2405
  git_config *cfg;
@@ -2404,24 +2407,30 @@ static int checkout_data_init(
2404
2407
  if ((error = git_repository_config__weakptr(&cfg, repo)) < 0)
2405
2408
  goto cleanup;
2406
2409
 
2407
- /* Get the repository index and reload it (unless we're checking
2408
- * out the index; then it has the changes we're trying to check
2409
- * out and those should not be overwritten.)
2410
+ /* Reload the repository index (unless we're checking out the
2411
+ * index; then it has the changes we're trying to check out
2412
+ * and those should not be overwritten.)
2410
2413
  */
2411
- if ((error = git_repository_index(&data->index, data->repo)) < 0)
2412
- goto cleanup;
2413
-
2414
2414
  if (data->index != git_iterator_index(target)) {
2415
- if ((error = git_index_read(data->index, true)) < 0)
2416
- goto cleanup;
2417
-
2418
- /* cannot checkout if unresolved conflicts exist */
2419
- if ((data->opts.checkout_strategy & GIT_CHECKOUT_FORCE) == 0 &&
2420
- git_index_has_conflicts(data->index)) {
2421
- error = GIT_ECONFLICT;
2422
- giterr_set(GITERR_CHECKOUT,
2423
- "unresolved conflicts exist in the index");
2424
- goto cleanup;
2415
+ if (data->opts.checkout_strategy & GIT_CHECKOUT_FORCE) {
2416
+ /* When forcing, we can blindly re-read the index */
2417
+ if ((error = git_index_read(data->index, false)) < 0)
2418
+ goto cleanup;
2419
+ } else {
2420
+ /*
2421
+ * When not being forced, we need to check for unresolved
2422
+ * conflicts and unsaved changes in the index before
2423
+ * proceeding.
2424
+ */
2425
+ if (git_index_has_conflicts(data->index)) {
2426
+ error = GIT_ECONFLICT;
2427
+ giterr_set(GITERR_CHECKOUT,
2428
+ "unresolved conflicts exist in the index");
2429
+ goto cleanup;
2430
+ }
2431
+
2432
+ if ((error = git_index_read_safely(data->index)) < 0)
2433
+ goto cleanup;
2425
2434
  }
2426
2435
 
2427
2436
  /* clean conflict data in the current index */
@@ -37,7 +37,7 @@ static int write_cherrypick_head(
37
37
  if (error < 0)
38
38
  git_filebuf_cleanup(&file);
39
39
 
40
- git_buf_free(&file_path);
40
+ git_buf_dispose(&file_path);
41
41
 
42
42
  return error;
43
43
  }
@@ -61,7 +61,7 @@ cleanup:
61
61
  if (error < 0)
62
62
  git_filebuf_cleanup(&file);
63
63
 
64
- git_buf_free(&file_path);
64
+ git_buf_dispose(&file_path);
65
65
 
66
66
  return error;
67
67
  }
@@ -216,7 +216,7 @@ done:
216
216
  git_index_free(index);
217
217
  git_commit_free(our_commit);
218
218
  git_reference_free(our_ref);
219
- git_buf_free(&their_label);
219
+ git_buf_dispose(&their_label);
220
220
 
221
221
  return error;
222
222
  }
@@ -48,7 +48,7 @@ static int create_branch(
48
48
  return error;
49
49
 
50
50
  error = git_reference_create(&branch_ref, repo, git_buf_cstr(&refname), target, 0, log_message);
51
- git_buf_free(&refname);
51
+ git_buf_dispose(&refname);
52
52
  git_commit_free(head_obj);
53
53
 
54
54
  if (!error)
@@ -87,8 +87,8 @@ static int setup_tracking_config(
87
87
  error = 0;
88
88
 
89
89
  cleanup:
90
- git_buf_free(&remote_key);
91
- git_buf_free(&merge_key);
90
+ git_buf_dispose(&remote_key);
91
+ git_buf_dispose(&merge_key);
92
92
  return error;
93
93
  }
94
94
 
@@ -195,8 +195,8 @@ static int update_head_to_remote(
195
195
  reflog_message);
196
196
 
197
197
  cleanup:
198
- git_buf_free(&remote_master_name);
199
- git_buf_free(&branch);
198
+ git_buf_dispose(&remote_master_name);
199
+ git_buf_dispose(&branch);
200
200
 
201
201
  return error;
202
202
  }
@@ -225,7 +225,7 @@ static int update_head_to_branch(
225
225
 
226
226
  cleanup:
227
227
  git_reference_free(remote_ref);
228
- git_buf_free(&remote_branch_name);
228
+ git_buf_dispose(&remote_branch_name);
229
229
  return retcode;
230
230
  }
231
231
 
@@ -351,7 +351,7 @@ static int clone_into(git_repository *repo, git_remote *_remote, const git_fetch
351
351
 
352
352
  cleanup:
353
353
  git_remote_free(remote);
354
- git_buf_free(&reflog_message);
354
+ git_buf_dispose(&reflog_message);
355
355
 
356
356
  return error;
357
357
  }
@@ -378,7 +378,7 @@ int git_clone__should_clone_local(const char *url_or_path, git_clone_local_t loc
378
378
  git_path_isdir(path);
379
379
 
380
380
  done:
381
- git_buf_free(&fromurl);
381
+ git_buf_dispose(&fromurl);
382
382
  return is_local;
383
383
  }
384
384
 
@@ -510,7 +510,7 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_
510
510
 
511
511
  /* Copy .git/objects/ from the source to the target */
512
512
  if ((error = git_repository_open(&src, git_buf_cstr(&src_path))) < 0) {
513
- git_buf_free(&src_path);
513
+ git_buf_dispose(&src_path);
514
514
  return error;
515
515
  }
516
516
 
@@ -549,10 +549,10 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_
549
549
  error = checkout_branch(repo, remote, co_opts, branch, git_buf_cstr(&reflog_message));
550
550
 
551
551
  cleanup:
552
- git_buf_free(&reflog_message);
553
- git_buf_free(&src_path);
554
- git_buf_free(&src_odb);
555
- git_buf_free(&dst_odb);
552
+ git_buf_dispose(&reflog_message);
553
+ git_buf_dispose(&src_path);
554
+ git_buf_dispose(&src_odb);
555
+ git_buf_dispose(&dst_odb);
556
556
  git_repository_free(src);
557
557
  return error;
558
558
  }
@@ -11,6 +11,7 @@
11
11
  #include "git2/object.h"
12
12
  #include "git2/repository.h"
13
13
  #include "git2/signature.h"
14
+ #include "git2/mailmap.h"
14
15
  #include "git2/sys/commit.h"
15
16
 
16
17
  #include "odb.h"
@@ -74,7 +75,7 @@ static int git_commit__create_buffer_internal(
74
75
  return 0;
75
76
 
76
77
  on_error:
77
- git_buf_free(out);
78
+ git_buf_dispose(out);
78
79
  return -1;
79
80
  }
80
81
 
@@ -176,7 +177,7 @@ static int git_commit__create_internal(
176
177
  cleanup:
177
178
  git_array_clear(parents);
178
179
  git_reference_free(ref);
179
- git_buf_free(&buf);
180
+ git_buf_dispose(&buf);
180
181
  return error;
181
182
  }
182
183
 
@@ -886,6 +887,18 @@ int git_commit_create_with_signature(
886
887
  goto cleanup;
887
888
 
888
889
  cleanup:
889
- git_buf_free(&commit);
890
+ git_buf_dispose(&commit);
890
891
  return error;
891
892
  }
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
+ }
@@ -17,8 +17,10 @@
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
20
22
  #else
21
- # define GIT_INLINE(type) static inline type
23
+ # define GIT_INLINE(type) static type
22
24
  #endif
23
25
 
24
26
  /** Support for gcc/clang __has_builtin intrinsic */
@@ -1164,7 +1164,7 @@ int git_config_open_default(git_config **out)
1164
1164
  error = git_config_add_file_ondisk(cfg, buf.ptr,
1165
1165
  GIT_CONFIG_LEVEL_PROGRAMDATA, NULL, 0);
1166
1166
 
1167
- git_buf_free(&buf);
1167
+ git_buf_dispose(&buf);
1168
1168
 
1169
1169
  if (error) {
1170
1170
  git_config_free(cfg);
@@ -1478,8 +1478,8 @@ int git_config_rename_section(
1478
1478
  config, git_buf_cstr(&pattern), rename_config_entries_cb, &data);
1479
1479
 
1480
1480
  cleanup:
1481
- git_buf_free(&pattern);
1482
- git_buf_free(&replace);
1481
+ git_buf_dispose(&pattern);
1482
+ git_buf_dispose(&replace);
1483
1483
 
1484
1484
  return error;
1485
1485
  }
@@ -23,69 +23,30 @@
23
23
  #include <sys/types.h>
24
24
  #include <regex.h>
25
25
 
26
- typedef struct cvar_t {
27
- struct cvar_t *next;
26
+ typedef struct config_entry_list {
27
+ struct config_entry_list *next;
28
28
  git_config_entry *entry;
29
- bool included; /* whether this is part of [include] */
30
- } cvar_t;
29
+ } config_entry_list;
31
30
 
32
31
  typedef struct git_config_file_iter {
33
32
  git_config_iterator parent;
34
- git_strmap_iter iter;
35
- cvar_t* next_var;
33
+ config_entry_list *head;
36
34
  } git_config_file_iter;
37
35
 
38
36
  /* Max depth for [include] directives */
39
37
  #define MAX_INCLUDE_DEPTH 10
40
38
 
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
-
79
39
  typedef struct {
80
40
  git_atomic refcount;
81
- git_strmap *values;
82
- } refcounted_strmap;
41
+ git_strmap *map;
42
+ config_entry_list *list;
43
+ } diskfile_entries;
83
44
 
84
45
  typedef struct {
85
46
  git_config_backend parent;
86
47
  /* mutex to coordinate accessing the values */
87
48
  git_mutex values_mutex;
88
- refcounted_strmap *values;
49
+ diskfile_entries *entries;
89
50
  const git_repository *repo;
90
51
  git_config_level_t level;
91
52
  } diskfile_header;
@@ -108,7 +69,15 @@ typedef struct {
108
69
  diskfile_backend *snapshot_from;
109
70
  } diskfile_readonly_backend;
110
71
 
111
- static int config_read(git_strmap *values, const git_repository *repo, git_config_file *file, git_config_level_t level, int depth);
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);
112
81
  static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const regex_t *preg, const char *value);
113
82
  static char *escape_value(const char *ptr);
114
83
 
@@ -121,15 +90,20 @@ static int config_error_readonly(void)
121
90
  return -1;
122
91
  }
123
92
 
124
- static void cvar_free(cvar_t *var)
93
+ static void config_entry_list_free(config_entry_list *list)
125
94
  {
126
- if (var == NULL)
127
- return;
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);
128
104
 
129
- git__free((char*)var->entry->name);
130
- git__free((char *)var->entry->value);
131
- git__free(var->entry);
132
- git__free(var);
105
+ list = next;
106
+ };
133
107
  }
134
108
 
135
109
  int git_config_file_normalize_section(char *start, char *end)
@@ -155,57 +129,70 @@ int git_config_file_normalize_section(char *start, char *end)
155
129
  return 0;
156
130
  }
157
131
 
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
+
158
145
  /* Add or append the new config option */
159
- static int append_entry(git_strmap *values, cvar_t *var)
146
+ static int diskfile_entries_append(diskfile_entries *entries, git_config_entry *entry)
160
147
  {
161
148
  git_strmap_iter pos;
162
- cvar_t *existing;
149
+ config_entry_list *existing, *var;
163
150
  int error = 0;
164
151
 
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);
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;
168
162
  } else {
169
- existing = git_strmap_value_at(values, pos);
170
- while (existing->next != NULL) {
171
- existing = existing->next;
172
- }
173
- existing->next = var;
163
+ existing = git_strmap_value_at(entries->map, pos);
164
+ config_entry_list_append(&existing, var);
174
165
  }
175
166
 
176
- if (error > 0)
177
- error = 0;
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);
178
171
 
179
172
  return error;
180
173
  }
181
174
 
182
- static void free_vars(git_strmap *values)
175
+ static void diskfile_entries_free(diskfile_entries *entries)
183
176
  {
184
- cvar_t *var = NULL;
177
+ config_entry_list *list = NULL, *next;
185
178
 
186
- if (values == NULL)
179
+ if (!entries)
187
180
  return;
188
181
 
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
- });
195
-
196
- git_strmap_free(values);
197
- }
198
-
199
- static void refcounted_strmap_free(refcounted_strmap *map)
200
- {
201
- if (!map)
182
+ if (git_atomic_dec(&entries->refcount) != 0)
202
183
  return;
203
184
 
204
- if (git_atomic_dec(&map->refcount) != 0)
205
- return;
185
+ git_strmap_foreach_value(entries->map, list, config_entry_list_free(list));
186
+ git_strmap_free(entries->map);
187
+
188
+ list = entries->list;
189
+ while (list != NULL) {
190
+ next = list->next;
191
+ git__free(list);
192
+ list = next;
193
+ }
206
194
 
207
- free_vars(map->values);
208
- git__free(map);
195
+ git__free(entries);
209
196
  }
210
197
 
211
198
  /**
@@ -213,37 +200,37 @@ static void refcounted_strmap_free(refcounted_strmap *map)
213
200
  * refcount. This is its own function to make sure we use the mutex to
214
201
  * avoid the map pointer from changing under us.
215
202
  */
216
- static refcounted_strmap *refcounted_strmap_take(diskfile_header *h)
203
+ static diskfile_entries *diskfile_entries_take(diskfile_header *h)
217
204
  {
218
- refcounted_strmap *map;
205
+ diskfile_entries *entries;
219
206
 
220
207
  if (git_mutex_lock(&h->values_mutex) < 0) {
221
208
  giterr_set(GITERR_OS, "failed to lock config backend");
222
209
  return NULL;
223
210
  }
224
211
 
225
- map = h->values;
226
- git_atomic_inc(&map->refcount);
212
+ entries = h->entries;
213
+ git_atomic_inc(&entries->refcount);
227
214
 
228
215
  git_mutex_unlock(&h->values_mutex);
229
216
 
230
- return map;
217
+ return entries;
231
218
  }
232
219
 
233
- static int refcounted_strmap_alloc(refcounted_strmap **out)
220
+ static int diskfile_entries_alloc(diskfile_entries **out)
234
221
  {
235
- refcounted_strmap *map;
222
+ diskfile_entries *entries;
236
223
  int error;
237
224
 
238
- map = git__calloc(1, sizeof(refcounted_strmap));
239
- GITERR_CHECK_ALLOC(map);
225
+ entries = git__calloc(1, sizeof(diskfile_entries));
226
+ GITERR_CHECK_ALLOC(entries);
240
227
 
241
- git_atomic_set(&map->refcount, 1);
228
+ git_atomic_set(&entries->refcount, 1);
242
229
 
243
- if ((error = git_strmap_alloc(&map->values)) < 0)
244
- git__free(map);
230
+ if ((error = git_strmap_alloc(&entries->map)) < 0)
231
+ git__free(entries);
245
232
  else
246
- *out = map;
233
+ *out = entries;
247
234
 
248
235
  return error;
249
236
  }
@@ -272,15 +259,15 @@ static int config_open(git_config_backend *cfg, git_config_level_t level, const
272
259
  b->header.level = level;
273
260
  b->header.repo = repo;
274
261
 
275
- if ((res = refcounted_strmap_alloc(&b->header.values)) < 0)
262
+ if ((res = diskfile_entries_alloc(&b->header.entries)) < 0)
276
263
  return res;
277
264
 
278
265
  if (!git_path_exists(b->file.path))
279
266
  return 0;
280
267
 
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;
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;
284
271
  }
285
272
 
286
273
  return res;
@@ -313,7 +300,7 @@ static int config_is_modified(int *modified, struct config_file *file)
313
300
  }
314
301
 
315
302
  out:
316
- git_buf_free(&buf);
303
+ git_buf_dispose(&buf);
317
304
 
318
305
  return error;
319
306
  }
@@ -321,7 +308,7 @@ out:
321
308
  static int config_refresh(git_config_backend *cfg)
322
309
  {
323
310
  diskfile_backend *b = (diskfile_backend *)cfg;
324
- refcounted_strmap *values = NULL, *tmp;
311
+ diskfile_entries *entries = NULL, *tmp;
325
312
  git_config_file *include;
326
313
  int error, modified;
327
314
  uint32_t i;
@@ -336,7 +323,7 @@ static int config_refresh(git_config_backend *cfg)
336
323
  if (!modified)
337
324
  return 0;
338
325
 
339
- if ((error = refcounted_strmap_alloc(&values)) < 0)
326
+ if ((error = diskfile_entries_alloc(&entries)) < 0)
340
327
  goto out;
341
328
 
342
329
  /* Reparse the current configuration */
@@ -345,7 +332,7 @@ static int config_refresh(git_config_backend *cfg)
345
332
  }
346
333
  git_array_clear(b->file.includes);
347
334
 
348
- if ((error = config_read(values->values, b->header.repo, &b->file, b->header.level, 0)) < 0)
335
+ if ((error = config_read(entries, b->header.repo, &b->file, b->header.level, 0)) < 0)
349
336
  goto out;
350
337
 
351
338
  if ((error = git_mutex_lock(&b->header.values_mutex)) < 0) {
@@ -353,14 +340,14 @@ static int config_refresh(git_config_backend *cfg)
353
340
  goto out;
354
341
  }
355
342
 
356
- tmp = b->header.values;
357
- b->header.values = values;
358
- values = tmp;
343
+ tmp = b->header.entries;
344
+ b->header.entries = entries;
345
+ entries = tmp;
359
346
 
360
347
  git_mutex_unlock(&b->header.values_mutex);
361
348
 
362
349
  out:
363
- refcounted_strmap_free(values);
350
+ diskfile_entries_free(entries);
364
351
 
365
352
  return (error == GIT_ENOTFOUND) ? 0 : error;
366
353
  }
@@ -373,7 +360,7 @@ static void backend_free(git_config_backend *_backend)
373
360
  return;
374
361
 
375
362
  config_file_clear(&backend->file);
376
- refcounted_strmap_free(backend->header.values);
363
+ diskfile_entries_free(backend->header.entries);
377
364
  git_mutex_free(&backend->header.values_mutex);
378
365
  git__free(backend);
379
366
  }
@@ -390,24 +377,12 @@ static int config_iterator_next(
390
377
  git_config_iterator *iter)
391
378
  {
392
379
  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;
397
380
 
398
- if (it->next_var == NULL) {
399
- err = git_strmap_next((void**) &var, &(it->iter), values);
400
- } else {
401
- var = it->next_var;
402
- }
403
-
404
- if (err < 0) {
405
- it->next_var = NULL;
406
- return err;
407
- }
381
+ if (!it->head)
382
+ return GIT_ITEROVER;
408
383
 
409
- *entry = var->entry;
410
- it->next_var = CVAR_LIST_NEXT(var);
384
+ *entry = it->head->entry;
385
+ it->head = it->head->next;
411
386
 
412
387
  return 0;
413
388
  }
@@ -433,15 +408,11 @@ static int config_iterator_new(
433
408
 
434
409
  h = (diskfile_header *)snapshot;
435
410
 
436
- /* strmap_begin() is currently a macro returning 0 */
437
- GIT_UNUSED(h);
438
-
439
411
  it->parent.backend = snapshot;
440
- it->iter = git_strmap_begin(h->values);
441
- it->next_var = NULL;
442
-
412
+ it->head = h->entries->list;
443
413
  it->parent.next = config_iterator_next;
444
414
  it->parent.free = config_iterator_free;
415
+
445
416
  *iter = (git_config_iterator *) it;
446
417
 
447
418
  return 0;
@@ -450,8 +421,8 @@ static int config_iterator_new(
450
421
  static int config_set(git_config_backend *cfg, const char *name, const char *value)
451
422
  {
452
423
  diskfile_backend *b = (diskfile_backend *)cfg;
453
- refcounted_strmap *map;
454
- git_strmap *values;
424
+ diskfile_entries *entries;
425
+ git_strmap *entry_map;
455
426
  char *key, *esc_value = NULL;
456
427
  khiter_t pos;
457
428
  int rval, ret;
@@ -459,17 +430,17 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
459
430
  if ((rval = git_config__normalize_name(name, &key)) < 0)
460
431
  return rval;
461
432
 
462
- if ((map = refcounted_strmap_take(&b->header)) == NULL)
433
+ if ((entries = diskfile_entries_take(&b->header)) == NULL)
463
434
  return -1;
464
- values = map->values;
435
+ entry_map = entries->map;
465
436
 
466
437
  /*
467
438
  * Try to find it in the existing values and update it if it
468
439
  * only has one value.
469
440
  */
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);
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);
473
444
 
474
445
  if (existing->next != NULL) {
475
446
  giterr_set(GITERR_CONFIG, "multivar incompatible with simple set");
@@ -477,7 +448,7 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
477
448
  goto out;
478
449
  }
479
450
 
480
- if (existing->included) {
451
+ if (existing->entry->include_depth) {
481
452
  giterr_set(GITERR_CONFIG, "modifying included variable is not supported");
482
453
  ret = -1;
483
454
  goto out;
@@ -505,17 +476,17 @@ static int config_set(git_config_backend *cfg, const char *name, const char *val
505
476
  ret = config_refresh(cfg);
506
477
 
507
478
  out:
508
- refcounted_strmap_free(map);
479
+ diskfile_entries_free(entries);
509
480
  git__free(esc_value);
510
481
  git__free(key);
511
482
  return ret;
512
483
  }
513
484
 
514
485
  /* release the map containing the entry as an equivalent to freeing it */
515
- static void release_map(git_config_entry *entry)
486
+ static void free_diskfile_entry(git_config_entry *entry)
516
487
  {
517
- refcounted_strmap *map = (refcounted_strmap *) entry->payload;
518
- refcounted_strmap_free(map);
488
+ diskfile_entries *map = (diskfile_entries *) entry->payload;
489
+ diskfile_entries_free(map);
519
490
  }
520
491
 
521
492
  /*
@@ -524,34 +495,34 @@ static void release_map(git_config_entry *entry)
524
495
  static int config_get(git_config_backend *cfg, const char *key, git_config_entry **out)
525
496
  {
526
497
  diskfile_header *h = (diskfile_header *)cfg;
527
- refcounted_strmap *map;
528
- git_strmap *values;
498
+ diskfile_entries *entries;
499
+ git_strmap *entry_map;
529
500
  khiter_t pos;
530
- cvar_t *var;
501
+ config_entry_list *var;
531
502
  int error = 0;
532
503
 
533
504
  if (!h->parent.readonly && ((error = config_refresh(cfg)) < 0))
534
505
  return error;
535
506
 
536
- if ((map = refcounted_strmap_take(h)) == NULL)
507
+ if ((entries = diskfile_entries_take(h)) == NULL)
537
508
  return -1;
538
- values = map->values;
509
+ entry_map = entries->map;
539
510
 
540
- pos = git_strmap_lookup_index(values, key);
511
+ pos = git_strmap_lookup_index(entry_map, key);
541
512
 
542
513
  /* no error message; the config system will write one */
543
- if (!git_strmap_valid_index(values, pos)) {
544
- refcounted_strmap_free(map);
514
+ if (!git_strmap_valid_index(entry_map, pos)) {
515
+ diskfile_entries_free(entries);
545
516
  return GIT_ENOTFOUND;
546
517
  }
547
518
 
548
- var = git_strmap_value_at(values, pos);
519
+ var = git_strmap_value_at(entry_map, pos);
549
520
  while (var->next)
550
521
  var = var->next;
551
522
 
552
523
  *out = var->entry;
553
- (*out)->free = release_map;
554
- (*out)->payload = map;
524
+ (*out)->free = free_diskfile_entry;
525
+ (*out)->payload = entries;
555
526
 
556
527
  return error;
557
528
  }
@@ -591,9 +562,10 @@ out:
591
562
 
592
563
  static int config_delete(git_config_backend *cfg, const char *name)
593
564
  {
594
- cvar_t *var;
565
+ config_entry_list *var;
595
566
  diskfile_backend *b = (diskfile_backend *)cfg;
596
- refcounted_strmap *map; git_strmap *values;
567
+ diskfile_entries *map;
568
+ git_strmap *entry_map;
597
569
  char *key;
598
570
  int result;
599
571
  khiter_t pos;
@@ -601,23 +573,23 @@ static int config_delete(git_config_backend *cfg, const char *name)
601
573
  if ((result = git_config__normalize_name(name, &key)) < 0)
602
574
  return result;
603
575
 
604
- if ((map = refcounted_strmap_take(&b->header)) == NULL)
576
+ if ((map = diskfile_entries_take(&b->header)) == NULL)
605
577
  return -1;
606
- values = b->header.values->values;
578
+ entry_map = b->header.entries->map;
607
579
 
608
- pos = git_strmap_lookup_index(values, key);
580
+ pos = git_strmap_lookup_index(entry_map, key);
609
581
  git__free(key);
610
582
 
611
- if (!git_strmap_valid_index(values, pos)) {
612
- refcounted_strmap_free(map);
583
+ if (!git_strmap_valid_index(entry_map, pos)) {
584
+ diskfile_entries_free(map);
613
585
  giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
614
586
  return GIT_ENOTFOUND;
615
587
  }
616
588
 
617
- var = git_strmap_value_at(values, pos);
618
- refcounted_strmap_free(map);
589
+ var = git_strmap_value_at(entry_map, pos);
590
+ diskfile_entries_free(map);
619
591
 
620
- if (var->included) {
592
+ if (var->entry->include_depth) {
621
593
  giterr_set(GITERR_CONFIG, "cannot delete included variable");
622
594
  return -1;
623
595
  }
@@ -636,8 +608,8 @@ static int config_delete(git_config_backend *cfg, const char *name)
636
608
  static int config_delete_multivar(git_config_backend *cfg, const char *name, const char *regexp)
637
609
  {
638
610
  diskfile_backend *b = (diskfile_backend *)cfg;
639
- refcounted_strmap *map;
640
- git_strmap *values;
611
+ diskfile_entries *map;
612
+ git_strmap *entry_map;
641
613
  char *key;
642
614
  regex_t preg;
643
615
  int result;
@@ -646,20 +618,20 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
646
618
  if ((result = git_config__normalize_name(name, &key)) < 0)
647
619
  return result;
648
620
 
649
- if ((map = refcounted_strmap_take(&b->header)) == NULL)
621
+ if ((map = diskfile_entries_take(&b->header)) == NULL)
650
622
  return -1;
651
- values = b->header.values->values;
623
+ entry_map = b->header.entries->map;
652
624
 
653
- pos = git_strmap_lookup_index(values, key);
625
+ pos = git_strmap_lookup_index(entry_map, key);
654
626
 
655
- if (!git_strmap_valid_index(values, pos)) {
656
- refcounted_strmap_free(map);
627
+ if (!git_strmap_valid_index(entry_map, pos)) {
628
+ diskfile_entries_free(map);
657
629
  git__free(key);
658
630
  giterr_set(GITERR_CONFIG, "could not find key '%s' to delete", name);
659
631
  return GIT_ENOTFOUND;
660
632
  }
661
633
 
662
- refcounted_strmap_free(map);
634
+ diskfile_entries_free(map);
663
635
 
664
636
  result = p_regcomp(&preg, regexp, REG_EXTENDED);
665
637
  if (result != 0) {
@@ -716,7 +688,7 @@ static int config_unlock(git_config_backend *_cfg, int success)
716
688
  }
717
689
 
718
690
  git_filebuf_cleanup(&cfg->locked_buf);
719
- git_buf_free(&cfg->locked_content);
691
+ git_buf_dispose(&cfg->locked_content);
720
692
  cfg->locked = false;
721
693
 
722
694
  return error;
@@ -812,7 +784,7 @@ static void backend_readonly_free(git_config_backend *_backend)
812
784
  if (backend == NULL)
813
785
  return;
814
786
 
815
- refcounted_strmap_free(backend->header.values);
787
+ diskfile_entries_free(backend->header.entries);
816
788
  git_mutex_free(&backend->header.values_mutex);
817
789
  git__free(backend);
818
790
  }
@@ -822,7 +794,7 @@ static int config_readonly_open(git_config_backend *cfg, git_config_level_t leve
822
794
  diskfile_readonly_backend *b = (diskfile_readonly_backend *) cfg;
823
795
  diskfile_backend *src = b->snapshot_from;
824
796
  diskfile_header *src_header = &src->header;
825
- refcounted_strmap *src_map;
797
+ diskfile_entries *entries;
826
798
  int error;
827
799
 
828
800
  if (!src_header->parent.readonly && (error = config_refresh(&src_header->parent)) < 0)
@@ -832,9 +804,9 @@ static int config_readonly_open(git_config_backend *cfg, git_config_level_t leve
832
804
  GIT_UNUSED(level);
833
805
  GIT_UNUSED(repo);
834
806
 
835
- if ((src_map = refcounted_strmap_take(src_header)) == NULL)
807
+ if ((entries = diskfile_entries_take(src_header)) == NULL)
836
808
  return -1;
837
- b->header.values = src_map;
809
+ b->header.entries = entries;
838
810
 
839
811
  return 0;
840
812
  }
@@ -904,33 +876,20 @@ static char *escape_value(const char *ptr)
904
876
  ptr++;
905
877
  }
906
878
 
907
- if (git_buf_oom(&buf)) {
908
- git_buf_free(&buf);
879
+ if (git_buf_oom(&buf))
909
880
  return NULL;
910
- }
911
881
 
912
882
  return git_buf_detach(&buf);
913
883
  }
914
884
 
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
-
923
885
  static int parse_include(git_config_parser *reader,
924
- struct parse_data *parse_data, const char *file)
886
+ diskfile_parse_state *parse_data, const char *file)
925
887
  {
926
888
  struct config_file *include;
927
889
  git_buf path = GIT_BUF_INIT;
928
890
  char *dir;
929
891
  int result;
930
892
 
931
- if (!file)
932
- return 0;
933
-
934
893
  if ((result = git_path_dirname_r(&path, reader->file->path)) < 0)
935
894
  return result;
936
895
 
@@ -946,7 +905,7 @@ static int parse_include(git_config_parser *reader,
946
905
  git_array_init(include->includes);
947
906
  include->path = git_buf_detach(&path);
948
907
 
949
- result = config_read(parse_data->values, parse_data->repo,
908
+ result = config_read(parse_data->entries, parse_data->repo,
950
909
  include, parse_data->level, parse_data->depth+1);
951
910
 
952
911
  if (result == GIT_ENOTFOUND) {
@@ -995,7 +954,7 @@ static int do_match_gitdir(
995
954
  *matches = (error == 0);
996
955
 
997
956
  out:
998
- git_buf_free(&path);
957
+ git_buf_dispose(&path);
999
958
  return error;
1000
959
  }
1001
960
 
@@ -1026,13 +985,13 @@ static const struct {
1026
985
  };
1027
986
 
1028
987
  static int parse_conditional_include(git_config_parser *reader,
1029
- struct parse_data *parse_data, const char *section, const char *file)
988
+ diskfile_parse_state *parse_data, const char *section, const char *file)
1030
989
  {
1031
990
  char *condition;
1032
991
  size_t i;
1033
992
  int error = 0, matches;
1034
993
 
1035
- if (!parse_data->repo || !file)
994
+ if (!parse_data->repo)
1036
995
  return 0;
1037
996
 
1038
997
  condition = git__substrdup(section + strlen("includeIf."),
@@ -1061,64 +1020,60 @@ static int parse_conditional_include(git_config_parser *reader,
1061
1020
  static int read_on_variable(
1062
1021
  git_config_parser *reader,
1063
1022
  const char *current_section,
1064
- char *var_name,
1065
- char *var_value,
1023
+ const char *var_name,
1024
+ const char *var_value,
1066
1025
  const char *line,
1067
1026
  size_t line_len,
1068
1027
  void *data)
1069
1028
  {
1070
- struct parse_data *parse_data = (struct parse_data *)data;
1029
+ diskfile_parse_state *parse_data = (diskfile_parse_state *)data;
1071
1030
  git_buf buf = GIT_BUF_INIT;
1072
- cvar_t *var;
1031
+ git_config_entry *entry;
1032
+ const char *c;
1073
1033
  int result = 0;
1074
1034
 
1075
1035
  GIT_UNUSED(line);
1076
1036
  GIT_UNUSED(line_len);
1077
1037
 
1078
- git__strtolower(var_name);
1079
- git_buf_printf(&buf, "%s.%s", current_section, var_name);
1080
- git__free(var_name);
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));
1081
1042
 
1082
- if (git_buf_oom(&buf)) {
1083
- git__free(var_value);
1043
+ if (git_buf_oom(&buf))
1084
1044
  return -1;
1085
- }
1086
1045
 
1087
- var = git__calloc(1, sizeof(cvar_t));
1088
- GITERR_CHECK_ALLOC(var);
1089
- var->entry = git__calloc(1, sizeof(git_config_entry));
1090
- GITERR_CHECK_ALLOC(var->entry);
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;
1091
1052
 
1092
- var->entry->name = git_buf_detach(&buf);
1093
- var->entry->value = var_value;
1094
- var->entry->level = parse_data->level;
1095
- var->included = !!parse_data->depth;
1096
-
1097
- if ((result = append_entry(parse_data->values, var)) < 0)
1053
+ if ((result = diskfile_entries_append(parse_data->entries, entry)) < 0)
1098
1054
  return result;
1099
1055
 
1100
1056
  result = 0;
1101
1057
 
1102
1058
  /* Add or append the new config option */
1103
- if (!git__strcmp(var->entry->name, "include.path"))
1104
- result = parse_include(reader, parse_data, var->entry->value);
1105
- else if (!git__prefixcmp(var->entry->name, "includeif.") &&
1106
- !git__suffixcmp(var->entry->name, ".path"))
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"))
1107
1063
  result = parse_conditional_include(reader, parse_data,
1108
- var->entry->name, var->entry->value);
1109
-
1064
+ entry->name, entry->value);
1110
1065
 
1111
1066
  return result;
1112
1067
  }
1113
1068
 
1114
1069
  static int config_read(
1115
- git_strmap *values,
1070
+ diskfile_entries *entries,
1116
1071
  const git_repository *repo,
1117
1072
  git_config_file *file,
1118
1073
  git_config_level_t level,
1119
1074
  int depth)
1120
1075
  {
1121
- struct parse_data parse_data;
1076
+ diskfile_parse_state parse_data;
1122
1077
  git_config_parser reader;
1123
1078
  git_buf contents = GIT_BUF_INIT;
1124
1079
  int error;
@@ -1146,14 +1101,14 @@ static int config_read(
1146
1101
 
1147
1102
  parse_data.repo = repo;
1148
1103
  parse_data.file_path = file->path;
1149
- parse_data.values = values;
1104
+ parse_data.entries = entries;
1150
1105
  parse_data.level = level;
1151
1106
  parse_data.depth = depth;
1152
1107
 
1153
1108
  error = git_config_parse(&reader, NULL, read_on_variable, NULL, NULL, &parse_data);
1154
1109
 
1155
1110
  out:
1156
- git_buf_free(&contents);
1111
+ git_buf_dispose(&contents);
1157
1112
  return error;
1158
1113
  }
1159
1114
 
@@ -1182,7 +1137,7 @@ static int write_section(git_buf *fbuf, const char *key)
1182
1137
  return -1;
1183
1138
 
1184
1139
  result = git_buf_put(fbuf, git_buf_cstr(&buf), buf.size);
1185
- git_buf_free(&buf);
1140
+ git_buf_dispose(&buf);
1186
1141
 
1187
1142
  return result;
1188
1143
  }
@@ -1291,8 +1246,8 @@ static int write_on_section(
1291
1246
  static int write_on_variable(
1292
1247
  git_config_parser *reader,
1293
1248
  const char *current_section,
1294
- char *var_name,
1295
- char *var_value,
1249
+ const char *var_name,
1250
+ const char *var_value,
1296
1251
  const char *line,
1297
1252
  size_t line_len,
1298
1253
  void *data)
@@ -1321,9 +1276,6 @@ static int write_on_variable(
1321
1276
  if (has_matched && write_data->preg != NULL)
1322
1277
  has_matched = (regexec(write_data->preg, var_value, 0, NULL, 0) == 0);
1323
1278
 
1324
- git__free(var_name);
1325
- git__free(var_value);
1326
-
1327
1279
  /* If this isn't the name/value we're looking for, simply dump the
1328
1280
  * existing data back out and continue on.
1329
1281
  */
@@ -1401,7 +1353,7 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1401
1353
  /* Lock the file */
1402
1354
  if ((result = git_filebuf_open(
1403
1355
  &file, cfg->file.path, GIT_FILEBUF_HASH_CONTENTS, GIT_CONFIG_FILE_MODE)) < 0) {
1404
- git_buf_free(&contents);
1356
+ git_buf_dispose(&contents);
1405
1357
  return result;
1406
1358
  }
1407
1359
 
@@ -1446,7 +1398,7 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1446
1398
  &write_data);
1447
1399
  git__free(section);
1448
1400
  git__free(orig_section);
1449
- git_buf_free(&write_data.buffered_comment);
1401
+ git_buf_dispose(&write_data.buffered_comment);
1450
1402
 
1451
1403
  if (result < 0) {
1452
1404
  git_filebuf_cleanup(&file);
@@ -1456,7 +1408,7 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1456
1408
  if (cfg->locked) {
1457
1409
  size_t len = buf.asize;
1458
1410
  /* Update our copy with the modified contents */
1459
- git_buf_free(&cfg->locked_content);
1411
+ git_buf_dispose(&cfg->locked_content);
1460
1412
  git_buf_attach(&cfg->locked_content, git_buf_detach(&buf), len);
1461
1413
  } else {
1462
1414
  git_filebuf_write(&file, git_buf_cstr(&buf), git_buf_len(&buf));
@@ -1464,8 +1416,8 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
1464
1416
  }
1465
1417
 
1466
1418
  done:
1467
- git_buf_free(&buf);
1468
- git_buf_free(&contents);
1419
+ git_buf_dispose(&buf);
1420
+ git_buf_dispose(&contents);
1469
1421
  git_parse_ctx_clear(&reader.ctx);
1470
1422
  return result;
1471
1423
  }