rugged 0.22.2 → 0.23.0b1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/ext/rugged/rugged.c +1 -2
  3. data/ext/rugged/rugged_branch_collection.c +6 -44
  4. data/ext/rugged/rugged_config.c +7 -3
  5. data/ext/rugged/rugged_diff_delta.c +1 -1
  6. data/ext/rugged/rugged_diff_line.c +1 -1
  7. data/ext/rugged/rugged_object.c +2 -2
  8. data/ext/rugged/rugged_reference_collection.c +12 -56
  9. data/ext/rugged/rugged_remote.c +4 -33
  10. data/ext/rugged/rugged_remote_collection.c +1 -1
  11. data/ext/rugged/rugged_repo.c +10 -36
  12. data/ext/rugged/rugged_settings.c +3 -3
  13. data/ext/rugged/rugged_tree.c +1 -1
  14. data/lib/rugged/version.rb +1 -1
  15. data/vendor/libgit2/CMakeLists.txt +10 -3
  16. data/vendor/libgit2/COPYING +15 -21
  17. data/vendor/libgit2/include/git2/annotated_commit.h +20 -3
  18. data/vendor/libgit2/include/git2/branch.h +20 -16
  19. data/vendor/libgit2/include/git2/checkout.h +32 -18
  20. data/vendor/libgit2/include/git2/cherrypick.h +2 -2
  21. data/vendor/libgit2/include/git2/clone.h +4 -10
  22. data/vendor/libgit2/include/git2/config.h +66 -12
  23. data/vendor/libgit2/include/git2/describe.h +3 -2
  24. data/vendor/libgit2/include/git2/diff.h +3 -3
  25. data/vendor/libgit2/include/git2/errors.h +1 -0
  26. data/vendor/libgit2/include/git2/filter.h +21 -5
  27. data/vendor/libgit2/include/git2/index.h +32 -0
  28. data/vendor/libgit2/include/git2/merge.h +20 -3
  29. data/vendor/libgit2/include/git2/oid.h +1 -1
  30. data/vendor/libgit2/include/git2/pack.h +13 -0
  31. data/vendor/libgit2/include/git2/patch.h +3 -6
  32. data/vendor/libgit2/include/git2/rebase.h +8 -12
  33. data/vendor/libgit2/include/git2/refs.h +19 -29
  34. data/vendor/libgit2/include/git2/remote.h +5 -11
  35. data/vendor/libgit2/include/git2/repository.h +44 -15
  36. data/vendor/libgit2/include/git2/reset.h +19 -10
  37. data/vendor/libgit2/include/git2/revert.h +2 -2
  38. data/vendor/libgit2/include/git2/submodule.h +3 -9
  39. data/vendor/libgit2/include/git2/sys/config.h +3 -1
  40. data/vendor/libgit2/include/git2/sys/filter.h +10 -2
  41. data/vendor/libgit2/include/git2/sys/hashsig.h +49 -22
  42. data/vendor/libgit2/include/git2/transport.h +1 -1
  43. data/vendor/libgit2/include/git2/types.h +10 -3
  44. data/vendor/libgit2/include/git2/version.h +3 -2
  45. data/vendor/libgit2/src/annotated_commit.c +28 -0
  46. data/vendor/libgit2/src/array.h +19 -8
  47. data/vendor/libgit2/src/attr.c +95 -35
  48. data/vendor/libgit2/src/attr_file.c +51 -17
  49. data/vendor/libgit2/src/attr_file.h +37 -10
  50. data/vendor/libgit2/src/attrcache.c +13 -7
  51. data/vendor/libgit2/src/attrcache.h +1 -0
  52. data/vendor/libgit2/src/blame.c +26 -2
  53. data/vendor/libgit2/src/blame_git.c +6 -2
  54. data/vendor/libgit2/src/blob.c +6 -8
  55. data/vendor/libgit2/src/branch.c +55 -43
  56. data/vendor/libgit2/src/buf_text.c +13 -6
  57. data/vendor/libgit2/src/buffer.c +110 -25
  58. data/vendor/libgit2/src/buffer.h +18 -0
  59. data/vendor/libgit2/src/checkout.c +164 -92
  60. data/vendor/libgit2/src/checkout.h +0 -7
  61. data/vendor/libgit2/src/cherrypick.c +13 -7
  62. data/vendor/libgit2/src/clone.c +23 -25
  63. data/vendor/libgit2/src/commit.c +3 -3
  64. data/vendor/libgit2/src/common.h +23 -1
  65. data/vendor/libgit2/src/config.c +137 -19
  66. data/vendor/libgit2/src/config.h +2 -2
  67. data/vendor/libgit2/src/config_cache.c +2 -1
  68. data/vendor/libgit2/src/config_file.c +39 -18
  69. data/vendor/libgit2/src/config_file.h +1 -1
  70. data/vendor/libgit2/src/crlf.c +1 -1
  71. data/vendor/libgit2/src/delta-apply.c +3 -2
  72. data/vendor/libgit2/src/delta.c +25 -6
  73. data/vendor/libgit2/src/describe.c +2 -0
  74. data/vendor/libgit2/src/diff.c +8 -5
  75. data/vendor/libgit2/src/diff_driver.c +39 -18
  76. data/vendor/libgit2/src/diff_file.c +1 -1
  77. data/vendor/libgit2/src/diff_patch.c +12 -6
  78. data/vendor/libgit2/src/diff_tform.c +21 -24
  79. data/vendor/libgit2/src/filebuf.c +14 -12
  80. data/vendor/libgit2/src/fileops.c +61 -18
  81. data/vendor/libgit2/src/fileops.h +11 -2
  82. data/vendor/libgit2/src/filter.c +351 -99
  83. data/vendor/libgit2/src/filter.h +17 -0
  84. data/vendor/libgit2/src/global.c +38 -9
  85. data/vendor/libgit2/src/hash/hash_generic.c +1 -1
  86. data/vendor/libgit2/src/hashsig.c +28 -16
  87. data/vendor/libgit2/src/ignore.c +2 -2
  88. data/vendor/libgit2/src/index.c +159 -42
  89. data/vendor/libgit2/src/index.h +29 -0
  90. data/vendor/libgit2/src/indexer.c +11 -2
  91. data/vendor/libgit2/src/integer.h +96 -0
  92. data/vendor/libgit2/src/iterator.c +5 -3
  93. data/vendor/libgit2/src/khash.h +41 -29
  94. data/vendor/libgit2/src/merge.c +48 -35
  95. data/vendor/libgit2/src/merge.h +0 -1
  96. data/vendor/libgit2/src/merge_file.c +13 -0
  97. data/vendor/libgit2/src/mwindow.c +1 -1
  98. data/vendor/libgit2/src/notes.c +1 -1
  99. data/vendor/libgit2/src/odb.c +13 -11
  100. data/vendor/libgit2/src/odb_loose.c +22 -10
  101. data/vendor/libgit2/src/odb_mempack.c +4 -2
  102. data/vendor/libgit2/src/offmap.h +3 -2
  103. data/vendor/libgit2/src/oid.c +1 -1
  104. data/vendor/libgit2/src/oidmap.h +2 -1
  105. data/vendor/libgit2/src/openssl_stream.c +6 -3
  106. data/vendor/libgit2/src/pack-objects.c +273 -12
  107. data/vendor/libgit2/src/pack-objects.h +10 -0
  108. data/vendor/libgit2/src/pack.c +17 -6
  109. data/vendor/libgit2/src/pack.h +1 -3
  110. data/vendor/libgit2/src/path.c +68 -38
  111. data/vendor/libgit2/src/pathspec.c +3 -0
  112. data/vendor/libgit2/src/pool.c +9 -8
  113. data/vendor/libgit2/src/posix.c +11 -1
  114. data/vendor/libgit2/src/push.c +15 -17
  115. data/vendor/libgit2/src/push.h +1 -6
  116. data/vendor/libgit2/src/rebase.c +77 -35
  117. data/vendor/libgit2/src/refdb_fs.c +2 -2
  118. data/vendor/libgit2/src/refs.c +107 -81
  119. data/vendor/libgit2/src/refs.h +2 -2
  120. data/vendor/libgit2/src/refspec.c +3 -0
  121. data/vendor/libgit2/src/remote.c +19 -21
  122. data/vendor/libgit2/src/repository.c +258 -67
  123. data/vendor/libgit2/src/repository.h +31 -16
  124. data/vendor/libgit2/src/reset.c +28 -12
  125. data/vendor/libgit2/src/revert.c +12 -7
  126. data/vendor/libgit2/src/revwalk.c +3 -5
  127. data/vendor/libgit2/src/revwalk.h +1 -1
  128. data/vendor/libgit2/src/sortedcache.c +5 -3
  129. data/vendor/libgit2/src/stash.c +3 -5
  130. data/vendor/libgit2/src/strmap.h +2 -1
  131. data/vendor/libgit2/src/submodule.c +5 -6
  132. data/vendor/libgit2/src/tag.c +7 -5
  133. data/vendor/libgit2/src/transaction.c +1 -1
  134. data/vendor/libgit2/src/transports/cred.c +5 -2
  135. data/vendor/libgit2/src/transports/git.c +2 -3
  136. data/vendor/libgit2/src/transports/local.c +15 -34
  137. data/vendor/libgit2/src/transports/smart.c +1 -1
  138. data/vendor/libgit2/src/transports/smart_pkt.c +58 -18
  139. data/vendor/libgit2/src/transports/smart_protocol.c +2 -2
  140. data/vendor/libgit2/src/transports/winhttp.c +2 -2
  141. data/vendor/libgit2/src/tree.c +7 -5
  142. data/vendor/libgit2/src/tsort.c +3 -1
  143. data/vendor/libgit2/src/util.c +25 -0
  144. data/vendor/libgit2/src/util.h +31 -27
  145. data/vendor/libgit2/src/vector.c +2 -7
  146. data/vendor/libgit2/src/win32/dir.c +5 -3
  147. data/vendor/libgit2/src/win32/git2.rc +8 -4
  148. data/vendor/libgit2/src/win32/mingw-compat.h +7 -0
  149. data/vendor/libgit2/src/win32/msvc-compat.h +3 -0
  150. data/vendor/libgit2/src/win32/posix.h +1 -3
  151. data/vendor/libgit2/src/win32/posix_w32.c +31 -7
  152. data/vendor/libgit2/src/win32/utf-conv.c +1 -3
  153. data/vendor/libgit2/src/zstream.c +1 -1
  154. metadata +5 -5
  155. data/vendor/libgit2/src/bswap.h +0 -97
