rugged 0.23.3 → 0.24.0b0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/ext/rugged/rugged.c +24 -0
  4. data/ext/rugged/rugged_config.c +65 -0
  5. data/ext/rugged/rugged_remote.c +22 -2
  6. data/ext/rugged/rugged_repo.c +10 -5
  7. data/ext/rugged/rugged_tree.c +4 -1
  8. data/lib/rugged/version.rb +1 -1
  9. data/vendor/libgit2/CMakeLists.txt +47 -2
  10. data/vendor/libgit2/include/git2/config.h +18 -0
  11. data/vendor/libgit2/include/git2/diff.h +25 -2
  12. data/vendor/libgit2/include/git2/errors.h +0 -12
  13. data/vendor/libgit2/include/git2/index.h +11 -0
  14. data/vendor/libgit2/include/git2/remote.h +12 -1
  15. data/vendor/libgit2/include/git2/sys/config.h +14 -0
  16. data/vendor/libgit2/include/git2/sys/filter.h +4 -1
  17. data/vendor/libgit2/include/git2/sys/odb_backend.h +4 -0
  18. data/vendor/libgit2/include/git2/sys/refdb_backend.h +5 -4
  19. data/vendor/libgit2/include/git2/sys/transport.h +27 -0
  20. data/vendor/libgit2/include/git2/transport.h +25 -21
  21. data/vendor/libgit2/include/git2/version.h +2 -2
  22. data/vendor/libgit2/libgit2.pc.in +3 -2
  23. data/vendor/libgit2/src/branch.c +1 -12
  24. data/vendor/libgit2/src/checkout.c +29 -20
  25. data/vendor/libgit2/src/clone.c +2 -2
  26. data/vendor/libgit2/src/common.h +13 -4
  27. data/vendor/libgit2/src/config.c +36 -0
  28. data/vendor/libgit2/src/config.h +15 -0
  29. data/vendor/libgit2/src/config_file.c +124 -20
  30. data/vendor/libgit2/src/config_file.h +10 -0
  31. data/vendor/libgit2/src/curl_stream.c +7 -7
  32. data/vendor/libgit2/src/diff.c +89 -27
  33. data/vendor/libgit2/src/diff_print.c +1 -1
  34. data/vendor/libgit2/src/errors.c +75 -40
  35. data/vendor/libgit2/src/filebuf.c +81 -3
  36. data/vendor/libgit2/src/fileops.c +176 -75
  37. data/vendor/libgit2/src/fileops.h +7 -10
  38. data/vendor/libgit2/src/filter.c +5 -2
  39. data/vendor/libgit2/src/global.c +25 -9
  40. data/vendor/libgit2/src/global.h +1 -0
  41. data/vendor/libgit2/src/idxmap.h +92 -0
  42. data/vendor/libgit2/src/ignore.c +9 -7
  43. data/vendor/libgit2/src/index.c +246 -46
  44. data/vendor/libgit2/src/index.h +2 -0
  45. data/vendor/libgit2/src/iterator.c +377 -118
  46. data/vendor/libgit2/src/iterator.h +28 -20
  47. data/vendor/libgit2/src/merge.c +26 -13
  48. data/vendor/libgit2/src/notes.c +1 -1
  49. data/vendor/libgit2/src/odb.c +1 -2
  50. data/vendor/libgit2/src/odb_loose.c +2 -2
  51. data/vendor/libgit2/src/odb_mempack.c +6 -2
  52. data/vendor/libgit2/src/oidmap.h +2 -0
  53. data/vendor/libgit2/src/openssl_stream.c +9 -3
  54. data/vendor/libgit2/src/path.c +37 -2
  55. data/vendor/libgit2/src/path.h +12 -1
  56. data/vendor/libgit2/src/pathspec.c +12 -12
  57. data/vendor/libgit2/src/push.c +2 -1
  58. data/vendor/libgit2/src/push.h +1 -0
  59. data/vendor/libgit2/src/refdb.c +2 -6
  60. data/vendor/libgit2/src/refdb_fs.c +13 -3
  61. data/vendor/libgit2/src/remote.c +44 -15
  62. data/vendor/libgit2/src/repository.c +28 -12
  63. data/vendor/libgit2/src/stash.c +17 -12
  64. data/vendor/libgit2/src/stransport_stream.c +1 -1
  65. data/vendor/libgit2/src/submodule.c +234 -152
  66. data/vendor/libgit2/src/sysdir.c +22 -8
  67. data/vendor/libgit2/src/transaction.c +41 -0
  68. data/vendor/libgit2/src/transaction.h +14 -0
  69. data/vendor/libgit2/src/transports/cred.c +8 -0
  70. data/vendor/libgit2/src/transports/http.c +6 -0
  71. data/vendor/libgit2/src/transports/smart.c +95 -0
  72. data/vendor/libgit2/src/transports/smart.h +1 -0
  73. data/vendor/libgit2/src/transports/smart_pkt.c +9 -2
  74. data/vendor/libgit2/src/transports/ssh.c +5 -3
  75. data/vendor/libgit2/src/transports/winhttp.c +19 -1
  76. data/vendor/libgit2/src/unix/posix.h +14 -1
  77. data/vendor/libgit2/src/util.c +56 -13
  78. data/vendor/libgit2/src/util.h +13 -5
  79. data/vendor/libgit2/src/win32/path_w32.c +15 -8
  80. data/vendor/libgit2/src/win32/posix_w32.c +11 -2
  81. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.c +343 -0
  82. data/vendor/libgit2/src/win32/w32_crtdbg_stacktrace.h +93 -0
  83. data/vendor/libgit2/src/win32/w32_stack.c +192 -0
  84. data/vendor/libgit2/src/win32/w32_stack.h +138 -0
  85. data/vendor/libgit2/src/win32/w32_util.c +29 -5
  86. data/vendor/libgit2/src/win32/w32_util.h +13 -3
  87. metadata +11 -5
@@ -241,9 +241,10 @@ GIT_EXTERN(const git_refspec *)git_remote_get_refspec(const git_remote *remote,
241
241
  * @param direction GIT_DIRECTION_FETCH if you want to fetch or
242
242
  * GIT_DIRECTION_PUSH if you want to push
243
243
  * @param callbacks the callbacks to use for this connection
244
+ * @param custom_headers extra HTTP headers to use in this connection
244
245
  * @return 0 or an error code
245
246
  */
246
- GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks);
247
+ GIT_EXTERN(int) git_remote_connect(git_remote *remote, git_direction direction, const git_remote_callbacks *callbacks, const git_strarray *custom_headers);
247
248
 
248
249
  /**
249
250
  * Get the remote repository's reference advertisement list
@@ -546,6 +547,11 @@ typedef struct {
546
547
  * The default is to auto-follow tags.
547
548
  */
548
549
  git_remote_autotag_option_t download_tags;
550
+
551
+ /**
552
+ * Extra headers for this fetch operation
553
+ */
554
+ git_strarray custom_headers;
549
555
  } git_fetch_options;
550
556
 
551
557
  #define GIT_FETCH_OPTIONS_VERSION 1
@@ -585,6 +591,11 @@ typedef struct {
585
591
  * Callbacks to use for this push operation
586
592
  */
587
593
  git_remote_callbacks callbacks;
594
+
595
+ /**
596
+ * Extra headers for this push operation
597
+ */
598
+ git_strarray custom_headers;
588
599
  } git_push_options;
589
600
 
590
601
  #define GIT_PUSH_OPTIONS_VERSION 1