@@ -12,13 +12,6 @@
12
12
 
13
13
  #define GIT_CHECKOUT__NOTIFY_CONFLICT_TREE (1u << 12)
14
14
 
15
- /** Internal structure; this is exposed in future versions. */
16
- typedef struct {
17
- size_t mkdir_calls;
18
- size_t stat_calls;
19
- size_t chmod_calls;
20
- } git_checkout_perfdata;
21
-
22
15
  /**
23
16
  * Update the working directory to match the target iterator. The
24
17
  * expected baseline value can be passed in via the checkout options
@@ -10,6 +10,7 @@
10
10
  #include "filebuf.h"
11
11
  #include "merge.h"
12
12
  #include "vector.h"
13
+ #include "index.h"
13
14
 
14
15
  #include "git2/types.h"
15
16
  #include "git2/merge.h"
@@ -71,7 +72,7 @@ static int cherrypick_normalize_opts(
71
72
  const char *their_label)
72
73
  {
73
74
  int error = 0;
74
- unsigned int default_checkout_strategy = GIT_CHECKOUT_SAFE_CREATE |
75
+ unsigned int default_checkout_strategy = GIT_CHECKOUT_SAFE |
75
76
  GIT_CHECKOUT_ALLOW_CONFLICTS;
76
77
 
77
78
  GIT_UNUSED(repo);
@@ -171,7 +172,8 @@ int git_cherrypick(
171
172
  char commit_oidstr[GIT_OID_HEXSZ + 1];
172
173
  const char *commit_msg, *commit_summary;
173
174
  git_buf their_label = GIT_BUF_INIT;
174
- git_index *index_new = NULL;
175
+ git_index *index = NULL;
176
+ git_indexwriter indexwriter = GIT_INDEXWRITER_INIT;
175
177
  int error = 0;
176
178
 
177
179
  assert(repo && commit);
@@ -192,21 +194,25 @@ int git_cherrypick(
192
194
  if ((error = write_merge_msg(repo, commit_msg)) < 0 ||
193
195
  (error = git_buf_printf(&their_label, "%.7s... %s", commit_oidstr, commit_summary)) < 0 ||
194
196
  (error = cherrypick_normalize_opts(repo, &opts, given_opts, git_buf_cstr(&their_label))) < 0 ||
197
+ (error = git_indexwriter_init_for_operation(&indexwriter, repo, &opts.checkout_opts.checkout_strategy)) < 0 ||
195
198
  (error = write_cherrypick_head(repo, commit_oidstr)) < 0 ||
196
199
  (error = git_repository_head(&our_ref, repo)) < 0 ||
197
200
  (error = git_reference_peel((git_object **)&our_commit, our_ref, GIT_OBJ_COMMIT)) < 0 ||
198
- (error = git_cherrypick_commit(&index_new, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
199
- (error = git_merge__check_result(repo, index_new)) < 0 ||
200
- (error = git_merge__append_conflicts_to_merge_msg(repo, index_new)) < 0 ||
201
- (error = git_checkout_index(repo, index_new, &opts.checkout_opts)) < 0)
201
+ (error = git_cherrypick_commit(&index, repo, commit, our_commit, opts.mainline, &opts.merge_opts)) < 0 ||
202
+ (error = git_merge__check_result(repo, index)) < 0 ||
203
+ (error = git_merge__append_conflicts_to_merge_msg(repo, index)) < 0 ||
204
+ (error = git_checkout_index(repo, index, &opts.checkout_opts)) < 0 ||
205
+ (error = git_indexwriter_commit(&indexwriter)) < 0)
202
206
  goto on_error;
207
+
203
208
  goto done;
204
209
 
205
210
  on_error:
206
211
  cherrypick_state_cleanup(repo);
207
212
 
208
213
  done:
209
- git_index_free(index_new);
214
+ git_indexwriter_cleanup(&indexwriter);
215
+ git_index_free(index);
210
216
  git_commit_free(our_commit);
211
217
  git_reference_free(our_ref);
212
218
  git_buf_free(&their_label);
@@ -24,18 +24,18 @@
24
24
  #include "repository.h"
25
25
  #include "odb.h"
26
26
 
27
- static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature);
27
+ static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link);
28
28
 
29
29
  static int create_branch(
30
30
  git_reference **branch,
31
31
  git_repository *repo,
32
32
  const git_oid *target,
33
33
  const char *name,
34
- const git_signature *signature,
35
34
  const char *log_message)
36
35
  {
37
36
  git_commit *head_obj = NULL;
38
37
  git_reference *branch_ref = NULL;
38
+ git_buf refname = GIT_BUF_INIT;
39
39
  int error;
40
40
 
41
41
  /* Find the target commit */