@@ -67,6 +67,20 @@ struct git_config_backend {
67
67
  int (*iterator)(git_config_iterator **, struct git_config_backend *);
68
68
  /** Produce a read-only version of this backend */
69
69
  int (*snapshot)(struct git_config_backend **, struct git_config_backend *);
70
+ /**
71
+ * Lock this backend.
72
+ *
73
+ * Prevent any writes to the data store backing this
74
+ * backend. Any updates must not be visible to any other
75
+ * readers.
76
+ */
77
+ int (*lock)(struct git_config_backend *);
78
+ /**
79
+ * Unlock the data store backing this backend. If success is
80
+ * true, the changes should be committed, otherwise rolled
81
+ * back.
82
+ */
83
+ int (*unlock)(struct git_config_backend *, int success);
70
84
  void (*free)(struct git_config_backend *);
71
85
  };
72
86
  #define GIT_CONFIG_BACKEND_VERSION 1
@@ -240,7 +240,10 @@ typedef void (*git_filter_cleanup_fn)(
240
240
  * for this filter (e.g. "eol crlf text"). If the attribute name is bare,
241
241
  * it will be simply loaded and passed to the `check` callback. If it has
242
242
  * a value (i.e. "name=value"), the attribute must match that value for
243
- * the filter to be applied.
243
+ * the filter to be applied. The value may be a wildcard (eg, "name=*"),
244
+ * in which case the filter will be invoked for any value for the given
245
+ * attribute name. See the attribute parameter of the `check` callback
246
+ * for the attribute value that was specified.
244
247
  *
245
248
  * The `initialize`, `shutdown`, `check`, `apply`, and `cleanup` callbacks
246
249
  * are all documented above with the respective function pointer typedefs.
@@ -83,6 +83,10 @@ struct git_odb_backend {
83
83
  git_odb_writepack **, git_odb_backend *, git_odb *odb,
84
84
  git_transfer_progress_cb progress_cb, void *progress_payload);
85
85
 
86
+ /**
87
+ * Frees any resources held by the odb (including the `git_odb_backend`
88
+ * itself). An odb backend implementation must provide this function.
89
+ */
86
90
  void (* free)(git_odb_backend *);
87
91
  };
88
92
 
@@ -103,8 +103,9 @@ struct git_refdb_backend {
103
103
  const git_signature *who, const char *message);
104
104
 
105
105
  /**
106
- * Deletes the given reference from the refdb. A refdb implementation
107
- * must provide this function.
106
+ * Deletes the given reference (and if necessary its reflog)
107
+ * from the refdb. A refdb implementation must provide this
108
+ * function.
108
109
  */
109
110
  int (*del)(git_refdb_backend *backend, const char *ref_name, const git_oid *old_id, const char *old_target);
110
111
 
@@ -129,8 +130,8 @@ struct git_refdb_backend {
129
130
  int (*ensure_log)(git_refdb_backend *backend, const char *refname);
130
131
 
131
132
  /**
132
- * Frees any resources held by the refdb. A refdb implementation may
133
- * provide this function; if it is not provided, nothing will be done.
133
+ * Frees any resources held by the refdb (including the `git_refdb_backend`
134
+ * itself). A refdb backend implementation must provide this function.
134
135
  */
135
136
  void (*free)(git_refdb_backend *backend);
136
137
 
@@ -40,6 +40,11 @@ struct git_transport {
40
40
  git_transport_certificate_check_cb certificate_check_cb,
41
41
  void *payload);
42
42
 
43
+ /* Set custom headers for HTTP requests */
44
+ int (*set_custom_headers)(
45
+ git_transport *transport,
46
+ const git_strarray *custom_headers);
47
+
43
48
  /* Connect the transport to the remote repository, using the given
44
49
  * direction. */
45
50
  int (*connect)(
@@ -211,6 +216,28 @@ GIT_EXTERN(int) git_transport_smart(
211
216
  git_remote *owner,
212
217
  /* (git_smart_subtransport_definition *) */ void *payload);
213
218
 
219
+ /**
220
+ * Call the certificate check for this transport.
221
+ *
222
+ * @param transport a smart transport
223
+ * @param cert the certificate to pass to the caller
224
+ * @param valid whether we believe the certificate is valid
225
+ * @param hostname the hostname we connected to
226
+ * @return the return value of the callback
227
+ */
228
+ GIT_EXTERN(int) git_transport_smart_certificate_check(git_transport *transport, git_cert *cert, int valid, const char *hostname);
229
+
230
+ /**
231
+ * Call the credentials callback for this transport
232
+ *
233
+ * @param out the pointer where the creds are to be stored
234
+ * @param transport a smart transport
235
+ * @param user the user we saw on the url (if any)
236
+ * @param methods available methods for authentication
237
+ * @return the return value of the callback
238
+ */
239
+ GIT_EXTERN(int) git_transport_smart_credentials(git_cred **out, git_transport *transport, const char *user, int methods);
240
+
214
241
  /*
215
242
  *** End of base transport interface ***
216
243
  *** Begin interface for subtransports for the smart transport ***
@@ -37,39 +37,32 @@ typedef enum {
37
37
  * Hostkey information taken from libssh2
38
38
  */
39
39
  typedef struct {
40
+ git_cert parent;
41
+
40
42
  /**
41
- * Type of certificate. Here to share the header with
42
- * `git_cert`.
43
+ * A hostkey type from libssh2, either
44
+ * `GIT_CERT_SSH_MD5` or `GIT_CERT_SSH_SHA1`
43
45
  */
44
- git_cert_t cert_type;
45
- /**
46
- * A hostkey type from libssh2, either
47
- * `GIT_CERT_SSH_MD5` or `GIT_CERT_SSH_SHA1`
48
- */
49
46
  git_cert_ssh_t type;
50
47
 
51
- /**
52
- * Hostkey hash. If type has `GIT_CERT_SSH_MD5` set, this will
53
- * have the MD5 hash of the hostkey.
54
- */
48
+ /**
49
+ * Hostkey hash. If type has `GIT_CERT_SSH_MD5` set, this will
50
+ * have the MD5 hash of the hostkey.
51
+ */
55
52
  unsigned char hash_md5[16];
56
53
 
57
- /**
58
- * Hostkey hash. If type has `GIT_CERT_SSH_SHA1` set, this will
59
- * have the SHA-1 hash of the hostkey.
60
- */
61
- unsigned char hash_sha1[20];
54
+ /**
55
+ * Hostkey hash. If type has `GIT_CERT_SSH_SHA1` set, this will
56
+ * have the SHA-1 hash of the hostkey.
57
+ */
58
+ unsigned char hash_sha1[20];
62
59
  } git_cert_hostkey;
63
60
 
64
61
  /**
65
62
  * X.509 certificate information
66
63
  */
67
64
  typedef struct {
68
- /**
69
- * Type of certificate. Here to share the header with
70
- * `git_cert`.
71
- */
72
- git_cert_t cert_type;
65
+ git_cert parent;
73
66
  /**
74
67
  * Pointer to the X.509 certificate data
75
68
  */
@@ -314,6 +307,17 @@ GIT_EXTERN(int) git_cred_ssh_key_memory_new(
314
307
  const char *privatekey,
315
308
  const char *passphrase);
316
309
 
310
+
311
+ /**
312
+ * Free a credential.
313
+ *
314
+ * This is only necessary if you own the object; that is, if you are a
315
+ * transport.
316
+ *
317
+ * @param cred the object to free
318
+ */
319
+ GIT_EXTERN(void) git_cred_free(git_cred *cred);
320
+
317
321
  /**
318
322
  * Signature of a function which acquires a credential object.
319
323
  *
@@ -7,10 +7,10 @@
7
7
  #ifndef INCLUDE_git_version_h__
8
8
  #define INCLUDE_git_version_h__
9
9
 
10
- #define LIBGIT2_VERSION "0.23.3"
10
+ #define LIBGIT2_VERSION "0.23.0"
11
11
  #define LIBGIT2_VER_MAJOR 0
12
12
  #define LIBGIT2_VER_MINOR 23
13
- #define LIBGIT2_VER_REVISION 3
13
+ #define LIBGIT2_VER_REVISION 0
14
14
  #define LIBGIT2_VER_PATCH 0
15
15
 
16
16
  #define LIBGIT2_SOVERSION 23
@@ -1,5 +1,6 @@
1
- libdir=@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_DIR@
2
- includedir=@CMAKE_INSTALL_PREFIX@/@INCLUDE_INSTALL_DIR@
1
+ prefix=@PKGCONFIG_PREFIX@
2
+ libdir=@PKGCONFIG_LIBDIR@
3
+ includedir=@PKGCONFIG_INCLUDEDIR@
3
4
 
4
5
  Name: libgit2
5
6
  Description: The git library, take 2
@@ -155,18 +155,7 @@ int git_branch_delete(git_reference *branch)
155
155
  git_reference_owner(branch), git_buf_cstr(&config_section), NULL) < 0)
156
156
  goto on_error;
157
157
 
158
- if (git_reference_delete(branch) < 0)
159
- goto on_error;
160
-
161
- if ((error = git_reflog_delete(git_reference_owner(branch), git_reference_name(branch))) < 0) {
162
- if (error == GIT_ENOTFOUND) {
163
- giterr_clear();
164
- error = 0;
165
- }
166
- goto on_error;
167
- }
168
-
169
- error = 0;
158
+ error = git_reference_delete(branch);
170
159
 
171
160
  on_error:
172
161
  git_buf_free(&config_section);
@@ -244,6 +244,12 @@ static int checkout_action_common(
244
244
  if (delta->new_file.mode == GIT_FILEMODE_LINK && wd != NULL)
245
245
  *action |= CHECKOUT_ACTION__REMOVE;
246
246
 
247
+ /* if the file is on disk and doesn't match our mode, force update */
248
+ if (wd &&
249
+ GIT_PERMS_IS_EXEC(wd->mode) !=
250
+ GIT_PERMS_IS_EXEC(delta->new_file.mode))
251
+ *action |= CHECKOUT_ACTION__REMOVE;
252
+
247
253
  notify = GIT_CHECKOUT_NOTIFY_UPDATED;
248
254
  }
249
255
 
@@ -1361,7 +1367,7 @@ static int checkout_mkdir(
1361
1367
  mkdir_opts.dir_map = data->mkdir_map;
1362
1368
  mkdir_opts.pool = &data->pool;
1363
1369
 
1364
- error = git_futils_mkdir_ext(
1370
+ error = git_futils_mkdir_relative(
1365
1371
  path, base, mode, flags, &mkdir_opts);
1366
1372
 
1367
1373
  data->perfdata.mkdir_calls += mkdir_opts.perfdata.mkdir_calls;
@@ -1501,15 +1507,6 @@ static int blob_content_to_file(
1501
1507
  if (error < 0)
1502
1508
  return error;
1503
1509
 
1504
- if (GIT_PERMS_IS_EXEC(mode)) {
1505
- data->perfdata.chmod_calls++;
1506
-
1507
- if ((error = p_chmod(path, mode)) < 0) {
1508
- giterr_set(GITERR_OS, "Failed to set permissions on '%s'", path);
1509
- return error;
1510
- }
1511
- }
1512
-
1513
1510
  if (st) {
1514
1511
  data->perfdata.stat_calls++;
1515
1512
 
@@ -2472,11 +2469,12 @@ int git_checkout_iterator(
2472
2469
  {
2473
2470
  int error = 0;
2474
2471
  git_iterator *baseline = NULL, *workdir = NULL;
2472
+ git_iterator_options baseline_opts = GIT_ITERATOR_OPTIONS_INIT,
2473
+ workdir_opts = GIT_ITERATOR_OPTIONS_INIT;
2475
2474
  checkout_data data = {0};
2476
2475
  git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
2477
2476
  uint32_t *actions = NULL;
2478
2477
  size_t *counts = NULL;
2479
- git_iterator_flag_t iterflags = 0;
2480
2478
 
2481
2479
  /* initialize structures and options */
2482
2480
  error = checkout_data_init(&data, target, opts);
@@ -2500,25 +2498,30 @@ int git_checkout_iterator(
2500
2498
 
2501
2499
  /* set up iterators */
2502
2500
 
2503
- iterflags = git_iterator_ignore_case(target) ?
2501
+ workdir_opts.flags = git_iterator_ignore_case(target) ?
2504
2502
  GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE;
2503
+ workdir_opts.flags |= GIT_ITERATOR_DONT_AUTOEXPAND;
2504
+ workdir_opts.start = data.pfx;
2505
+ workdir_opts.end = data.pfx;
2505
2506
 
2506
2507
  if ((error = git_iterator_reset(target, data.pfx, data.pfx)) < 0 ||
2507
2508
  (error = git_iterator_for_workdir_ext(
2508
2509
  &workdir, data.repo, data.opts.target_directory, index, NULL,
2509
- iterflags | GIT_ITERATOR_DONT_AUTOEXPAND,
2510
- data.pfx, data.pfx)) < 0)
2510
+ &workdir_opts)) < 0)
2511
2511
  goto cleanup;
2512
2512
 
2513
+ baseline_opts.flags = git_iterator_ignore_case(target) ?
2514
+ GIT_ITERATOR_IGNORE_CASE : GIT_ITERATOR_DONT_IGNORE_CASE;
2515
+ baseline_opts.start = data.pfx;
2516
+ baseline_opts.end = data.pfx;
2517
+
2513
2518
  if (data.opts.baseline_index) {
2514
2519
  if ((error = git_iterator_for_index(
2515
- &baseline, data.opts.baseline_index,
2516
- iterflags, data.pfx, data.pfx)) < 0)
2520
+ &baseline, data.opts.baseline_index, &baseline_opts)) < 0)
2517
2521
  goto cleanup;
2518
2522
  } else {
2519
2523
  if ((error = git_iterator_for_tree(
2520
- &baseline, data.opts.baseline,
2521
- iterflags, data.pfx, data.pfx)) < 0)
2524
+ &baseline, data.opts.baseline, &baseline_opts)) < 0)
2522
2525
  goto cleanup;
2523
2526
  }