@@ -43,8 +43,11 @@ static int create_branch(
43
43
  return error;
44
44
 
45
45
  /* Create the new branch */
46
- error = git_branch_create(&branch_ref, repo, name, head_obj, 0, signature, log_message);
46
+ if ((error = git_buf_printf(&refname, GIT_REFS_HEADS_DIR "%s", name)) < 0)
47
+ return error;
47
48
 
49
+ error = git_reference_create(&branch_ref, repo, git_buf_cstr(&refname), target, 0, log_message);
50
+ git_buf_free(&refname);
48
51
  git_commit_free(head_obj);
49
52
 
50
53
  if (!error)
@@ -93,12 +96,11 @@ static int create_tracking_branch(
93
96
  git_repository *repo,
94
97
  const git_oid *target,
95
98
  const char *branch_name,
96
- const git_signature *signature,
97
99
  const char *log_message)
98
100
  {
99
101
  int error;
100
102
 
101
- if ((error = create_branch(branch, repo, target, branch_name, signature, log_message)) < 0)
103
+ if ((error = create_branch(branch, repo, target, branch_name, log_message)) < 0)
102
104
  return error;
103
105
 
104
106
  return setup_tracking_config(
@@ -112,7 +114,6 @@ static int update_head_to_new_branch(
112
114
  git_repository *repo,
113
115
  const git_oid *target,
114
116
  const char *name,
115
- const git_signature *signature,
116
117
  const char *reflog_message)
117
118
  {
118
119
  git_reference *tracking_branch = NULL;
@@ -122,12 +123,11 @@ static int update_head_to_new_branch(
122
123
  name += strlen(GIT_REFS_HEADS_DIR);
123
124
 
124
125
  error = create_tracking_branch(&tracking_branch, repo, target, name,
125
- signature, reflog_message);
126
+ reflog_message);
126
127
 
127
128
  if (!error)
128
129
  error = git_repository_set_head(
129
- repo, git_reference_name(tracking_branch),
130
- signature, reflog_message);
130
+ repo, git_reference_name(tracking_branch));
131
131
 
132
132
  git_reference_free(tracking_branch);
133
133
 
@@ -141,7 +141,6 @@ static int update_head_to_new_branch(
141
141
  static int update_head_to_remote(
142
142
  git_repository *repo,
143
143
  git_remote *remote,
144
- const git_signature *signature,
145
144
  const char *reflog_message)
146
145
  {
147
146
  int error = 0;
@@ -169,7 +168,7 @@ static int update_head_to_remote(
169
168
  error = git_remote_default_branch(&branch, remote);
170
169
  if (error == GIT_ENOTFOUND) {
171
170
  error = git_repository_set_head_detached(
172
- repo, remote_head_id, signature, reflog_message);
171
+ repo, remote_head_id);
173
172
  goto cleanup;
174
173
  }
175
174
 
@@ -192,7 +191,7 @@ static int update_head_to_remote(
192
191
  repo,
193
192
  remote_head_id,
194
193
  git_buf_cstr(&branch),
195
- signature, reflog_message);
194
+ reflog_message);
196
195
 
197
196
  cleanup:
198
197
  git_buf_free(&remote_master_name);
@@ -205,7 +204,6 @@ static int update_head_to_branch(
205
204
  git_repository *repo,
206
205
  const char *remote_name,
207
206
  const char *branch,
208
- const git_signature *signature,
209
207
  const char *reflog_message)
210
208
  {
211
209
  int retcode;
@@ -222,7 +220,7 @@ static int update_head_to_branch(
222
220
  goto cleanup;
223
221
 
224
222
  retcode = update_head_to_new_branch(repo, git_reference_target(remote_ref), branch,
225
- signature, reflog_message);
223
+ reflog_message);
226
224
 
227
225
  cleanup:
228
226
  git_reference_free(remote_ref);
@@ -313,16 +311,16 @@ static bool should_checkout(
313
311
  return !git_repository_head_unborn(repo);
314
312
  }
315
313
 
316
- static int checkout_branch(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature, const char *reflog_message)
314
+ static int checkout_branch(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, const char *reflog_message)
317
315
  {
318
316
  int error;
319
317
 
320
318
  if (branch)
321
319
  error = update_head_to_branch(repo, git_remote_name(remote), branch,
322
- signature, reflog_message);
320
+ reflog_message);
323
321
  /* Point HEAD to the same ref as the remote's head */
324
322
  else
325
- error = update_head_to_remote(repo, remote, signature, reflog_message);
323
+ error = update_head_to_remote(repo, remote, reflog_message);
326
324
 
327
325
  if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts))
328
326
  error = git_checkout_head(repo, co_opts);
@@ -330,7 +328,7 @@ static int checkout_branch(git_repository *repo, git_remote *remote, const git_c
330
328
  return error;
331
329
  }
332
330
 
333
- static int clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature)
331
+ static int clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch)
334
332
  {
335
333
  int error;
336
334
  git_buf reflog_message = GIT_BUF_INIT;
@@ -358,10 +356,10 @@ static int clone_into(git_repository *repo, git_remote *_remote, const git_check
358
356
  git_remote_set_update_fetchhead(remote, 0);
359
357
  git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote));
360
358
 
361
- if ((error = git_remote_fetch(remote, NULL, signature, git_buf_cstr(&reflog_message))) != 0)
359
+ if ((error = git_remote_fetch(remote, NULL, git_buf_cstr(&reflog_message))) != 0)
362
360
  goto cleanup;
363
361
 
364
- error = checkout_branch(repo, remote, co_opts, branch, signature, git_buf_cstr(&reflog_message));
362
+ error = checkout_branch(repo, remote, co_opts, branch, git_buf_cstr(&reflog_message));
365
363
 
366
364
  cleanup:
367
365
  git_remote_free(remote);
@@ -442,11 +440,11 @@ int git_clone(
442
440
  if (clone_local == 1)
443
441
  error = clone_local_into(
444
442
  repo, origin, &options.checkout_opts,
445
- options.checkout_branch, link, options.signature);
443
+ options.checkout_branch, link);
446
444
  else if (clone_local == 0)
447
445
  error = clone_into(
448
446
  repo, origin, &options.checkout_opts,
449
- options.checkout_branch, options.signature);
447
+ options.checkout_branch);
450
448
  else
451
449
  error = -1;
452
450
 
@@ -508,7 +506,7 @@ static bool can_link(const char *src, const char *dst, int link)
508
506
  #endif
509
507
  }
510
508
 
511
- static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link, const git_signature *signature)
509
+ static int clone_local_into(git_repository *repo, git_remote *remote, const git_checkout_options *co_opts, const char *branch, int link)
512
510
  {
513
511
  int error, flags;
514
512
  git_repository *src;
@@ -553,10 +551,10 @@ static int clone_local_into(git_repository *repo, git_remote *remote, const git_
553
551
 
554
552
  git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote));
555
553
 
556
- if ((error = git_remote_fetch(remote, NULL, signature, git_buf_cstr(&reflog_message))) != 0)
554
+ if ((error = git_remote_fetch(remote, NULL, git_buf_cstr(&reflog_message))) != 0)
557
555
  goto cleanup;
558
556
 
559
- error = checkout_branch(repo, remote, co_opts, branch, signature, git_buf_cstr(&reflog_message));
557
+ error = checkout_branch(repo, remote, co_opts, branch, git_buf_cstr(&reflog_message));
560
558
 
561
559
  cleanup:
562
560
  git_buf_free(&reflog_message);
@@ -104,7 +104,7 @@ int git_commit_create_from_callback(
104
104
 
105
105
  if (update_ref != NULL) {
106
106
  error = git_reference__update_for_commit(
107
- repo, ref, update_ref, id, committer, "commit");
107
+ repo, ref, update_ref, id, "commit");
108
108
  git_reference_free(ref);
109
109
  return error;
110
110
  }