2524
2527
 
@@ -2626,7 +2629,7 @@ int git_checkout_index(
2626
2629
  return error;
2627
2630
  GIT_REFCOUNT_INC(index);
2628
2631
 
2629
- if (!(error = git_iterator_for_index(&index_i, index, 0, NULL, NULL)))
2632
+ if (!(error = git_iterator_for_index(&index_i, index, NULL)))
2630
2633
  error = git_checkout_iterator(index_i, index, opts);
2631
2634
 
2632
2635
  if (owned)
@@ -2647,6 +2650,7 @@ int git_checkout_tree(
2647
2650
  git_index *index;
2648
2651
  git_tree *tree = NULL;
2649
2652
  git_iterator *tree_i = NULL;
2653
+ git_iterator_options iter_opts = GIT_ITERATOR_OPTIONS_INIT;
2650
2654
 
2651
2655
  if (!treeish && !repo) {
2652
2656
  giterr_set(GITERR_CHECKOUT,
@@ -2682,7 +2686,12 @@ int git_checkout_tree(
2682
2686
  if ((error = git_repository_index(&index, repo)) < 0)
2683
2687
  return error;
2684
2688
 
2685
- if (!(error = git_iterator_for_tree(&tree_i, tree, 0, NULL, NULL)))
2689
+ if ((opts->checkout_strategy & GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH)) {
2690
+ iter_opts.pathlist.count = opts->paths.count;
2691
+ iter_opts.pathlist.strings = opts->paths.strings;
2692
+ }
2693
+
2694
+ if (!(error = git_iterator_for_tree(&tree_i, tree, &iter_opts)))
2686
2695
  error = git_checkout_iterator(tree_i, index, opts);
2687
2696
 
2688
2697
  git_iterator_free(tree_i);
@@ -440,14 +440,14 @@ int git_clone(
440
440
 
441
441
  if (error != 0) {
442
442
  git_error_state last_error = {0};
443
- giterr_capture(&last_error, error);
443
+ giterr_state_capture(&last_error, error);
444
444
 
445
445
  git_repository_free(repo);
446
446
  repo = NULL;
447
447
 
448
448
  (void)git_futils_rmdir_r(local_path, NULL, rmdir_flags);
449
449
 
450
- giterr_restore(&last_error);
450
+ giterr_state_restore(&last_error);
451
451
  }
452
452
 
453
453
  *out = repo;
@@ -46,6 +46,10 @@
46
46
  # ifdef GIT_THREADS
47
47
  # include "win32/pthread.h"
48
48
  # endif
49
+ # if defined(GIT_MSVC_CRTDBG)
50
+ # include "win32/w32_stack.h"
51
+ # include "win32/w32_crtdbg_stacktrace.h"
52
+ # endif
49
53
 
50
54
  #else
51
55
 
@@ -137,20 +141,25 @@ void giterr_system_set(int code);
137
141
  * Structure to preserve libgit2 error state
138
142
  */
139
143
  typedef struct {
140
- int error_code;
144
+ int error_code;
145
+ unsigned int oom : 1;
141
146
  git_error error_msg;
142
147
  } git_error_state;
143
148
 
144
149
  /**
145
150
  * Capture current error state to restore later, returning error code.
146
- * If `error_code` is zero, this does nothing and returns zero.
151
+ * If `error_code` is zero, this does not clear the current error state.
152
+ * You must either restore this error state, or free it.
147
153
  */
148
- int giterr_capture(git_error_state *state, int error_code);
154
+ extern int giterr_state_capture(git_error_state *state, int error_code);
149
155
 
150
156
  /**
151
157
  * Restore error state to a previous value, returning saved error code.
152
158
  */
153
- int giterr_restore(git_error_state *state);
159
+ extern int giterr_state_restore(git_error_state *state);
160
+
161
+ /** Free an error state. */
162
+ extern void giterr_state_free(git_error_state *state);
154
163
 
155
164
  /**
156
165
  * Check a versioned structure for validity
@@ -13,6 +13,7 @@
13
13
  #include "vector.h"
14
14
  #include "buf_text.h"
15
15
  #include "config_file.h"
16
+ #include "transaction.h"
16
17
  #if GIT_WIN32
17
18
  # include <windows.h>
18
19
  #endif
@@ -1144,6 +1145,41 @@ int git_config_open_default(git_config **out)
1144
1145
  return error;
1145
1146
  }
1146
1147
 
1148
+ int git_config_lock(git_transaction **out, git_config *cfg)
1149
+ {
1150
+ int error;
1151
+ git_config_backend *file;
1152
+ file_internal *internal;
1153
+
1154
+ internal = git_vector_get(&cfg->files, 0);
1155
+ if (!internal || !internal->file) {
1156
+ giterr_set(GITERR_CONFIG, "cannot lock; the config has no backends/files");
1157
+ return -1;
1158
+ }
1159
+ file = internal->file;
1160
+
1161
+ if ((error = file->lock(file)) < 0)
1162
+ return error;
1163
+
1164
+ return git_transaction_config_new(out, cfg);
1165
+ }
1166
+
1167
+ int git_config_unlock(git_config *cfg, int commit)
1168
+ {
1169
+ git_config_backend *file;
1170
+ file_internal *internal;
1171
+
1172
+ internal = git_vector_get(&cfg->files, 0);
1173
+ if (!internal || !internal->file) {
1174
+ giterr_set(GITERR_CONFIG, "cannot lock; the config has no backends/files");
1175
+ return -1;
1176
+ }
1177
+
1178
+ file = internal->file;
1179
+
1180
+ return file->unlock(file, commit);
1181
+ }
1182
+
1147
1183
  /***********
1148
1184
  * Parsers
1149
1185
  ***********/