@@ -295,7 +295,7 @@ int git_commit_amend(
295
295
 
296
296
  if (!error && update_ref) {
297
297
  error = git_reference__update_for_commit(
298
- repo, ref, NULL, id, committer, "commit");
298
+ repo, ref, NULL, id, "commit");
299
299
  git_reference_free(ref);
300
300
  }
301
301
 
@@ -400,7 +400,7 @@ GIT_COMMIT_GETTER(const char *, raw_header, commit->raw_header)
400
400
  GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time)
401
401
  GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset)
402
402
  GIT_COMMIT_GETTER(unsigned int, parentcount, (unsigned int)git_array_size(commit->parent_ids))
403
- GIT_COMMIT_GETTER(const git_oid *, tree_id, &commit->tree_id);
403
+ GIT_COMMIT_GETTER(const git_oid *, tree_id, &commit->tree_id)
404
404
 
405
405
  const char *git_commit_message(const git_commit *commit)
406
406
  {
@@ -17,6 +17,11 @@
17
17
  # define GIT_INLINE(type) static inline type
18
18
  #endif
19
19
 
20
+ /** Support for gcc/clang __has_builtin intrinsic */
21
+ #ifndef __has_builtin
22
+ # define __has_builtin(x) 0
23
+ #endif
24
+
20
25
  #include <assert.h>
21
26
  #include <errno.h>
22
27
  #include <limits.h>
@@ -59,7 +64,7 @@
59
64
  #include "git2/types.h"
60
65
  #include "git2/errors.h"
61
66
  #include "thread-utils.h"
62
- #include "bswap.h"
67
+ #include "integer.h"
63
68
 
64
69
  #include <regex.h>
65
70
 
@@ -176,6 +181,23 @@ GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int v
176
181
  GITERR_CHECK_VERSION(&(VERSION), _tmpl.version, #TYPE); \
177
182
  memcpy((PTR), &_tmpl, sizeof(_tmpl)); } while (0)
178
183
 
184
+
185
+ /** Check for additive overflow, setting an error if would occur. */
186
+ #define GIT_ADD_SIZET_OVERFLOW(out, one, two) \
187
+ (git__add_sizet_overflow(out, one, two) ? (giterr_set_oom(), 1) : 0)
188
+
189
+ /** Check for additive overflow, setting an error if would occur. */
190
+ #define GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize) \
191
+ (git__multiply_sizet_overflow(out, nelem, elsize) ? (giterr_set_oom(), 1) : 0)
192
+
193
+ /** Check for additive overflow, failing if it would occur. */
194
+ #define GITERR_CHECK_ALLOC_ADD(out, one, two) \
195
+ if (GIT_ADD_SIZET_OVERFLOW(out, one, two)) { return -1; }
196
+
197
+ /** Check for multiplicative overflow, failing if it would occur. */
198
+ #define GITERR_CHECK_ALLOC_MULTIPLY(out, nelem, elsize) \
199
+ if (GIT_MULTIPLY_SIZET_OVERFLOW(out, nelem, elsize)) { return -1; }
200
+
179
201
  /* NOTE: other giterr functions are in the public errors.h header file */
180
202
 
181
203
  #include "util.h"
@@ -19,6 +19,14 @@
19
19
 
20
20
  #include <ctype.h>
21
21
 
22
+ void git_config_entry_free(git_config_entry *entry)
23
+ {
24
+ if (!entry)
25
+ return;
26
+
27
+ entry->free(entry);
28
+ }
29
+
22
30
  typedef struct {
23
31
  git_refcount rc;
24
32
 
@@ -638,7 +646,7 @@ int git_config__update_entry(
638
646
  bool only_if_existing)
639
647
  {
640
648
  int error = 0;
641
- const git_config_entry *ce = NULL;
649
+ git_config_entry *ce = NULL;
642
650
 
643
651
  if ((error = git_config__lookup_entry(&ce, config, key, false)) < 0)
644
652
  return error;
@@ -657,6 +665,7 @@ int git_config__update_entry(
657
665
  else
658
666
  error = git_config_set_string(config, key, value);
659
667
 
668
+ git_config_entry_free(ce);
660
669
  return error;
661
670
  }
662
671
 
@@ -677,7 +686,7 @@ enum {
677
686
  };
678
687
 
679
688
  static int get_entry(
680
- const git_config_entry **out,
689
+ git_config_entry **out,
681
690
  const git_config *cfg,
682
691
  const char *name,
683
692
  bool normalize_name,
@@ -721,13 +730,13 @@ cleanup:
721
730
  }
722
731
 
723
732
  int git_config_get_entry(
724
- const git_config_entry **out, const git_config *cfg, const char *name)
733
+ git_config_entry **out, const git_config *cfg, const char *name)
725
734
  {
726
735
  return get_entry(out, cfg, name, true, GET_ALL_ERRORS);
727
736
  }
728
737
 
729
738
  int git_config__lookup_entry(
730
- const git_config_entry **out,
739
+ git_config_entry **out,
731
740
  const git_config *cfg,
732
741
  const char *key,
733
742
  bool no_errors)
@@ -743,76 +752,154 @@ int git_config_get_mapped(
743
752
  const git_cvar_map *maps,
744
753
  size_t map_n)
745
754
  {
746
- const git_config_entry *entry;
755
+ git_config_entry *entry;
747
756
  int ret;
748
757
 
749
758
  if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
750
759
  return ret;
751
760
 
752
- return git_config_lookup_map_value(out, maps, map_n, entry->value);
761
+ ret = git_config_lookup_map_value(out, maps, map_n, entry->value);
762
+ git_config_entry_free(entry);
763
+
764
+ return ret;
753
765
  }
754
766
 
755
767
  int git_config_get_int64(int64_t *out, const git_config *cfg, const char *name)
756
768
  {
757
- const git_config_entry *entry;
769
+ git_config_entry *entry;
758
770
  int ret;
759
771
 
760
772
  if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
761
773
  return ret;
762
774
 
763
- return git_config_parse_int64(out, entry->value);
775
+ ret = git_config_parse_int64(out, entry->value);
776
+ git_config_entry_free(entry);
777
+
778
+ return ret;
764
779
  }
765
780
 
766
781
  int git_config_get_int32(int32_t *out, const git_config *cfg, const char *name)
767
782
  {
768
- const git_config_entry *entry;
783
+ git_config_entry *entry;
769
784
  int ret;
770
785
 
771
786
  if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
772
787
  return ret;
773
788
 
774
- return git_config_parse_int32(out, entry->value);
789
+ ret = git_config_parse_int32(out, entry->value);
790
+ git_config_entry_free(entry);
791
+
792
+ return ret;
775
793
  }
776
794
 
777
795
  int git_config_get_bool(int *out, const git_config *cfg, const char *name)
778
796
  {
779
- const git_config_entry *entry;
797
+ git_config_entry *entry;
780
798
  int ret;
781
799
 
782
800
  if ((ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
783
801
  return ret;
784
802
 
785
- return git_config_parse_bool(out, entry->value);
803
+ ret = git_config_parse_bool(out, entry->value);
804
+ git_config_entry_free(entry);
805
+
806
+ return ret;
807
+ }
808
+
809
+ static int is_readonly(const git_config *cfg)
810
+ {
811
+ size_t i;
812
+ file_internal *internal;
813
+
814
+ git_vector_foreach(&cfg->files, i, internal) {
815
+ if (!internal || !internal->file)
816
+ continue;
817
+
818
+ if (!internal->file->readonly)
819
+ return 0;
820
+ }
821
+
822
+ return 1;
823
+ }
824
+
825
+ int git_config_get_path(git_buf *out, const git_config *cfg, const char *name)
826
+ {
827
+ git_config_entry *entry;
828
+ int error;
829
+
830
+ if ((error = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS)) < 0)
831
+ return error;
832
+
833
+ error = git_config_parse_path(out, entry->value);
834
+ git_config_entry_free(entry);
835
+
836
+ return error;
786
837
  }
787
838
 
788
839
  int git_config_get_string(
789
840
  const char **out, const git_config *cfg, const char *name)
790
841
  {
791
- const git_config_entry *entry;
792
- int ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS);
842
+ git_config_entry *entry;
843
+ int ret;
844
+
845
+ if (!is_readonly(cfg)) {
846
+ giterr_set(GITERR_CONFIG, "get_string called on a live config object");
847
+ return -1;
848
+ }
849
+
850
+ ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS);
793
851
  *out = !ret ? (entry->value ? entry->value : "") : NULL;
852
+
853
+ git_config_entry_free(entry);
854
+
794
855
  return ret;
795
856
  }
796
857
 
797
- const char *git_config__get_string_force(
858
+ int git_config_get_string_buf(
859
+ git_buf *out, const git_config *cfg, const char *name)
860
+ {
861
+ git_config_entry *entry;
862
+ int ret;
863
+ const char *str;
864
+
865
+ git_buf_sanitize(out);
866
+
867
+ ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS);
868
+ str = !ret ? (entry->value ? entry->value : "") : NULL;
869
+
870
+ if (str)
871
+ ret = git_buf_puts(out, str);
872
+
873
+ git_config_entry_free(entry);
874
+
875
+ return ret;
876
+ }
877
+
878
+ char *git_config__get_string_force(
798
879
  const git_config *cfg, const char *key, const char *fallback_value)
799
880
  {
800
- const git_config_entry *entry;
881
+ git_config_entry *entry;
882
+ char *ret;
883
+
801
884
  get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
802
- return (entry && entry->value) ? entry->value : fallback_value;
885
+ ret = (entry && entry->value) ? git__strdup(entry->value) : fallback_value ? git__strdup(fallback_value) : NULL;
886
+ git_config_entry_free(entry);
887
+
888
+ return ret;
803
889
  }
804
890
 
805
891
  int git_config__get_bool_force(
806
892
  const git_config *cfg, const char *key, int fallback_value)
807
893
  {
808
894
  int val = fallback_value;
809
- const git_config_entry *entry;
895
+ git_config_entry *entry;
810
896
 
811
897
  get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
812
898
 
813
899
  if (entry && git_config_parse_bool(&val, entry->value) < 0)
814
900
  giterr_clear();
815
901
 
902
+ git_config_entry_free(entry);
816
903
  return val;
817
904
  }
818
905
 
@@ -820,13 +907,14 @@ int git_config__get_int_force(
820
907
  const git_config *cfg, const char *key, int fallback_value)
821
908
  {
822
909
  int32_t val = (int32_t)fallback_value;
823
- const git_config_entry *entry;
910
+ git_config_entry *entry;
824
911
 
825
912
  get_entry(&entry, cfg, key, false, GET_NO_ERRORS);
826
913
 
827
914
  if (entry && git_config_parse_int32(&val, entry->value) < 0)
828
915
  giterr_clear();
829
916
 
917
+ git_config_entry_free(entry);
830
918
  return (int)val;
831
919
  }
832
920
 
@@ -1184,6 +1272,36 @@ fail_parse:
1184
1272
  return -1;
1185
1273
  }
1186
1274
 
1275
+ int git_config_parse_path(git_buf *out, const char *value)
1276
+ {
1277
+ int error = 0;
1278
+ const git_buf *home;
1279
+
1280
+ assert(out && value);
1281
+
1282
+ git_buf_sanitize(out);
1283
+
1284
+ if (value[0] == '~') {
1285
+ if (value[1] != '\0' && value[1] != '/') {
1286
+ giterr_set(GITERR_CONFIG, "retrieving a homedir by name is not supported");
1287
+ return -1;
1288
+ }
1289
+
1290
+ if ((error = git_sysdir_get(&home, GIT_SYSDIR_GLOBAL)) < 0)
1291
+ return error;
1292
+
1293
+ git_buf_sets(out, home->ptr);
1294
+ git_buf_puts(out, value + 1);
1295
+
1296
+ if (git_buf_oom(out))
1297
+ return -1;
1298
+
1299
+ return 0;
1300
+ }
1301
+
1302
+ return git_buf_sets(out, value);
1303
+ }
1304
+
1187
1305
  /* Take something the user gave us and make it nice for our hash function */
1188
1306
  int git_config__normalize_name(const char *in, char **out)
1189
1307
  {